src/share/vm/classfile/stackMapTableFormat.hpp

Mon, 15 May 2017 12:20:15 +0200

author
tschatzl
date
Mon, 15 May 2017 12:20:15 +0200
changeset 8766
ce9a710b0f63
parent 8570
e4525db27263
child 8604
04d83ba48607
permissions
-rw-r--r--

8180048: Interned string and symbol table leak memory during parallel unlinking
Summary: Make appending found dead BasicHashtableEntrys to the free list atomic.
Reviewed-by: ehelin, shade

kamg@2232 1 /*
hseigel@8570 2 * Copyright (c) 2010, 2016, 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;
hseigel@8570 206 inline void print_truncated(outputStream* st, int current_offset) const;
kamg@2232 207
kamg@2232 208 // Create as_xxx and is_xxx methods for the subtypes
kamg@2232 209 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
kamg@2232 210 inline stackmap_frame_type* as_##stackmap_frame_type() const; \
kamg@2232 211 bool is_##stackmap_frame_type() { \
kamg@2232 212 return as_##stackmap_frame_type() != NULL; \
kamg@2232 213 }
kamg@2232 214
kamg@2232 215 FOR_EACH_STACKMAP_FRAME_TYPE(FRAME_TYPE_DECL, x, x)
kamg@2232 216 #undef FRAME_TYPE_DECL
kamg@2232 217 };
kamg@2232 218
kamg@2232 219 class same_frame : public stack_map_frame {
kamg@2232 220 private:
kamg@2232 221 static int frame_type_to_offset_delta(u1 frame_type) {
kamg@2232 222 return frame_type + 1; }
kamg@2232 223 static u1 offset_delta_to_frame_type(int offset_delta) {
kamg@2232 224 return (u1)(offset_delta - 1); }
kamg@2232 225
kamg@2232 226 public:
kamg@2232 227
kamg@2232 228 static bool is_frame_type(u1 tag) {
kamg@2232 229 return tag < 64;
kamg@2232 230 }
kamg@2232 231
kamg@2232 232 static same_frame* at(address addr) {
kamg@2232 233 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 234 return (same_frame*)addr;
kamg@2232 235 }
kamg@2232 236
kamg@2232 237 static same_frame* create_at(address addr, int offset_delta) {
kamg@2232 238 same_frame* sm = (same_frame*)addr;
kamg@2232 239 sm->set_offset_delta(offset_delta);
kamg@2232 240 return sm;
kamg@2232 241 }
kamg@2232 242
kamg@2232 243 static size_t calculate_size() { return sizeof(u1); }
kamg@2232 244
kamg@2232 245 size_t size() const { return calculate_size(); }
kamg@2232 246 int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }
kamg@2232 247
kamg@2232 248 void set_offset_delta(int offset_delta) {
kamg@2232 249 assert(offset_delta <= 64, "Offset too large for same_frame");
kamg@2232 250 set_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 251 }
kamg@2232 252
kamg@2232 253 int number_of_types() const { return 0; }
kamg@2232 254 verification_type_info* types() const { return NULL; }
kamg@2232 255
kamg@2232 256 bool is_valid_offset(int offset_delta) const {
kamg@2232 257 return is_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 258 }
kamg@2232 259
kamg@2232 260 bool verify_subtype(address start, address end) const {
kamg@2232 261 return true;
kamg@2232 262 }
kamg@2232 263
kamg@3992 264 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 265 st->print("same_frame(@%d)", offset_delta() + current_offset);
kamg@2232 266 }
hseigel@8570 267
hseigel@8570 268 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 269 print_on(st, current_offset);
hseigel@8570 270 }
kamg@2232 271 };
kamg@2232 272
kamg@2232 273 class same_frame_extended : public stack_map_frame {
kamg@2232 274 private:
kamg@2232 275 enum { _frame_id = 251 };
kamg@2232 276 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 277
kamg@2232 278 public:
kamg@2232 279 static bool is_frame_type(u1 tag) {
kamg@2232 280 return tag == _frame_id;
kamg@2232 281 }
kamg@2232 282
kamg@2232 283 static same_frame_extended* at(address addr) {
kamg@2232 284 assert(is_frame_type(*addr), "Wrong frame type");
kamg@2232 285 return (same_frame_extended*)addr;
kamg@2232 286 }
kamg@2232 287
kamg@2232 288 static same_frame_extended* create_at(address addr, u2 offset_delta) {
kamg@2232 289 same_frame_extended* sm = (same_frame_extended*)addr;
kamg@2232 290 sm->set_frame_type(_frame_id);
kamg@2232 291 sm->set_offset_delta(offset_delta);
kamg@2232 292 return sm;
kamg@2232 293 }
kamg@2232 294
kamg@2232 295 static size_t calculate_size() { return sizeof(u1) + sizeof(u2); }
kamg@2232 296
kamg@2232 297 size_t size() const { return calculate_size(); }
kamg@2232 298 int offset_delta() const {
kamg@2232 299 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 300 }
kamg@2232 301
kamg@2232 302 void set_offset_delta(int offset_delta) {
kamg@2232 303 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 304 }
kamg@2232 305
kamg@2232 306 int number_of_types() const { return 0; }
kamg@2232 307 verification_type_info* types() const { return NULL; }
kamg@2232 308 bool is_valid_offset(int offset) const { return true; }
kamg@2232 309
kamg@2232 310 bool verify_subtype(address start, address end) const {
kamg@2232 311 return frame_type_addr() + size() <= end;
kamg@2232 312 }
kamg@2232 313
kamg@3992 314 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 315 st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
kamg@2232 316 }
hseigel@8570 317
hseigel@8570 318 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 319 print_on(st, current_offset);
hseigel@8570 320 }
kamg@2232 321 };
kamg@2232 322
kamg@3992 323 class same_locals_1_stack_item_frame : public stack_map_frame {
kamg@2232 324 private:
kamg@2232 325 address type_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 326
kamg@2232 327 static int frame_type_to_offset_delta(u1 frame_type) {
kamg@2232 328 return frame_type - 63; }
kamg@2232 329 static u1 offset_delta_to_frame_type(int offset_delta) {
kamg@2232 330 return (u1)(offset_delta + 63); }
kamg@2232 331
kamg@2232 332 public:
kamg@2232 333 static bool is_frame_type(u1 tag) {
kamg@2232 334 return tag >= 64 && tag < 128;
kamg@2232 335 }
kamg@2232 336
kamg@3992 337 static same_locals_1_stack_item_frame* at(address addr) {
kamg@2232 338 assert(is_frame_type(*addr), "Wrong frame id");
kamg@3992 339 return (same_locals_1_stack_item_frame*)addr;
kamg@2232 340 }
kamg@2232 341
kamg@3992 342 static same_locals_1_stack_item_frame* create_at(
kamg@2232 343 address addr, int offset_delta, verification_type_info* vti) {
kamg@3992 344 same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
kamg@2232 345 sm->set_offset_delta(offset_delta);
kamg@2232 346 if (vti != NULL) {
kamg@2232 347 sm->set_type(vti);
kamg@2232 348 }
kamg@2232 349 return sm;
kamg@2232 350 }
kamg@2232 351
kamg@2232 352 static size_t calculate_size(verification_type_info* vti) {
kamg@2232 353 return sizeof(u1) + vti->size();
kamg@2232 354 }
kamg@2232 355
kamg@2232 356 static size_t max_size() {
kamg@2232 357 return sizeof(u1) + verification_type_info::max_size();
kamg@2232 358 }
kamg@2232 359
kamg@2232 360 size_t size() const { return calculate_size(types()); }
kamg@2232 361 int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }
kamg@2232 362
kamg@2232 363 void set_offset_delta(int offset_delta) {
kamg@2232 364 assert(offset_delta > 0 && offset_delta <= 64,
kamg@2232 365 "Offset too large for this frame type");
kamg@2232 366 set_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 367 }
kamg@2232 368
kamg@2232 369 void set_type(verification_type_info* vti) {
kamg@2232 370 verification_type_info* cur = types();
kamg@2232 371 cur->copy_from(vti);
kamg@2232 372 }
kamg@2232 373
kamg@2232 374 int number_of_types() const { return 1; }
kamg@2232 375 verification_type_info* types() const {
kamg@2232 376 return verification_type_info::at(type_addr());
kamg@2232 377 }
kamg@2232 378
kamg@2232 379 bool is_valid_offset(int offset_delta) const {
kamg@2232 380 return is_frame_type(offset_delta_to_frame_type(offset_delta));
kamg@2232 381 }
kamg@2232 382
kamg@2232 383 bool verify_subtype(address start, address end) const {
kamg@2232 384 return types()->verify(start, end);
kamg@2232 385 }
kamg@2232 386
kamg@3992 387 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 388 st->print("same_locals_1_stack_item_frame(@%d,",
kamg@3992 389 offset_delta() + current_offset);
kamg@2232 390 types()->print_on(st);
kamg@2232 391 st->print(")");
kamg@2232 392 }
hseigel@8570 393
hseigel@8570 394 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 395 st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
hseigel@8570 396 offset_delta() + current_offset);
hseigel@8570 397 }
kamg@2232 398 };
kamg@2232 399
kamg@3992 400 class same_locals_1_stack_item_extended : public stack_map_frame {
kamg@2232 401 private:
kamg@2232 402 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 403 address type_addr() const { return offset_delta_addr() + sizeof(u2); }
kamg@2232 404
kamg@2232 405 enum { _frame_id = 247 };
kamg@2232 406
kamg@2232 407 public:
kamg@2232 408 static bool is_frame_type(u1 tag) {
kamg@2232 409 return tag == _frame_id;
kamg@2232 410 }
kamg@2232 411
kamg@3992 412 static same_locals_1_stack_item_extended* at(address addr) {
kamg@2232 413 assert(is_frame_type(*addr), "Wrong frame id");
kamg@3992 414 return (same_locals_1_stack_item_extended*)addr;
kamg@2232 415 }
kamg@2232 416
kamg@3992 417 static same_locals_1_stack_item_extended* create_at(
kamg@2232 418 address addr, int offset_delta, verification_type_info* vti) {
kamg@3992 419 same_locals_1_stack_item_extended* sm =
kamg@3992 420 (same_locals_1_stack_item_extended*)addr;
kamg@2232 421 sm->set_frame_type(_frame_id);
kamg@2232 422 sm->set_offset_delta(offset_delta);
kamg@2232 423 if (vti != NULL) {
kamg@2232 424 sm->set_type(vti);
kamg@2232 425 }
kamg@2232 426 return sm;
kamg@2232 427 }
kamg@2232 428
kamg@2232 429 static size_t calculate_size(verification_type_info* vti) {
kamg@2232 430 return sizeof(u1) + sizeof(u2) + vti->size();
kamg@2232 431 }
kamg@2232 432
kamg@2232 433 size_t size() const { return calculate_size(types()); }
kamg@2232 434 int offset_delta() const {
kamg@2232 435 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 436 }
kamg@2232 437
kamg@2232 438 void set_offset_delta(int offset_delta) {
kamg@2232 439 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 440 }
kamg@2232 441
kamg@2232 442 void set_type(verification_type_info* vti) {
kamg@2232 443 verification_type_info* cur = types();
kamg@2232 444 cur->copy_from(vti);
kamg@2232 445 }
kamg@2232 446
kamg@2232 447 int number_of_types() const { return 1; }
kamg@2232 448 verification_type_info* types() const {
kamg@2232 449 return verification_type_info::at(type_addr());
kamg@2232 450 }
kamg@2232 451 bool is_valid_offset(int offset) { return true; }
kamg@2232 452
kamg@2232 453 bool verify_subtype(address start, address end) const {
kamg@2232 454 return type_addr() < end && types()->verify(start, end);
kamg@2232 455 }
kamg@2232 456
kamg@3992 457 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 458 st->print("same_locals_1_stack_item_extended(@%d,",
kamg@3992 459 offset_delta() + current_offset);
kamg@2232 460 types()->print_on(st);
kamg@2232 461 st->print(")");
kamg@2232 462 }
hseigel@8570 463
hseigel@8570 464 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 465 st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",
hseigel@8570 466 offset_delta() + current_offset);
hseigel@8570 467 }
kamg@2232 468 };
kamg@2232 469
kamg@2232 470 class chop_frame : public stack_map_frame {
kamg@2232 471 private:
kamg@2232 472 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 473
kamg@2232 474 static int frame_type_to_chops(u1 frame_type) {
kamg@2232 475 int chop = 251 - frame_type;
kamg@2232 476 return chop;
kamg@2232 477 }
kamg@2232 478
kamg@2232 479 static u1 chops_to_frame_type(int chop) {
kamg@2232 480 return 251 - chop;
kamg@2232 481 }
kamg@2232 482
kamg@2232 483 public:
kamg@2232 484 static bool is_frame_type(u1 tag) {
kamg@2232 485 return frame_type_to_chops(tag) > 0 && frame_type_to_chops(tag) < 4;
kamg@2232 486 }
kamg@2232 487
kamg@2232 488 static chop_frame* at(address addr) {
kamg@2232 489 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 490 return (chop_frame*)addr;
kamg@2232 491 }
kamg@2232 492
kamg@2232 493 static chop_frame* create_at(address addr, int offset_delta, int chops) {
kamg@2232 494 chop_frame* sm = (chop_frame*)addr;
kamg@2232 495 sm->set_chops(chops);
kamg@2232 496 sm->set_offset_delta(offset_delta);
kamg@2232 497 return sm;
kamg@2232 498 }
kamg@2232 499
kamg@2232 500 static size_t calculate_size() {
kamg@2232 501 return sizeof(u1) + sizeof(u2);
kamg@2232 502 }
kamg@2232 503
kamg@2232 504 size_t size() const { return calculate_size(); }
kamg@2232 505 int offset_delta() const {
kamg@2232 506 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 507 }
kamg@2232 508 void set_offset_delta(int offset_delta) {
kamg@2232 509 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 510 }
kamg@2232 511
kamg@2232 512 int chops() const {
kamg@2232 513 int chops = frame_type_to_chops(frame_type());
kamg@2232 514 assert(chops > 0 && chops < 4, "Invalid number of chops in frame");
kamg@2232 515 return chops;
kamg@2232 516 }
kamg@2232 517 void set_chops(int chops) {
kamg@2232 518 assert(chops > 0 && chops <= 3, "Bad number of chops");
kamg@2232 519 set_frame_type(chops_to_frame_type(chops));
kamg@2232 520 }
kamg@2232 521
kamg@2232 522 int number_of_types() const { return 0; }
kamg@2232 523 verification_type_info* types() const { return NULL; }
kamg@2232 524 bool is_valid_offset(int offset) { return true; }
kamg@2232 525
kamg@2232 526 bool verify_subtype(address start, address end) const {
kamg@2232 527 return frame_type_addr() + size() <= end;
kamg@2232 528 }
kamg@2232 529
kamg@3992 530 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 531 st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
kamg@2232 532 }
hseigel@8570 533
hseigel@8570 534 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 535 print_on(st, current_offset);
hseigel@8570 536 }
kamg@2232 537 };
kamg@2232 538
kamg@2232 539 class append_frame : public stack_map_frame {
kamg@2232 540 private:
kamg@2232 541 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 542 address types_addr() const { return offset_delta_addr() + sizeof(u2); }
kamg@2232 543
kamg@2232 544 static int frame_type_to_appends(u1 frame_type) {
kamg@2232 545 int append = frame_type - 251;
kamg@2232 546 return append;
kamg@2232 547 }
kamg@2232 548
kamg@2232 549 static u1 appends_to_frame_type(int appends) {
kamg@2232 550 assert(appends > 0 && appends < 4, "Invalid append amount");
kamg@2232 551 return 251 + appends;
kamg@2232 552 }
kamg@2232 553
kamg@2232 554 public:
kamg@2232 555 static bool is_frame_type(u1 tag) {
kamg@2232 556 return frame_type_to_appends(tag) > 0 && frame_type_to_appends(tag) < 4;
kamg@2232 557 }
kamg@2232 558
kamg@2232 559 static append_frame* at(address addr) {
kamg@2232 560 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 561 return (append_frame*)addr;
kamg@2232 562 }
kamg@2232 563
kamg@2232 564 static append_frame* create_at(
kamg@2232 565 address addr, int offset_delta, int appends,
kamg@2232 566 verification_type_info* types) {
kamg@2232 567 append_frame* sm = (append_frame*)addr;
kamg@2232 568 sm->set_appends(appends);
kamg@2232 569 sm->set_offset_delta(offset_delta);
kamg@2232 570 if (types != NULL) {
kamg@2232 571 verification_type_info* cur = sm->types();
kamg@2232 572 for (int i = 0; i < appends; ++i) {
kamg@2232 573 cur->copy_from(types);
kamg@2232 574 cur = cur->next();
kamg@2232 575 types = types->next();
kamg@2232 576 }
kamg@2232 577 }
kamg@2232 578 return sm;
kamg@2232 579 }
kamg@2232 580
kamg@2232 581 static size_t calculate_size(int appends, verification_type_info* types) {
kamg@2232 582 size_t sz = sizeof(u1) + sizeof(u2);
kamg@2232 583 for (int i = 0; i < appends; ++i) {
kamg@2232 584 sz += types->size();
kamg@2232 585 types = types->next();
kamg@2232 586 }
kamg@2232 587 return sz;
kamg@2232 588 }
kamg@2232 589
kamg@2232 590 static size_t max_size() {
kamg@2232 591 return sizeof(u1) + sizeof(u2) + 3 * verification_type_info::max_size();
kamg@2232 592 }
kamg@2232 593
kamg@2232 594 size_t size() const { return calculate_size(number_of_types(), types()); }
kamg@2232 595 int offset_delta() const {
kamg@2232 596 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 597 }
kamg@2232 598
kamg@2232 599 void set_offset_delta(int offset_delta) {
kamg@2232 600 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 601 }
kamg@2232 602
kamg@2232 603 void set_appends(int appends) {
kamg@2232 604 assert(appends > 0 && appends < 4, "Bad number of appends");
kamg@2232 605 set_frame_type(appends_to_frame_type(appends));
kamg@2232 606 }
kamg@2232 607
kamg@2232 608 int number_of_types() const {
kamg@2232 609 int appends = frame_type_to_appends(frame_type());
kamg@2232 610 assert(appends > 0 && appends < 4, "Invalid number of appends in frame");
kamg@2232 611 return appends;
kamg@2232 612 }
kamg@2232 613 verification_type_info* types() const {
kamg@2232 614 return verification_type_info::at(types_addr());
kamg@2232 615 }
kamg@2232 616 bool is_valid_offset(int offset) const { return true; }
kamg@2232 617
kamg@2232 618 bool verify_subtype(address start, address end) const {
kamg@2232 619 verification_type_info* vti = types();
kamg@2232 620 if ((address)vti < end && vti->verify(start, end)) {
kamg@2232 621 int nof = number_of_types();
kamg@2232 622 vti = vti->next();
kamg@2232 623 if (nof < 2 || vti->verify(start, end)) {
kamg@2232 624 vti = vti->next();
kamg@2232 625 if (nof < 3 || vti->verify(start, end)) {
kamg@2232 626 return true;
kamg@2232 627 }
kamg@2232 628 }
kamg@2232 629 }
kamg@2232 630 return false;
kamg@2232 631 }
kamg@2232 632
kamg@3992 633 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 634 st->print("append_frame(@%d,", offset_delta() + current_offset);
kamg@2232 635 verification_type_info* vti = types();
kamg@2232 636 for (int i = 0; i < number_of_types(); ++i) {
kamg@2232 637 vti->print_on(st);
kamg@2232 638 if (i != number_of_types() - 1) {
kamg@2232 639 st->print(",");
kamg@2232 640 }
kamg@2232 641 vti = vti->next();
kamg@2232 642 }
kamg@2232 643 st->print(")");
kamg@2232 644 }
hseigel@8570 645
hseigel@8570 646 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 647 st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
hseigel@8570 648 offset_delta() + current_offset);
hseigel@8570 649 }
kamg@2232 650 };
kamg@2232 651
kamg@2232 652 class full_frame : public stack_map_frame {
kamg@2232 653 private:
kamg@2232 654 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
kamg@2232 655 address num_locals_addr() const { return offset_delta_addr() + sizeof(u2); }
kamg@2232 656 address locals_addr() const { return num_locals_addr() + sizeof(u2); }
kamg@2232 657 address stack_slots_addr(address end_of_locals) const {
kamg@2232 658 return end_of_locals; }
kamg@2232 659 address stack_addr(address end_of_locals) const {
kamg@2232 660 return stack_slots_addr(end_of_locals) + sizeof(u2); }
kamg@2232 661
kamg@2232 662 enum { _frame_id = 255 };
kamg@2232 663
kamg@2232 664 public:
kamg@2232 665 static bool is_frame_type(u1 tag) {
kamg@2232 666 return tag == _frame_id;
kamg@2232 667 }
kamg@2232 668
kamg@2232 669 static full_frame* at(address addr) {
kamg@2232 670 assert(is_frame_type(*addr), "Wrong frame id");
kamg@2232 671 return (full_frame*)addr;
kamg@2232 672 }
kamg@2232 673
kamg@2232 674 static full_frame* create_at(
kamg@2232 675 address addr, int offset_delta, int num_locals,
kamg@2232 676 verification_type_info* locals,
kamg@2232 677 int stack_slots, verification_type_info* stack) {
kamg@2232 678 full_frame* sm = (full_frame*)addr;
kamg@2232 679 sm->set_frame_type(_frame_id);
kamg@2232 680 sm->set_offset_delta(offset_delta);
kamg@2232 681 sm->set_num_locals(num_locals);
kamg@2232 682 if (locals != NULL) {
kamg@2232 683 verification_type_info* cur = sm->locals();
kamg@2232 684 for (int i = 0; i < num_locals; ++i) {
kamg@2232 685 cur->copy_from(locals);
kamg@2232 686 cur = cur->next();
kamg@2232 687 locals = locals->next();
kamg@2232 688 }
kamg@2232 689 address end_of_locals = (address)cur;
kamg@2232 690 sm->set_stack_slots(end_of_locals, stack_slots);
kamg@2232 691 cur = sm->stack(end_of_locals);
kamg@2232 692 for (int i = 0; i < stack_slots; ++i) {
kamg@2232 693 cur->copy_from(stack);
kamg@2232 694 cur = cur->next();
kamg@2232 695 stack = stack->next();
kamg@2232 696 }
kamg@2232 697 }
kamg@2232 698 return sm;
kamg@2232 699 }
kamg@2232 700
kamg@2232 701 static size_t calculate_size(
kamg@2232 702 int num_locals, verification_type_info* locals,
kamg@2232 703 int stack_slots, verification_type_info* stack) {
kamg@2232 704 size_t sz = sizeof(u1) + sizeof(u2) + sizeof(u2) + sizeof(u2);
kamg@2232 705 verification_type_info* vti = locals;
kamg@2232 706 for (int i = 0; i < num_locals; ++i) {
kamg@2232 707 sz += vti->size();
kamg@2232 708 vti = vti->next();
kamg@2232 709 }
kamg@2232 710 vti = stack;
kamg@2232 711 for (int i = 0; i < stack_slots; ++i) {
kamg@2232 712 sz += vti->size();
kamg@2232 713 vti = vti->next();
kamg@2232 714 }
kamg@2232 715 return sz;
kamg@2232 716 }
kamg@2232 717
kamg@2232 718 static size_t max_size(int locals, int stack) {
kamg@2232 719 return sizeof(u1) + 3 * sizeof(u2) +
kamg@2232 720 (locals + stack) * verification_type_info::max_size();
kamg@2232 721 }
kamg@2232 722
kamg@2232 723 size_t size() const {
kamg@2232 724 address eol = end_of_locals();
kamg@2232 725 return calculate_size(num_locals(), locals(), stack_slots(eol), stack(eol));
kamg@2232 726 }
kamg@2232 727
kamg@2232 728 int offset_delta() const {
kamg@2232 729 return Bytes::get_Java_u2(offset_delta_addr()) + 1;
kamg@2232 730 }
kamg@2232 731 int num_locals() const { return Bytes::get_Java_u2(num_locals_addr()); }
kamg@2232 732 verification_type_info* locals() const {
kamg@2232 733 return verification_type_info::at(locals_addr());
kamg@2232 734 }
kamg@2232 735 address end_of_locals() const {
kamg@2232 736 verification_type_info* vti = locals();
kamg@2232 737 for (int i = 0; i < num_locals(); ++i) {
kamg@2232 738 vti = vti->next();
kamg@2232 739 }
kamg@2232 740 return (address)vti;
kamg@2232 741 }
kamg@2232 742 int stack_slots(address end_of_locals) const {
kamg@2232 743 return Bytes::get_Java_u2(stack_slots_addr(end_of_locals));
kamg@2232 744 }
kamg@2232 745 verification_type_info* stack(address end_of_locals) const {
kamg@2232 746 return verification_type_info::at(stack_addr(end_of_locals));
kamg@2232 747 }
kamg@2232 748
kamg@2232 749 void set_offset_delta(int offset_delta) {
kamg@2232 750 Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
kamg@2232 751 }
kamg@2232 752 void set_num_locals(int num_locals) {
kamg@2232 753 Bytes::put_Java_u2(num_locals_addr(), num_locals);
kamg@2232 754 }
kamg@2232 755 void set_stack_slots(address end_of_locals, int stack_slots) {
kamg@2232 756 Bytes::put_Java_u2(stack_slots_addr(end_of_locals), stack_slots);
kamg@2232 757 }
kamg@2232 758
kamg@2232 759 // These return only the locals. Extra processing is required for stack
kamg@2232 760 // types of full frames.
kamg@2232 761 int number_of_types() const { return num_locals(); }
kamg@2232 762 verification_type_info* types() const { return locals(); }
kamg@2232 763 bool is_valid_offset(int offset) { return true; }
kamg@2232 764
kamg@2232 765 bool verify_subtype(address start, address end) const {
kamg@2232 766 verification_type_info* vti = types();
kamg@2232 767 if ((address)vti >= end) {
kamg@2232 768 return false;
kamg@2232 769 }
kamg@2232 770 int count = number_of_types();
kamg@2232 771 for (int i = 0; i < count; ++i) {
kamg@2232 772 if (!vti->verify(start, end)) {
kamg@2232 773 return false;
kamg@2232 774 }
kamg@2232 775 vti = vti->next();
kamg@2232 776 }
kamg@2232 777 address eol = (address)vti;
kamg@2232 778 if (eol + sizeof(u2) > end) {
kamg@2232 779 return false;
kamg@2232 780 }
kamg@2232 781 count = stack_slots(eol);
kamg@2232 782 vti = stack(eol);
kamg@2232 783 for (int i = 0; i < stack_slots(eol); ++i) {
kamg@2232 784 if (!vti->verify(start, end)) {
kamg@2232 785 return false;
kamg@2232 786 }
kamg@2232 787 vti = vti->next();
kamg@2232 788 }
kamg@2232 789 return true;
kamg@2232 790 }
kamg@2232 791
kamg@3992 792 void print_on(outputStream* st, int current_offset = -1) const {
kamg@3992 793 st->print("full_frame(@%d,{", offset_delta() + current_offset);
kamg@2232 794 verification_type_info* vti = locals();
kamg@2232 795 for (int i = 0; i < num_locals(); ++i) {
kamg@2232 796 vti->print_on(st);
kamg@2232 797 if (i != num_locals() - 1) {
kamg@2232 798 st->print(",");
kamg@2232 799 }
kamg@2232 800 vti = vti->next();
kamg@2232 801 }
kamg@2232 802 st->print("},{");
kamg@2232 803 address end_of_locals = (address)vti;
kamg@2232 804 vti = stack(end_of_locals);
kamg@2232 805 int ss = stack_slots(end_of_locals);
kamg@2232 806 for (int i = 0; i < ss; ++i) {
kamg@2232 807 vti->print_on(st);
kamg@2232 808 if (i != ss - 1) {
kamg@2232 809 st->print(",");
kamg@2232 810 }
kamg@2232 811 vti = vti->next();
kamg@2232 812 }
kamg@2232 813 st->print("})");
kamg@2232 814 }
hseigel@8570 815
hseigel@8570 816 void print_truncated(outputStream* st, int current_offset = -1) const {
hseigel@8570 817 st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",
hseigel@8570 818 offset_delta() + current_offset);
hseigel@8570 819 }
kamg@2232 820 };
kamg@2232 821
kamg@2232 822 #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
kamg@2232 823 stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
kamg@2232 824 if (item_##stack_frame_type != NULL) { \
kamg@2232 825 return item_##stack_frame_type->func_name args; \
kamg@2232 826 }
kamg@2232 827
kamg@2232 828 #define VOID_VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
kamg@2232 829 stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
kamg@2232 830 if (item_##stack_frame_type != NULL) { \
kamg@2232 831 item_##stack_frame_type->func_name args; \
kamg@2232 832 return; \
kamg@2232 833 }
kamg@2232 834
kamg@2232 835 size_t stack_map_frame::size() const {
kamg@2232 836 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, size, ());
kamg@2232 837 return 0;
kamg@2232 838 }
kamg@2232 839
kamg@2232 840 int stack_map_frame::offset_delta() const {
kamg@2232 841 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, offset_delta, ());
kamg@2232 842 return 0;
kamg@2232 843 }
kamg@2232 844
kamg@2232 845 void stack_map_frame::set_offset_delta(int offset_delta) {
kamg@2232 846 FOR_EACH_STACKMAP_FRAME_TYPE(
kamg@2232 847 VOID_VIRTUAL_DISPATCH, set_offset_delta, (offset_delta));
kamg@2232 848 }
kamg@2232 849
kamg@2232 850 int stack_map_frame::number_of_types() const {
kamg@2232 851 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, number_of_types, ());
kamg@2232 852 return 0;
kamg@2232 853 }
kamg@2232 854
kamg@2232 855 verification_type_info* stack_map_frame::types() const {
kamg@2232 856 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, types, ());
kamg@2232 857 return NULL;
kamg@2232 858 }
kamg@2232 859
kamg@2232 860 bool stack_map_frame::is_valid_offset(int offset) const {
kamg@2232 861 FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, is_valid_offset, (offset));
kamg@2232 862 return true;
kamg@2232 863 }
kamg@2232 864
kamg@2232 865 bool stack_map_frame::verify(address start, address end) const {
kamg@2232 866 if (frame_type_addr() >= start && frame_type_addr() < end) {
kamg@2232 867 FOR_EACH_STACKMAP_FRAME_TYPE(
kamg@2232 868 VIRTUAL_DISPATCH, verify_subtype, (start, end));
kamg@2232 869 }
kamg@2232 870 return false;
kamg@2232 871 }
kamg@2232 872
kamg@3992 873 void stack_map_frame::print_on(outputStream* st, int offs = -1) const {
kamg@3992 874 FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
kamg@2232 875 }
kamg@2232 876
hseigel@8570 877 void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {
hseigel@8570 878 FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));
hseigel@8570 879 }
hseigel@8570 880
kamg@2232 881 #undef VIRTUAL_DISPATCH
kamg@2232 882 #undef VOID_VIRTUAL_DISPATCH
kamg@2232 883
kamg@2232 884 #define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \
kamg@2232 885 stack_frame_type* stack_map_frame::as_##stack_frame_type() const { \
kamg@2232 886 if (stack_frame_type::is_frame_type(frame_type())) { \
kamg@2232 887 return (stack_frame_type*)this; \
kamg@2232 888 } else { \
kamg@2232 889 return NULL; \
kamg@2232 890 } \
kamg@2232 891 }
kamg@2232 892
kamg@2232 893 FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
kamg@2232 894 #undef AS_SUBTYPE_DEF
kamg@2232 895
kamg@3992 896 class stack_map_table {
kamg@3992 897 private:
kamg@3992 898 address number_of_entries_addr() const {
kamg@3992 899 return (address)this;
kamg@3992 900 }
kamg@3992 901 address entries_addr() const {
kamg@3992 902 return number_of_entries_addr() + sizeof(u2);
kamg@3992 903 }
kamg@3992 904
kamg@3992 905 protected:
kamg@3992 906 // No constructors - should be 'private', but GCC issues a warning if it is
kamg@3992 907 stack_map_table() {}
kamg@3992 908 stack_map_table(const stack_map_table&) {}
kamg@3992 909
kamg@3992 910 public:
kamg@3992 911
kamg@3992 912 static stack_map_table* at(address addr) {
kamg@3992 913 return (stack_map_table*)addr;
kamg@3992 914 }
kamg@3992 915
kamg@3992 916 u2 number_of_entries() const {
kamg@3992 917 return Bytes::get_Java_u2(number_of_entries_addr());
kamg@3992 918 }
kamg@3992 919 stack_map_frame* entries() const {
kamg@3992 920 return stack_map_frame::at(entries_addr());
kamg@3992 921 }
kamg@3992 922
kamg@3992 923 void set_number_of_entries(u2 num) {
kamg@3992 924 Bytes::put_Java_u2(number_of_entries_addr(), num);
kamg@3992 925 }
kamg@3992 926 };
kamg@3992 927
kamg@2232 928 class stack_map_table_attribute {
kamg@2232 929 private:
kamg@2232 930 address name_index_addr() const {
kamg@2232 931 return (address)this; }
kamg@2232 932 address attribute_length_addr() const {
kamg@2232 933 return name_index_addr() + sizeof(u2); }
kamg@3992 934 address stack_map_table_addr() const {
kamg@2232 935 return attribute_length_addr() + sizeof(u4); }
kamg@2232 936
kamg@2232 937 protected:
kamg@2232 938 // No constructors - should be 'private', but GCC issues a warning if it is
kamg@2232 939 stack_map_table_attribute() {}
kamg@2232 940 stack_map_table_attribute(const stack_map_table_attribute&) {}
kamg@2232 941
kamg@2232 942 public:
kamg@2232 943
kamg@2232 944 static stack_map_table_attribute* at(address addr) {
kamg@2232 945 return (stack_map_table_attribute*)addr;
kamg@2232 946 }
kamg@2232 947
kamg@2232 948 u2 name_index() const {
kamg@3992 949 return Bytes::get_Java_u2(name_index_addr()); }
kamg@2232 950 u4 attribute_length() const {
kamg@3992 951 return Bytes::get_Java_u4(attribute_length_addr()); }
kamg@3992 952 stack_map_table* table() const {
kamg@3992 953 return stack_map_table::at(stack_map_table_addr());
kamg@2232 954 }
kamg@2232 955
kamg@2232 956 void set_name_index(u2 idx) {
kamg@2232 957 Bytes::put_Java_u2(name_index_addr(), idx);
kamg@2232 958 }
kamg@2232 959 void set_attribute_length(u4 len) {
kamg@2232 960 Bytes::put_Java_u4(attribute_length_addr(), len);
kamg@2232 961 }
kamg@2232 962 };
stefank@2314 963
kamg@3992 964 #undef FOR_EACH_STACKMAP_FRAME_TYPE
kamg@3992 965
stefank@2314 966 #endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP

mercurial