src/share/vm/classfile/stackMapTableFormat.hpp

Tue, 18 Jun 2013 12:31:07 -0700

author
johnc
date
Tue, 18 Jun 2013 12:31:07 -0700
changeset 5277
01522ca68fc7
parent 3992
4ee06e614636
child 6876
710a3c8b516e
child 8570
e4525db27263
permissions
-rw-r--r--

8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

kamg@2232 1 /*
kamg@3992 2 * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
kamg@2232 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
kamg@2232 4 *
kamg@2232 5 * This code is free software; you can redistribute it and/or modify it
kamg@2232 6 * under the terms of the GNU General Public License version 2 only, as
kamg@2232 7 * published by the Free Software Foundation.
kamg@2232 8 *
kamg@2232 9 * This code is distributed in the hope that it will be useful, but WITHOUT
kamg@2232 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kamg@2232 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kamg@2232 12 * version 2 for more details (a copy is included in the LICENSE file that
kamg@2232 13 * accompanied this code).
kamg@2232 14 *
kamg@2232 15 * You should have received a copy of the GNU General Public License version
kamg@2232 16 * 2 along with this work; if not, write to the Free Software Foundation,
kamg@2232 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
kamg@2232 18 *
kamg@2232 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
kamg@2232 20 * or visit www.oracle.com if you need additional information or have any
kamg@2232 21 * questions.
kamg@2232 22 *
kamg@2232 23 */
kamg@2232 24
stefank@2314 25 #ifndef SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
stefank@2314 26 #define SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
stefank@2314 27
stefank@2314 28 #include "classfile/verificationType.hpp"
stefank@2314 29
kamg@2232 30 // These classes represent the stack-map substructures described in the JVMS
kamg@2232 31 // (hence the non-conforming naming scheme).
kamg@2232 32
kamg@2232 33 // These classes work with the types in their compressed form in-place (as they
kamg@2232 34 // would appear in the classfile). No virtual methods or fields allowed.
kamg@2232 35
kamg@2232 36 class verification_type_info {
kamg@2232 37 private:
kamg@2232 38 // u1 tag
kamg@2232 39 // u2 cpool_index || u2 bci (for ITEM_Object & ITEM_Uninitailized only)
kamg@2232 40
kamg@2232 41 address tag_addr() const { return (address)this; }
kamg@2232 42 address cpool_index_addr() const { return tag_addr() + sizeof(u1); }
kamg@2232 43 address bci_addr() const { return cpool_index_addr(); }
kamg@2232 44
kamg@2232 45 protected:
kamg@2232 46 // No constructors - should be 'private', but GCC issues a warning if it is
kamg@2232 47 verification_type_info() {}
kamg@2232 48 verification_type_info(const verification_type_info&) {}
kamg@2232 49
kamg@2232 50 public:
kamg@2232 51
kamg@2232 52 static verification_type_info* at(address addr) {
kamg@2232 53 return (verification_type_info*)addr;
kamg@2232 54 }
kamg@2232 55
kamg@2232 56 static verification_type_info* create_at(address addr, u1 tag) {
kamg@2232 57 verification_type_info* vti = (verification_type_info*)addr;
kamg@2232 58 vti->set_tag(tag);
kamg@2232 59 return vti;
kamg@2232 60 }
kamg@2232 61
kamg@2232 62 static verification_type_info* create_object_at(address addr, u2 cp_idx) {
kamg@2232 63 verification_type_info* vti = (verification_type_info*)addr;
kamg@2232 64 vti->set_tag(ITEM_Object);
kamg@2232 65 vti->set_cpool_index(cp_idx);
kamg@2232 66 return vti;
kamg@2232 67 }
kamg@2232 68
kamg@2232 69 static verification_type_info* create_uninit_at(address addr, u2 bci) {
kamg@2232 70 verification_type_info* vti = (verification_type_info*)addr;
kamg@2232 71 vti->set_tag(ITEM_Uninitialized);
kamg@2232 72 vti->set_bci(bci);
kamg@2232 73 return vti;
kamg@2232 74 }
kamg@2232 75
kamg@2232 76 static size_t calculate_size(u1 tag) {
kamg@2232 77 if (tag == ITEM_Object || tag == ITEM_Uninitialized) {
kamg@2232 78 return sizeof(u1) + sizeof(u2);
kamg@2232 79 } else {
kamg@2232 80 return sizeof(u1);
kamg@2232 81 }
kamg@2232 82 }
kamg@2232 83
kamg@2232 84 static size_t max_size() { return sizeof(u1) + sizeof(u2); }
kamg@2232 85
kamg@2232 86 u1 tag() const { return *(u1*)tag_addr(); }
kamg@2232 87 void set_tag(u1 tag) { *((u1*)tag_addr()) = tag; }
kamg@2232 88
kamg@2232 89 bool is_object() const { return tag() == ITEM_Object; }
kamg@2232 90 bool is_uninitialized() const { return tag() == ITEM_Uninitialized; }
kamg@2232 91
kamg@2232 92 u2 cpool_index() const {
kamg@2232 93 assert(is_object(), "This type has no cp_index");
kamg@2232 94 return Bytes::get_Java_u2(cpool_index_addr());
kamg@2232 95 }
kamg@2232 96 void set_cpool_index(u2 idx) {
kamg@2232 97 assert(is_object(), "This type has no cp_index");
kamg@2232 98 Bytes::put_Java_u2(cpool_index_addr(), idx);
kamg@2232 99 }
kamg@2232 100
kamg@2232 101 u2 bci() const {
kamg@2232 102 assert(is_uninitialized(), "This type has no bci");
kamg@2232 103 return Bytes::get_Java_u2(bci_addr());
kamg@2232 104 }
kamg@2232 105
kamg@2232 106 void set_bci(u2 bci) {
kamg@2232 107 assert(is_uninitialized(), "This type has no bci");
kamg@2232 108 Bytes::put_Java_u2(bci_addr(), bci);
kamg@2232 109 }
kamg@2232 110
kamg@2232 111 void copy_from(verification_type_info* from) {
kamg@2232 112 set_tag(from->tag());
kamg@2232 113 if (from->is_object()) {
kamg@2232 114 set_cpool_index(from->cpool_index());
kamg@2232 115 } else if (from->is_uninitialized()) {
kamg@2232 116 set_bci(from->bci());
kamg@2232 117 }
kamg@2232 118 }
kamg@2232 119
kamg@2232 120 size_t size() const {
kamg@2232 121 return calculate_size(tag());
kamg@2232 122 }
kamg@2232 123
kamg@2232 124 verification_type_info* next() {
kamg@2232 125 return (verification_type_info*)((address)this + size());
kamg@2232 126 }
kamg@2232 127
kamg@2232 128 // This method is used when reading unverified data in order to ensure
kamg@2232 129 // that we don't read past a particular memory limit. It returns false
kamg@2232 130 // if any part of the data structure is outside the specified memory bounds.
kamg@2232 131 bool verify(address start, address end) {
kamg@2232 132 return ((address)this >= start &&
kamg@2232 133 (address)this < end &&
kamg@2232 134 (bci_addr() + sizeof(u2) <= end ||
kamg@2232 135 !is_object() && !is_uninitialized()));
kamg@2232 136 }
kamg@2232 137
kamg@2232 138 void print_on(outputStream* st) {
kamg@2232 139 switch (tag()) {
kamg@2232 140 case ITEM_Top: st->print("Top"); break;
kamg@2232 141 case ITEM_Integer: st->print("Integer"); break;
kamg@2232 142 case ITEM_Float: st->print("Float"); break;
kamg@2232 143 case ITEM_Double: st->print("Double"); break;
kamg@2232 144 case ITEM_Long: st->print("Long"); break;
kamg@2232 145 case ITEM_Null: st->print("Null"); break;
kamg@2232 146 case ITEM_UninitializedThis:
kamg@2232 147 st->print("UninitializedThis"); break;
kamg@2232 148 case ITEM_Uninitialized:
kamg@2232 149 st->print("Uninitialized[#%d]", bci()); break;
kamg@2232 150 case ITEM_Object:
kamg@2232 151 st->print("Object[#%d]", cpool_index()); break;
kamg@2232 152 default:
kamg@2232 153 assert(false, "Bad verification_type_info");
kamg@2232 154 }
kamg@2232 155 }
kamg@2232 156 };
kamg@2232 157
kamg@2232 158 #define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
kamg@2232 159 macro(same_frame, arg1, arg2) \
kamg@2232 160 macro(same_frame_extended, arg1, arg2) \
kamg@3992 161 macro(same_locals_1_stack_item_frame, arg1, arg2) \
kamg@3992 162 macro(same_locals_1_stack_item_extended, arg1, arg2) \
kamg@2232 163 macro(chop_frame, arg1, arg2) \
kamg@2232 164 macro(append_frame, arg1, arg2) \
kamg@2232 165 macro(full_frame, arg1, arg2)
kamg@2232 166
kamg@2232 167 #define SM_FORWARD_DECL(type, arg1, arg2) class type;
kamg@2232 168 FOR_EACH_STACKMAP_FRAME_TYPE(SM_FORWARD_DECL, x, x)
kamg@2232 169 #undef SM_FORWARD_DECL
kamg@2232 170
kamg@2232 171 class stack_map_frame {
kamg@2232 172 protected:
kamg@2232 173 address frame_type_addr() const { return (address)this; }
kamg@2232 174
kamg@2232 175 // No constructors - should be 'private', but GCC issues a warning if it is
kamg@2232 176 stack_map_frame() {}
kamg@2232 177 stack_map_frame(const stack_map_frame&) {}
kamg@2232 178
kamg@2232 179 public:
kamg@2232 180
kamg@2232 181 static stack_map_frame* at(address addr) {
kamg@2232 182 return (stack_map_frame*)addr;
kamg@2232 183 }
kamg@2232 184
kamg@2232 185 stack_map_frame* next() const {
kamg@2232 186 return at((address)this + size());
kamg@2232 187 }
kamg@2232 188
kamg@2232 189 u1 frame_type() const { return *(u1*)frame_type_addr(); }
kamg@2232 190 void set_frame_type(u1 type) { *((u1*)frame_type_addr()) = type; }
kamg@2232 191
kamg@2232 192 // pseudo-virtual methods
kamg@2232 193 inline size_t size() const;
kamg@2232 194 inline int offset_delta() const;
kamg@2232 195 inline void set_offset_delta(int offset_delta);
kamg@2232 196 inline int number_of_types() const; // number of types contained in the frame
kamg@2232 197 inline verification_type_info* types() const; // pointer to first type
kamg@2232 198 inline bool is_valid_offset(int offset_delta) const;
kamg@2232 199
kamg@2232 200 // This method must be used when reading unverified data in order to ensure
kamg@2232 201 // that we don't read past a particular memory limit. It returns false
kamg@2232 202 // if any part of the data structure is outside the specified memory bounds.
kamg@2232 203 inline bool verify(address start, address end) const;
kamg@3992 204
kamg@3992 205 inline void print_on(outputStream* st, int current_offset) const;
kamg@2232 206
kamg@2232 207 // Create as_xxx and is_xxx methods for the subtypes
kamg@2232 208 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
kamg@2232 209 inline stackmap_frame_type* as_##stackmap_frame_type() const; \
kamg@2232 210 bool is_##stackmap_frame_type() { \
kamg@2232 211 return as_##stackmap_frame_type() != NULL; \
kamg@2232 212 }
kamg@2232 213
kamg@2232 214 FOR_EACH_STACKMAP_FRAME_TYPE(FRAME_TYPE_DECL, x, x)
kamg@2232 215 #undef FRAME_TYPE_DECL
kamg@2232 216 };
kamg@2232 217
kamg@2232 218 class same_frame : public stack_map_frame {
kamg@2232 219 private:
kamg@2232 220 static int frame_type_to_offset_delta(u1 frame_type) {
kamg@2232 221 return frame_type + 1; }
kamg@2232 222 static u1 offset_delta_to_frame_type(int offset_delta) {
kamg@2232 223 return (u1)(offset_delta - 1); }
kamg@2232 224
kamg@2232 225 public:
kamg@2232 226
kamg@2232 227 static bool is_frame_type(u1 tag) {
kamg@2232 228 return tag < 64;
kamg@2232 229 }
kamg@2232 230
kamg@2232 231 static same_frame* at(address addr) {
kamg@2232 232 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 233 return (same_frame*)addr;
kamg@2232 234 }
kamg@2232 235
kamg@2232 236 static same_frame* create_at(address addr, int offset_delta) {
kamg@2232 237 same_frame* sm = (same_frame*)addr;
kamg@2232 238 sm->set_offset_delta(offset_delta);
kamg@2232 239 return sm;
kamg@2232 240 }
kamg@2232 241
kamg@2232 242 static size_t calculate_size() { return sizeof(u1); }
kamg@2232 243
kamg@2232 244 size_t size() const { return calculate_size(); }
kamg@2232 245 int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }
kamg@2232 246
kamg@2232 247 void set_offset_delta(int offset_delta) {
kamg@2232 248 assert(offset_delta <= 64, "Offset too large for same_frame");
kamg@2232 249 set_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 250 }
kamg@2232 251
kamg@2232 252 int number_of_types() const { return 0; }
kamg@2232 253 verification_type_info* types() const { return NULL; }
kamg@2232 254
kamg@2232 255 bool is_valid_offset(int offset_delta) const {
kamg@2232 256 return is_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 257 }
kamg@2232 258
kamg@2232 259 bool verify_subtype(address start, address end) const {
kamg@2232 260 return true;
kamg@2232 261 }
kamg@2232 262
kamg@3992 263 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 264 st->print("same_frame(@%d)", offset_delta() + current_offset);
kamg@2232 265 }
kamg@2232 266 };
kamg@2232 267
kamg@2232 268 class same_frame_extended : public stack_map_frame {
kamg@2232 269 private:
kamg@2232 270 enum { _frame_id = 251 };
kamg@2232 271 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 272
kamg@2232 273 public:
kamg@2232 274 static bool is_frame_type(u1 tag) {
kamg@2232 275 return tag == _frame_id;
kamg@2232 276 }
kamg@2232 277
kamg@2232 278 static same_frame_extended* at(address addr) {
kamg@2232 279 assert(is_frame_type(*addr), "Wrong frame type");
kamg@2232 280 return (same_frame_extended*)addr;
kamg@2232 281 }
kamg@2232 282
kamg@2232 283 static same_frame_extended* create_at(address addr, u2 offset_delta) {
kamg@2232 284 same_frame_extended* sm = (same_frame_extended*)addr;
kamg@2232 285 sm->set_frame_type(_frame_id);
kamg@2232 286 sm->set_offset_delta(offset_delta);
kamg@2232 287 return sm;
kamg@2232 288 }
kamg@2232 289
kamg@2232 290 static size_t calculate_size() { return sizeof(u1) + sizeof(u2); }
kamg@2232 291
kamg@2232 292 size_t size() const { return calculate_size(); }
kamg@2232 293 int offset_delta() const {
kamg@2232 294 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 295 }
kamg@2232 296
kamg@2232 297 void set_offset_delta(int offset_delta) {
kamg@2232 298 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 299 }
kamg@2232 300
kamg@2232 301 int number_of_types() const { return 0; }
kamg@2232 302 verification_type_info* types() const { return NULL; }
kamg@2232 303 bool is_valid_offset(int offset) const { return true; }
kamg@2232 304
kamg@2232 305 bool verify_subtype(address start, address end) const {
kamg@2232 306 return frame_type_addr() + size() <= end;
kamg@2232 307 }
kamg@2232 308
kamg@3992 309 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 310 st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
kamg@2232 311 }
kamg@2232 312 };
kamg@2232 313
kamg@3992 314 class same_locals_1_stack_item_frame : public stack_map_frame {
kamg@2232 315 private:
kamg@2232 316 address type_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 317
kamg@2232 318 static int frame_type_to_offset_delta(u1 frame_type) {
kamg@2232 319 return frame_type - 63; }
kamg@2232 320 static u1 offset_delta_to_frame_type(int offset_delta) {
kamg@2232 321 return (u1)(offset_delta + 63); }
kamg@2232 322
kamg@2232 323 public:
kamg@2232 324 static bool is_frame_type(u1 tag) {
kamg@2232 325 return tag >= 64 && tag < 128;
kamg@2232 326 }
kamg@2232 327
kamg@3992 328 static same_locals_1_stack_item_frame* at(address addr) {
kamg@2232 329 assert(is_frame_type(*addr), "Wrong frame id");
kamg@3992 330 return (same_locals_1_stack_item_frame*)addr;
kamg@2232 331 }
kamg@2232 332
kamg@3992 333 static same_locals_1_stack_item_frame* create_at(
kamg@2232 334 address addr, int offset_delta, verification_type_info* vti) {
kamg@3992 335 same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
kamg@2232 336 sm->set_offset_delta(offset_delta);
kamg@2232 337 if (vti != NULL) {
kamg@2232 338 sm->set_type(vti);
kamg@2232 339 }
kamg@2232 340 return sm;
kamg@2232 341 }
kamg@2232 342
kamg@2232 343 static size_t calculate_size(verification_type_info* vti) {
kamg@2232 344 return sizeof(u1) + vti->size();
kamg@2232 345 }
kamg@2232 346
kamg@2232 347 static size_t max_size() {
kamg@2232 348 return sizeof(u1) + verification_type_info::max_size();
kamg@2232 349 }
kamg@2232 350
kamg@2232 351 size_t size() const { return calculate_size(types()); }
kamg@2232 352 int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }
kamg@2232 353
kamg@2232 354 void set_offset_delta(int offset_delta) {
kamg@2232 355 assert(offset_delta > 0 && offset_delta <= 64,
kamg@2232 356 "Offset too large for this frame type");
kamg@2232 357 set_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 358 }
kamg@2232 359
kamg@2232 360 void set_type(verification_type_info* vti) {
kamg@2232 361 verification_type_info* cur = types();
kamg@2232 362 cur->copy_from(vti);
kamg@2232 363 }
kamg@2232 364
kamg@2232 365 int number_of_types() const { return 1; }
kamg@2232 366 verification_type_info* types() const {
kamg@2232 367 return verification_type_info::at(type_addr());
kamg@2232 368 }
kamg@2232 369
kamg@2232 370 bool is_valid_offset(int offset_delta) const {
kamg@2232 371 return is_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 372 }
kamg@2232 373
kamg@2232 374 bool verify_subtype(address start, address end) const {
kamg@2232 375 return types()->verify(start, end);
kamg@2232 376 }
kamg@2232 377
kamg@3992 378 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 379 st->print("same_locals_1_stack_item_frame(@%d,",
kamg@3992 380 offset_delta() + current_offset);
kamg@2232 381 types()->print_on(st);
kamg@2232 382 st->print(")");
kamg@2232 383 }
kamg@2232 384 };
kamg@2232 385
kamg@3992 386 class same_locals_1_stack_item_extended : public stack_map_frame {
kamg@2232 387 private:
kamg@2232 388 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 389 address type_addr() const { return offset_delta_addr() + sizeof(u2); }
kamg@2232 390
kamg@2232 391 enum { _frame_id = 247 };
kamg@2232 392
kamg@2232 393 public:
kamg@2232 394 static bool is_frame_type(u1 tag) {
kamg@2232 395 return tag == _frame_id;
kamg@2232 396 }
kamg@2232 397
kamg@3992 398 static same_locals_1_stack_item_extended* at(address addr) {
kamg@2232 399 assert(is_frame_type(*addr), "Wrong frame id");
kamg@3992 400 return (same_locals_1_stack_item_extended*)addr;
kamg@2232 401 }
kamg@2232 402
kamg@3992 403 static same_locals_1_stack_item_extended* create_at(
kamg@2232 404 address addr, int offset_delta, verification_type_info* vti) {
kamg@3992 405 same_locals_1_stack_item_extended* sm =
kamg@3992 406 (same_locals_1_stack_item_extended*)addr;
kamg@2232 407 sm->set_frame_type(_frame_id);
kamg@2232 408 sm->set_offset_delta(offset_delta);
kamg@2232 409 if (vti != NULL) {
kamg@2232 410 sm->set_type(vti);
kamg@2232 411 }
kamg@2232 412 return sm;
kamg@2232 413 }
kamg@2232 414
kamg@2232 415 static size_t calculate_size(verification_type_info* vti) {
kamg@2232 416 return sizeof(u1) + sizeof(u2) + vti->size();
kamg@2232 417 }
kamg@2232 418
kamg@2232 419 size_t size() const { return calculate_size(types()); }
kamg@2232 420 int offset_delta() const {
kamg@2232 421 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 422 }
kamg@2232 423
kamg@2232 424 void set_offset_delta(int offset_delta) {
kamg@2232 425 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 426 }
kamg@2232 427
kamg@2232 428 void set_type(verification_type_info* vti) {
kamg@2232 429 verification_type_info* cur = types();
kamg@2232 430 cur->copy_from(vti);
kamg@2232 431 }
kamg@2232 432
kamg@2232 433 int number_of_types() const { return 1; }
kamg@2232 434 verification_type_info* types() const {
kamg@2232 435 return verification_type_info::at(type_addr());
kamg@2232 436 }
kamg@2232 437 bool is_valid_offset(int offset) { return true; }
kamg@2232 438
kamg@2232 439 bool verify_subtype(address start, address end) const {
kamg@2232 440 return type_addr() < end && types()->verify(start, end);
kamg@2232 441 }
kamg@2232 442
kamg@3992 443 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 444 st->print("same_locals_1_stack_item_extended(@%d,",
kamg@3992 445 offset_delta() + current_offset);
kamg@2232 446 types()->print_on(st);
kamg@2232 447 st->print(")");
kamg@2232 448 }
kamg@2232 449 };
kamg@2232 450
kamg@2232 451 class chop_frame : public stack_map_frame {
kamg@2232 452 private:
kamg@2232 453 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 454
kamg@2232 455 static int frame_type_to_chops(u1 frame_type) {
kamg@2232 456 int chop = 251 - frame_type;
kamg@2232 457 return chop;
kamg@2232 458 }
kamg@2232 459
kamg@2232 460 static u1 chops_to_frame_type(int chop) {
kamg@2232 461 return 251 - chop;
kamg@2232 462 }
kamg@2232 463
kamg@2232 464 public:
kamg@2232 465 static bool is_frame_type(u1 tag) {
kamg@2232 466 return frame_type_to_chops(tag) > 0 && frame_type_to_chops(tag) < 4;
kamg@2232 467 }
kamg@2232 468
kamg@2232 469 static chop_frame* at(address addr) {
kamg@2232 470 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 471 return (chop_frame*)addr;
kamg@2232 472 }
kamg@2232 473
kamg@2232 474 static chop_frame* create_at(address addr, int offset_delta, int chops) {
kamg@2232 475 chop_frame* sm = (chop_frame*)addr;
kamg@2232 476 sm->set_chops(chops);
kamg@2232 477 sm->set_offset_delta(offset_delta);
kamg@2232 478 return sm;
kamg@2232 479 }
kamg@2232 480
kamg@2232 481 static size_t calculate_size() {
kamg@2232 482 return sizeof(u1) + sizeof(u2);
kamg@2232 483 }
kamg@2232 484
kamg@2232 485 size_t size() const { return calculate_size(); }
kamg@2232 486 int offset_delta() const {
kamg@2232 487 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 488 }
kamg@2232 489 void set_offset_delta(int offset_delta) {
kamg@2232 490 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 491 }
kamg@2232 492
kamg@2232 493 int chops() const {
kamg@2232 494 int chops = frame_type_to_chops(frame_type());
kamg@2232 495 assert(chops > 0 && chops < 4, "Invalid number of chops in frame");
kamg@2232 496 return chops;
kamg@2232 497 }
kamg@2232 498 void set_chops(int chops) {
kamg@2232 499 assert(chops > 0 && chops <= 3, "Bad number of chops");
kamg@2232 500 set_frame_type(chops_to_frame_type(chops));
kamg@2232 501 }
kamg@2232 502
kamg@2232 503 int number_of_types() const { return 0; }
kamg@2232 504 verification_type_info* types() const { return NULL; }
kamg@2232 505 bool is_valid_offset(int offset) { return true; }
kamg@2232 506
kamg@2232 507 bool verify_subtype(address start, address end) const {
kamg@2232 508 return frame_type_addr() + size() <= end;
kamg@2232 509 }
kamg@2232 510
kamg@3992 511 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 512 st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
kamg@2232 513 }
kamg@2232 514 };
kamg@2232 515
kamg@2232 516 class append_frame : public stack_map_frame {
kamg@2232 517 private:
kamg@2232 518 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 519 address types_addr() const { return offset_delta_addr() + sizeof(u2); }
kamg@2232 520
kamg@2232 521 static int frame_type_to_appends(u1 frame_type) {
kamg@2232 522 int append = frame_type - 251;
kamg@2232 523 return append;
kamg@2232 524 }
kamg@2232 525
kamg@2232 526 static u1 appends_to_frame_type(int appends) {
kamg@2232 527 assert(appends > 0 && appends < 4, "Invalid append amount");
kamg@2232 528 return 251 + appends;
kamg@2232 529 }
kamg@2232 530
kamg@2232 531 public:
kamg@2232 532 static bool is_frame_type(u1 tag) {
kamg@2232 533 return frame_type_to_appends(tag) > 0 && frame_type_to_appends(tag) < 4;
kamg@2232 534 }
kamg@2232 535
kamg@2232 536 static append_frame* at(address addr) {
kamg@2232 537 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 538 return (append_frame*)addr;
kamg@2232 539 }
kamg@2232 540
kamg@2232 541 static append_frame* create_at(
kamg@2232 542 address addr, int offset_delta, int appends,
kamg@2232 543 verification_type_info* types) {
kamg@2232 544 append_frame* sm = (append_frame*)addr;
kamg@2232 545 sm->set_appends(appends);
kamg@2232 546 sm->set_offset_delta(offset_delta);
kamg@2232 547 if (types != NULL) {
kamg@2232 548 verification_type_info* cur = sm->types();
kamg@2232 549 for (int i = 0; i < appends; ++i) {
kamg@2232 550 cur->copy_from(types);
kamg@2232 551 cur = cur->next();
kamg@2232 552 types = types->next();
kamg@2232 553 }
kamg@2232 554 }
kamg@2232 555 return sm;
kamg@2232 556 }
kamg@2232 557
kamg@2232 558 static size_t calculate_size(int appends, verification_type_info* types) {
kamg@2232 559 size_t sz = sizeof(u1) + sizeof(u2);
kamg@2232 560 for (int i = 0; i < appends; ++i) {
kamg@2232 561 sz += types->size();
kamg@2232 562 types = types->next();
kamg@2232 563 }
kamg@2232 564 return sz;
kamg@2232 565 }
kamg@2232 566
kamg@2232 567 static size_t max_size() {
kamg@2232 568 return sizeof(u1) + sizeof(u2) + 3 * verification_type_info::max_size();
kamg@2232 569 }
kamg@2232 570
kamg@2232 571 size_t size() const { return calculate_size(number_of_types(), types()); }
kamg@2232 572 int offset_delta() const {
kamg@2232 573 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 574 }
kamg@2232 575
kamg@2232 576 void set_offset_delta(int offset_delta) {
kamg@2232 577 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 578 }
kamg@2232 579
kamg@2232 580 void set_appends(int appends) {
kamg@2232 581 assert(appends > 0 && appends < 4, "Bad number of appends");
kamg@2232 582 set_frame_type(appends_to_frame_type(appends));
kamg@2232 583 }
kamg@2232 584
kamg@2232 585 int number_of_types() const {
kamg@2232 586 int appends = frame_type_to_appends(frame_type());
kamg@2232 587 assert(appends > 0 && appends < 4, "Invalid number of appends in frame");
kamg@2232 588 return appends;
kamg@2232 589 }
kamg@2232 590 verification_type_info* types() const {
kamg@2232 591 return verification_type_info::at(types_addr());
kamg@2232 592 }
kamg@2232 593 bool is_valid_offset(int offset) const { return true; }
kamg@2232 594
kamg@2232 595 bool verify_subtype(address start, address end) const {
kamg@2232 596 verification_type_info* vti = types();
kamg@2232 597 if ((address)vti < end && vti->verify(start, end)) {
kamg@2232 598 int nof = number_of_types();
kamg@2232 599 vti = vti->next();
kamg@2232 600 if (nof < 2 || vti->verify(start, end)) {
kamg@2232 601 vti = vti->next();
kamg@2232 602 if (nof < 3 || vti->verify(start, end)) {
kamg@2232 603 return true;
kamg@2232 604 }
kamg@2232 605 }
kamg@2232 606 }
kamg@2232 607 return false;
kamg@2232 608 }
kamg@2232 609
kamg@3992 610 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 611 st->print("append_frame(@%d,", offset_delta() + current_offset);
kamg@2232 612 verification_type_info* vti = types();
kamg@2232 613 for (int i = 0; i < number_of_types(); ++i) {
kamg@2232 614 vti->print_on(st);
kamg@2232 615 if (i != number_of_types() - 1) {
kamg@2232 616 st->print(",");
kamg@2232 617 }
kamg@2232 618 vti = vti->next();
kamg@2232 619 }
kamg@2232 620 st->print(")");
kamg@2232 621 }
kamg@2232 622 };
kamg@2232 623
kamg@2232 624 class full_frame : public stack_map_frame {
kamg@2232 625 private:
kamg@2232 626 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 627 address num_locals_addr() const { return offset_delta_addr() + sizeof(u2); }
kamg@2232 628 address locals_addr() const { return num_locals_addr() + sizeof(u2); }
kamg@2232 629 address stack_slots_addr(address end_of_locals) const {
kamg@2232 630 return end_of_locals; }
kamg@2232 631 address stack_addr(address end_of_locals) const {
kamg@2232 632 return stack_slots_addr(end_of_locals) + sizeof(u2); }
kamg@2232 633
kamg@2232 634 enum { _frame_id = 255 };
kamg@2232 635
kamg@2232 636 public:
kamg@2232 637 static bool is_frame_type(u1 tag) {
kamg@2232 638 return tag == _frame_id;
kamg@2232 639 }
kamg@2232 640
kamg@2232 641 static full_frame* at(address addr) {
kamg@2232 642 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 643 return (full_frame*)addr;
kamg@2232 644 }
kamg@2232 645
kamg@2232 646 static full_frame* create_at(
kamg@2232 647 address addr, int offset_delta, int num_locals,
kamg@2232 648 verification_type_info* locals,
kamg@2232 649 int stack_slots, verification_type_info* stack) {
kamg@2232 650 full_frame* sm = (full_frame*)addr;
kamg@2232 651 sm->set_frame_type(_frame_id);
kamg@2232 652 sm->set_offset_delta(offset_delta);
kamg@2232 653 sm->set_num_locals(num_locals);
kamg@2232 654 if (locals != NULL) {
kamg@2232 655 verification_type_info* cur = sm->locals();
kamg@2232 656 for (int i = 0; i < num_locals; ++i) {
kamg@2232 657 cur->copy_from(locals);
kamg@2232 658 cur = cur->next();
kamg@2232 659 locals = locals->next();
kamg@2232 660 }
kamg@2232 661 address end_of_locals = (address)cur;
kamg@2232 662 sm->set_stack_slots(end_of_locals, stack_slots);
kamg@2232 663 cur = sm->stack(end_of_locals);
kamg@2232 664 for (int i = 0; i < stack_slots; ++i) {
kamg@2232 665 cur->copy_from(stack);
kamg@2232 666 cur = cur->next();
kamg@2232 667 stack = stack->next();
kamg@2232 668 }
kamg@2232 669 }
kamg@2232 670 return sm;
kamg@2232 671 }
kamg@2232 672
kamg@2232 673 static size_t calculate_size(
kamg@2232 674 int num_locals, verification_type_info* locals,
kamg@2232 675 int stack_slots, verification_type_info* stack) {
kamg@2232 676 size_t sz = sizeof(u1) + sizeof(u2) + sizeof(u2) + sizeof(u2);
kamg@2232 677 verification_type_info* vti = locals;
kamg@2232 678 for (int i = 0; i < num_locals; ++i) {
kamg@2232 679 sz += vti->size();
kamg@2232 680 vti = vti->next();
kamg@2232 681 }
kamg@2232 682 vti = stack;
kamg@2232 683 for (int i = 0; i < stack_slots; ++i) {
kamg@2232 684 sz += vti->size();
kamg@2232 685 vti = vti->next();
kamg@2232 686 }
kamg@2232 687 return sz;
kamg@2232 688 }
kamg@2232 689
kamg@2232 690 static size_t max_size(int locals, int stack) {
kamg@2232 691 return sizeof(u1) + 3 * sizeof(u2) +
kamg@2232 692 (locals + stack) * verification_type_info::max_size();
kamg@2232 693 }
kamg@2232 694
kamg@2232 695 size_t size() const {
kamg@2232 696 address eol = end_of_locals();
kamg@2232 697 return calculate_size(num_locals(), locals(), stack_slots(eol), stack(eol));
kamg@2232 698 }
kamg@2232 699
kamg@2232 700 int offset_delta() const {
kamg@2232 701 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 702 }
kamg@2232 703 int num_locals() const { return Bytes::get_Java_u2(num_locals_addr()); }
kamg@2232 704 verification_type_info* locals() const {
kamg@2232 705 return verification_type_info::at(locals_addr());
kamg@2232 706 }
kamg@2232 707 address end_of_locals() const {
kamg@2232 708 verification_type_info* vti = locals();
kamg@2232 709 for (int i = 0; i < num_locals(); ++i) {
kamg@2232 710 vti = vti->next();
kamg@2232 711 }
kamg@2232 712 return (address)vti;
kamg@2232 713 }
kamg@2232 714 int stack_slots(address end_of_locals) const {
kamg@2232 715 return Bytes::get_Java_u2(stack_slots_addr(end_of_locals));
kamg@2232 716 }
kamg@2232 717 verification_type_info* stack(address end_of_locals) const {
kamg@2232 718 return verification_type_info::at(stack_addr(end_of_locals));
kamg@2232 719 }
kamg@2232 720
kamg@2232 721 void set_offset_delta(int offset_delta) {
kamg@2232 722 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 723 }
kamg@2232 724 void set_num_locals(int num_locals) {
kamg@2232 725 Bytes::put_Java_u2(num_locals_addr(), num_locals);
kamg@2232 726 }
kamg@2232 727 void set_stack_slots(address end_of_locals, int stack_slots) {
kamg@2232 728 Bytes::put_Java_u2(stack_slots_addr(end_of_locals), stack_slots);
kamg@2232 729 }
kamg@2232 730
kamg@2232 731 // These return only the locals. Extra processing is required for stack
kamg@2232 732 // types of full frames.
kamg@2232 733 int number_of_types() const { return num_locals(); }
kamg@2232 734 verification_type_info* types() const { return locals(); }
kamg@2232 735 bool is_valid_offset(int offset) { return true; }
kamg@2232 736
kamg@2232 737 bool verify_subtype(address start, address end) const {
kamg@2232 738 verification_type_info* vti = types();
kamg@2232 739 if ((address)vti >= end) {
kamg@2232 740 return false;
kamg@2232 741 }
kamg@2232 742 int count = number_of_types();
kamg@2232 743 for (int i = 0; i < count; ++i) {
kamg@2232 744 if (!vti->verify(start, end)) {
kamg@2232 745 return false;
kamg@2232 746 }
kamg@2232 747 vti = vti->next();
kamg@2232 748 }
kamg@2232 749 address eol = (address)vti;
kamg@2232 750 if (eol + sizeof(u2) > end) {
kamg@2232 751 return false;
kamg@2232 752 }
kamg@2232 753 count = stack_slots(eol);
kamg@2232 754 vti = stack(eol);
kamg@2232 755 for (int i = 0; i < stack_slots(eol); ++i) {
kamg@2232 756 if (!vti->verify(start, end)) {
kamg@2232 757 return false;
kamg@2232 758 }
kamg@2232 759 vti = vti->next();
kamg@2232 760 }
kamg@2232 761 return true;
kamg@2232 762 }
kamg@2232 763
kamg@3992 764 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 765 st->print("full_frame(@%d,{", offset_delta() + current_offset);
kamg@2232 766 verification_type_info* vti = locals();
kamg@2232 767 for (int i = 0; i < num_locals(); ++i) {
kamg@2232 768 vti->print_on(st);
kamg@2232 769 if (i != num_locals() - 1) {
kamg@2232 770 st->print(",");
kamg@2232 771 }
kamg@2232 772 vti = vti->next();
kamg@2232 773 }
kamg@2232 774 st->print("},{");
kamg@2232 775 address end_of_locals = (address)vti;
kamg@2232 776 vti = stack(end_of_locals);
kamg@2232 777 int ss = stack_slots(end_of_locals);
kamg@2232 778 for (int i = 0; i < ss; ++i) {
kamg@2232 779 vti->print_on(st);
kamg@2232 780 if (i != ss - 1) {
kamg@2232 781 st->print(",");
kamg@2232 782 }
kamg@2232 783 vti = vti->next();
kamg@2232 784 }
kamg@2232 785 st->print("})");
kamg@2232 786 }
kamg@2232 787 };
kamg@2232 788
kamg@2232 789 #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
kamg@2232 790 stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
kamg@2232 791 if (item_##stack_frame_type != NULL) { \
kamg@2232 792 return item_##stack_frame_type->func_name args; \
kamg@2232 793 }
kamg@2232 794
kamg@2232 795 #define VOID_VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
kamg@2232 796 stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
kamg@2232 797 if (item_##stack_frame_type != NULL) { \
kamg@2232 798 item_##stack_frame_type->func_name args; \
kamg@2232 799 return; \
kamg@2232 800 }
kamg@2232 801
kamg@2232 802 size_t stack_map_frame::size() const {
kamg@2232 803 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, size, ());
kamg@2232 804 return 0;
kamg@2232 805 }
kamg@2232 806
kamg@2232 807 int stack_map_frame::offset_delta() const {
kamg@2232 808 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, offset_delta, ());
kamg@2232 809 return 0;
kamg@2232 810 }
kamg@2232 811
kamg@2232 812 void stack_map_frame::set_offset_delta(int offset_delta) {
kamg@2232 813 FOR_EACH_STACKMAP_FRAME_TYPE(
kamg@2232 814 VOID_VIRTUAL_DISPATCH, set_offset_delta, (offset_delta));
kamg@2232 815 }
kamg@2232 816
kamg@2232 817 int stack_map_frame::number_of_types() const {
kamg@2232 818 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, number_of_types, ());
kamg@2232 819 return 0;
kamg@2232 820 }
kamg@2232 821
kamg@2232 822 verification_type_info* stack_map_frame::types() const {
kamg@2232 823 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, types, ());
kamg@2232 824 return NULL;
kamg@2232 825 }
kamg@2232 826
kamg@2232 827 bool stack_map_frame::is_valid_offset(int offset) const {
kamg@2232 828 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, is_valid_offset, (offset));
kamg@2232 829 return true;
kamg@2232 830 }
kamg@2232 831
kamg@2232 832 bool stack_map_frame::verify(address start, address end) const {
kamg@2232 833 if (frame_type_addr() >= start && frame_type_addr() < end) {
kamg@2232 834 FOR_EACH_STACKMAP_FRAME_TYPE(
kamg@2232 835 VIRTUAL_DISPATCH, verify_subtype, (start, end));
kamg@2232 836 }
kamg@2232 837 return false;
kamg@2232 838 }
kamg@2232 839
kamg@3992 840 void stack_map_frame::print_on(outputStream* st, int offs = -1) const {
kamg@3992 841 FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
kamg@2232 842 }
kamg@2232 843
kamg@2232 844 #undef VIRTUAL_DISPATCH
kamg@2232 845 #undef VOID_VIRTUAL_DISPATCH
kamg@2232 846
kamg@2232 847 #define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \
kamg@2232 848 stack_frame_type* stack_map_frame::as_##stack_frame_type() const { \
kamg@2232 849 if (stack_frame_type::is_frame_type(frame_type())) { \
kamg@2232 850 return (stack_frame_type*)this; \
kamg@2232 851 } else { \
kamg@2232 852 return NULL; \
kamg@2232 853 } \
kamg@2232 854 }
kamg@2232 855
kamg@2232 856 FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
kamg@2232 857 #undef AS_SUBTYPE_DEF
kamg@2232 858
kamg@3992 859 class stack_map_table {
kamg@3992 860 private:
kamg@3992 861 address number_of_entries_addr() const {
kamg@3992 862 return (address)this;
kamg@3992 863 }
kamg@3992 864 address entries_addr() const {
kamg@3992 865 return number_of_entries_addr() + sizeof(u2);
kamg@3992 866 }
kamg@3992 867
kamg@3992 868 protected:
kamg@3992 869 // No constructors - should be 'private', but GCC issues a warning if it is
kamg@3992 870 stack_map_table() {}
kamg@3992 871 stack_map_table(const stack_map_table&) {}
kamg@3992 872
kamg@3992 873 public:
kamg@3992 874
kamg@3992 875 static stack_map_table* at(address addr) {
kamg@3992 876 return (stack_map_table*)addr;
kamg@3992 877 }
kamg@3992 878
kamg@3992 879 u2 number_of_entries() const {
kamg@3992 880 return Bytes::get_Java_u2(number_of_entries_addr());
kamg@3992 881 }
kamg@3992 882 stack_map_frame* entries() const {
kamg@3992 883 return stack_map_frame::at(entries_addr());
kamg@3992 884 }
kamg@3992 885
kamg@3992 886 void set_number_of_entries(u2 num) {
kamg@3992 887 Bytes::put_Java_u2(number_of_entries_addr(), num);
kamg@3992 888 }
kamg@3992 889 };
kamg@3992 890
kamg@2232 891 class stack_map_table_attribute {
kamg@2232 892 private:
kamg@2232 893 address name_index_addr() const {
kamg@2232 894 return (address)this; }
kamg@2232 895 address attribute_length_addr() const {
kamg@2232 896 return name_index_addr() + sizeof(u2); }
kamg@3992 897 address stack_map_table_addr() const {
kamg@2232 898 return attribute_length_addr() + sizeof(u4); }
kamg@2232 899
kamg@2232 900 protected:
kamg@2232 901 // No constructors - should be 'private', but GCC issues a warning if it is
kamg@2232 902 stack_map_table_attribute() {}
kamg@2232 903 stack_map_table_attribute(const stack_map_table_attribute&) {}
kamg@2232 904
kamg@2232 905 public:
kamg@2232 906
kamg@2232 907 static stack_map_table_attribute* at(address addr) {
kamg@2232 908 return (stack_map_table_attribute*)addr;
kamg@2232 909 }
kamg@2232 910
kamg@2232 911 u2 name_index() const {
kamg@3992 912 return Bytes::get_Java_u2(name_index_addr()); }
kamg@2232 913 u4 attribute_length() const {
kamg@3992 914 return Bytes::get_Java_u4(attribute_length_addr()); }
kamg@3992 915 stack_map_table* table() const {
kamg@3992 916 return stack_map_table::at(stack_map_table_addr());
kamg@2232 917 }
kamg@2232 918
kamg@2232 919 void set_name_index(u2 idx) {
kamg@2232 920 Bytes::put_Java_u2(name_index_addr(), idx);
kamg@2232 921 }
kamg@2232 922 void set_attribute_length(u4 len) {
kamg@2232 923 Bytes::put_Java_u4(attribute_length_addr(), len);
kamg@2232 924 }
kamg@2232 925 };
stefank@2314 926
kamg@3992 927 #undef FOR_EACH_STACKMAP_FRAME_TYPE
kamg@3992 928
stefank@2314 929 #endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP

mercurial