src/share/vm/classfile/stackMapTableFormat.hpp

Thu, 24 May 2018 18:41:44 +0800

author
aoqi
date
Thu, 24 May 2018 18:41:44 +0800
changeset 8856
ac27a9c85bea
parent 8604
04d83ba48607
permissions
-rw-r--r--

Merge

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

mercurial