src/share/vm/classfile/stackMapTableFormat.hpp

Fri, 12 Nov 2010 09:37:13 -0500

author
zgu
date
Fri, 12 Nov 2010 09:37:13 -0500
changeset 2299
9752a6549f2e
parent 2232
a4c7fe54bf3f
child 2314
f95d63e2154a
permissions
-rw-r--r--

Merge

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

mercurial