src/share/vm/classfile/stackMapTableFormat.hpp

Mon, 25 Jun 2012 21:33:35 -0400

author
coleenp
date
Mon, 25 Jun 2012 21:33:35 -0400
changeset 3875
246d977b51f2
parent 2314
f95d63e2154a
child 3992
4ee06e614636
permissions
-rw-r--r--

7178670: runtime/7158800/BadUtf8.java fails in SymbolTable::rehash_table
Summary: Cannot delete _buckets and HashtableEntries in shared space (CDS)
Reviewed-by: acorn, kvn, dlong, dcubed, kamg

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

mercurial