Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp
32285 views
/*1* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP25#define SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP2627#include "classfile/verificationType.hpp"2829// These classes represent the stack-map substructures described in the JVMS30// (hence the non-conforming naming scheme).3132// These classes work with the types in their compressed form in-place (as they33// would appear in the classfile). No virtual methods or fields allowed.3435class verification_type_info {36private:37// u1 tag38// u2 cpool_index || u2 bci (for ITEM_Object & ITEM_Uninitailized only)3940address tag_addr() const { return (address)this; }41address cpool_index_addr() const { return tag_addr() + sizeof(u1); }42address bci_addr() const { return cpool_index_addr(); }4344protected:45// No constructors - should be 'private', but GCC issues a warning if it is46verification_type_info() {}47verification_type_info(const verification_type_info&) {}4849public:5051static verification_type_info* at(address addr) {52return (verification_type_info*)addr;53}5455static verification_type_info* create_at(address addr, u1 tag) {56verification_type_info* vti = (verification_type_info*)addr;57vti->set_tag(tag);58return vti;59}6061static verification_type_info* create_object_at(address addr, u2 cp_idx) {62verification_type_info* vti = (verification_type_info*)addr;63vti->set_tag(ITEM_Object);64vti->set_cpool_index(cp_idx);65return vti;66}6768static verification_type_info* create_uninit_at(address addr, u2 bci) {69verification_type_info* vti = (verification_type_info*)addr;70vti->set_tag(ITEM_Uninitialized);71vti->set_bci(bci);72return vti;73}7475static size_t calculate_size(u1 tag) {76if (tag == ITEM_Object || tag == ITEM_Uninitialized) {77return sizeof(u1) + sizeof(u2);78} else {79return sizeof(u1);80}81}8283static size_t max_size() { return sizeof(u1) + sizeof(u2); }8485u1 tag() const { return *(u1*)tag_addr(); }86void set_tag(u1 tag) { *((u1*)tag_addr()) = tag; }8788bool is_object() const { return tag() == ITEM_Object; }89bool is_uninitialized() const { return tag() == ITEM_Uninitialized; }9091u2 cpool_index() const {92assert(is_object(), "This type has no cp_index");93return Bytes::get_Java_u2(cpool_index_addr());94}95void set_cpool_index(u2 idx) {96assert(is_object(), "This type has no cp_index");97Bytes::put_Java_u2(cpool_index_addr(), idx);98}99100u2 bci() const {101assert(is_uninitialized(), "This type has no bci");102return Bytes::get_Java_u2(bci_addr());103}104105void set_bci(u2 bci) {106assert(is_uninitialized(), "This type has no bci");107Bytes::put_Java_u2(bci_addr(), bci);108}109110void copy_from(verification_type_info* from) {111set_tag(from->tag());112if (from->is_object()) {113set_cpool_index(from->cpool_index());114} else if (from->is_uninitialized()) {115set_bci(from->bci());116}117}118119size_t size() const {120return calculate_size(tag());121}122123verification_type_info* next() {124return (verification_type_info*)((address)this + size());125}126127// This method is used when reading unverified data in order to ensure128// that we don't read past a particular memory limit. It returns false129// if any part of the data structure is outside the specified memory bounds.130bool verify(address start, address end) {131return ((address)this >= start &&132(address)this < end &&133(bci_addr() + sizeof(u2) <= end ||134!is_object() && !is_uninitialized()));135}136137void print_on(outputStream* st) {138switch (tag()) {139case ITEM_Top: st->print("Top"); break;140case ITEM_Integer: st->print("Integer"); break;141case ITEM_Float: st->print("Float"); break;142case ITEM_Double: st->print("Double"); break;143case ITEM_Long: st->print("Long"); break;144case ITEM_Null: st->print("Null"); break;145case ITEM_UninitializedThis:146st->print("UninitializedThis"); break;147case ITEM_Uninitialized:148st->print("Uninitialized[#%d]", bci()); break;149case ITEM_Object:150st->print("Object[#%d]", cpool_index()); break;151default:152assert(false, "Bad verification_type_info");153}154}155};156157#define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \158macro(same_frame, arg1, arg2) \159macro(same_frame_extended, arg1, arg2) \160macro(same_locals_1_stack_item_frame, arg1, arg2) \161macro(same_locals_1_stack_item_extended, arg1, arg2) \162macro(chop_frame, arg1, arg2) \163macro(append_frame, arg1, arg2) \164macro(full_frame, arg1, arg2)165166#define SM_FORWARD_DECL(type, arg1, arg2) class type;167FOR_EACH_STACKMAP_FRAME_TYPE(SM_FORWARD_DECL, x, x)168#undef SM_FORWARD_DECL169170class stack_map_frame {171protected:172address frame_type_addr() const { return (address)this; }173174// No constructors - should be 'private', but GCC issues a warning if it is175stack_map_frame() {}176stack_map_frame(const stack_map_frame&) {}177178public:179180static stack_map_frame* at(address addr) {181return (stack_map_frame*)addr;182}183184stack_map_frame* next() const {185return at((address)this + size());186}187188u1 frame_type() const { return *(u1*)frame_type_addr(); }189void set_frame_type(u1 type) { *((u1*)frame_type_addr()) = type; }190191// pseudo-virtual methods192inline size_t size() const;193inline int offset_delta() const;194inline void set_offset_delta(int offset_delta);195inline int number_of_types() const; // number of types contained in the frame196inline verification_type_info* types() const; // pointer to first type197inline bool is_valid_offset(int offset_delta) const;198199// This method must be used when reading unverified data in order to ensure200// that we don't read past a particular memory limit. It returns false201// if any part of the data structure is outside the specified memory bounds.202inline bool verify(address start, address end) const;203204inline void print_on(outputStream* st, int current_offset) const;205inline void print_truncated(outputStream* st, int current_offset) const;206207// Create as_xxx and is_xxx methods for the subtypes208#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \209inline stackmap_frame_type* as_##stackmap_frame_type() const; \210bool is_##stackmap_frame_type() { \211return as_##stackmap_frame_type() != NULL; \212}213214FOR_EACH_STACKMAP_FRAME_TYPE(FRAME_TYPE_DECL, x, x)215#undef FRAME_TYPE_DECL216};217218class same_frame : public stack_map_frame {219private:220static int frame_type_to_offset_delta(u1 frame_type) {221return frame_type + 1; }222static u1 offset_delta_to_frame_type(int offset_delta) {223return (u1)(offset_delta - 1); }224225public:226227static bool is_frame_type(u1 tag) {228return tag < 64;229}230231static same_frame* at(address addr) {232assert(is_frame_type(*addr), "Wrong frame id");233return (same_frame*)addr;234}235236static same_frame* create_at(address addr, int offset_delta) {237same_frame* sm = (same_frame*)addr;238sm->set_offset_delta(offset_delta);239return sm;240}241242static size_t calculate_size() { return sizeof(u1); }243244size_t size() const { return calculate_size(); }245int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }246247void set_offset_delta(int offset_delta) {248assert(offset_delta <= 64, "Offset too large for same_frame");249set_frame_type(offset_delta_to_frame_type(offset_delta));250}251252int number_of_types() const { return 0; }253verification_type_info* types() const { return NULL; }254255bool is_valid_offset(int offset_delta) const {256return is_frame_type(offset_delta_to_frame_type(offset_delta));257}258259bool verify_subtype(address start, address end) const {260return true;261}262263void print_on(outputStream* st, int current_offset = -1) const {264st->print("same_frame(@%d)", offset_delta() + current_offset);265}266267void print_truncated(outputStream* st, int current_offset = -1) const {268print_on(st, current_offset);269}270};271272class same_frame_extended : public stack_map_frame {273private:274enum { _frame_id = 251 };275address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }276277public:278static bool is_frame_type(u1 tag) {279return tag == _frame_id;280}281282static same_frame_extended* at(address addr) {283assert(is_frame_type(*addr), "Wrong frame type");284return (same_frame_extended*)addr;285}286287static same_frame_extended* create_at(address addr, u2 offset_delta) {288same_frame_extended* sm = (same_frame_extended*)addr;289sm->set_frame_type(_frame_id);290sm->set_offset_delta(offset_delta);291return sm;292}293294static size_t calculate_size() { return sizeof(u1) + sizeof(u2); }295296size_t size() const { return calculate_size(); }297int offset_delta() const {298return Bytes::get_Java_u2(offset_delta_addr()) + 1;299}300301void set_offset_delta(int offset_delta) {302Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);303}304305int number_of_types() const { return 0; }306verification_type_info* types() const { return NULL; }307bool is_valid_offset(int offset) const { return true; }308309bool verify_subtype(address start, address end) const {310return frame_type_addr() + size() <= end;311}312313void print_on(outputStream* st, int current_offset = -1) const {314st->print("same_frame_extended(@%d)", offset_delta() + current_offset);315}316317void print_truncated(outputStream* st, int current_offset = -1) const {318print_on(st, current_offset);319}320};321322class same_locals_1_stack_item_frame : public stack_map_frame {323private:324address type_addr() const { return frame_type_addr() + sizeof(u1); }325326static int frame_type_to_offset_delta(u1 frame_type) {327return frame_type - 63; }328static u1 offset_delta_to_frame_type(int offset_delta) {329return (u1)(offset_delta + 63); }330331public:332static bool is_frame_type(u1 tag) {333return tag >= 64 && tag < 128;334}335336static same_locals_1_stack_item_frame* at(address addr) {337assert(is_frame_type(*addr), "Wrong frame id");338return (same_locals_1_stack_item_frame*)addr;339}340341static same_locals_1_stack_item_frame* create_at(342address addr, int offset_delta, verification_type_info* vti) {343same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;344sm->set_offset_delta(offset_delta);345if (vti != NULL) {346sm->set_type(vti);347}348return sm;349}350351static size_t calculate_size(verification_type_info* vti) {352return sizeof(u1) + vti->size();353}354355static size_t max_size() {356return sizeof(u1) + verification_type_info::max_size();357}358359size_t size() const { return calculate_size(types()); }360int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }361362void set_offset_delta(int offset_delta) {363assert(offset_delta > 0 && offset_delta <= 64,364"Offset too large for this frame type");365set_frame_type(offset_delta_to_frame_type(offset_delta));366}367368void set_type(verification_type_info* vti) {369verification_type_info* cur = types();370cur->copy_from(vti);371}372373int number_of_types() const { return 1; }374verification_type_info* types() const {375return verification_type_info::at(type_addr());376}377378bool is_valid_offset(int offset_delta) const {379return is_frame_type(offset_delta_to_frame_type(offset_delta));380}381382bool verify_subtype(address start, address end) const {383return types()->verify(start, end);384}385386void print_on(outputStream* st, int current_offset = -1) const {387st->print("same_locals_1_stack_item_frame(@%d,",388offset_delta() + current_offset);389types()->print_on(st);390st->print(")");391}392393void print_truncated(outputStream* st, int current_offset = -1) const {394st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",395offset_delta() + current_offset);396}397};398399class same_locals_1_stack_item_extended : public stack_map_frame {400private:401address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }402address type_addr() const { return offset_delta_addr() + sizeof(u2); }403404enum { _frame_id = 247 };405406public:407static bool is_frame_type(u1 tag) {408return tag == _frame_id;409}410411static same_locals_1_stack_item_extended* at(address addr) {412assert(is_frame_type(*addr), "Wrong frame id");413return (same_locals_1_stack_item_extended*)addr;414}415416static same_locals_1_stack_item_extended* create_at(417address addr, int offset_delta, verification_type_info* vti) {418same_locals_1_stack_item_extended* sm =419(same_locals_1_stack_item_extended*)addr;420sm->set_frame_type(_frame_id);421sm->set_offset_delta(offset_delta);422if (vti != NULL) {423sm->set_type(vti);424}425return sm;426}427428static size_t calculate_size(verification_type_info* vti) {429return sizeof(u1) + sizeof(u2) + vti->size();430}431432size_t size() const { return calculate_size(types()); }433int offset_delta() const {434return Bytes::get_Java_u2(offset_delta_addr()) + 1;435}436437void set_offset_delta(int offset_delta) {438Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);439}440441void set_type(verification_type_info* vti) {442verification_type_info* cur = types();443cur->copy_from(vti);444}445446int number_of_types() const { return 1; }447verification_type_info* types() const {448return verification_type_info::at(type_addr());449}450bool is_valid_offset(int offset) { return true; }451452bool verify_subtype(address start, address end) const {453return type_addr() < end && types()->verify(start, end);454}455456void print_on(outputStream* st, int current_offset = -1) const {457st->print("same_locals_1_stack_item_extended(@%d,",458offset_delta() + current_offset);459types()->print_on(st);460st->print(")");461}462463void print_truncated(outputStream* st, int current_offset = -1) const {464st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",465offset_delta() + current_offset);466}467};468469class chop_frame : public stack_map_frame {470private:471address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }472473static int frame_type_to_chops(u1 frame_type) {474int chop = 251 - frame_type;475return chop;476}477478static u1 chops_to_frame_type(int chop) {479return 251 - chop;480}481482public:483static bool is_frame_type(u1 tag) {484return frame_type_to_chops(tag) > 0 && frame_type_to_chops(tag) < 4;485}486487static chop_frame* at(address addr) {488assert(is_frame_type(*addr), "Wrong frame id");489return (chop_frame*)addr;490}491492static chop_frame* create_at(address addr, int offset_delta, int chops) {493chop_frame* sm = (chop_frame*)addr;494sm->set_chops(chops);495sm->set_offset_delta(offset_delta);496return sm;497}498499static size_t calculate_size() {500return sizeof(u1) + sizeof(u2);501}502503size_t size() const { return calculate_size(); }504int offset_delta() const {505return Bytes::get_Java_u2(offset_delta_addr()) + 1;506}507void set_offset_delta(int offset_delta) {508Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);509}510511int chops() const {512int chops = frame_type_to_chops(frame_type());513assert(chops > 0 && chops < 4, "Invalid number of chops in frame");514return chops;515}516void set_chops(int chops) {517assert(chops > 0 && chops <= 3, "Bad number of chops");518set_frame_type(chops_to_frame_type(chops));519}520521int number_of_types() const { return 0; }522verification_type_info* types() const { return NULL; }523bool is_valid_offset(int offset) { return true; }524525bool verify_subtype(address start, address end) const {526return frame_type_addr() + size() <= end;527}528529void print_on(outputStream* st, int current_offset = -1) const {530st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());531}532533void print_truncated(outputStream* st, int current_offset = -1) const {534print_on(st, current_offset);535}536};537538class append_frame : public stack_map_frame {539private:540address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }541address types_addr() const { return offset_delta_addr() + sizeof(u2); }542543static int frame_type_to_appends(u1 frame_type) {544int append = frame_type - 251;545return append;546}547548static u1 appends_to_frame_type(int appends) {549assert(appends > 0 && appends < 4, "Invalid append amount");550return 251 + appends;551}552553public:554static bool is_frame_type(u1 tag) {555return frame_type_to_appends(tag) > 0 && frame_type_to_appends(tag) < 4;556}557558static append_frame* at(address addr) {559assert(is_frame_type(*addr), "Wrong frame id");560return (append_frame*)addr;561}562563static append_frame* create_at(564address addr, int offset_delta, int appends,565verification_type_info* types) {566append_frame* sm = (append_frame*)addr;567sm->set_appends(appends);568sm->set_offset_delta(offset_delta);569if (types != NULL) {570verification_type_info* cur = sm->types();571for (int i = 0; i < appends; ++i) {572cur->copy_from(types);573cur = cur->next();574types = types->next();575}576}577return sm;578}579580static size_t calculate_size(int appends, verification_type_info* types) {581size_t sz = sizeof(u1) + sizeof(u2);582for (int i = 0; i < appends; ++i) {583sz += types->size();584types = types->next();585}586return sz;587}588589static size_t max_size() {590return sizeof(u1) + sizeof(u2) + 3 * verification_type_info::max_size();591}592593size_t size() const { return calculate_size(number_of_types(), types()); }594int offset_delta() const {595return Bytes::get_Java_u2(offset_delta_addr()) + 1;596}597598void set_offset_delta(int offset_delta) {599Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);600}601602void set_appends(int appends) {603assert(appends > 0 && appends < 4, "Bad number of appends");604set_frame_type(appends_to_frame_type(appends));605}606607int number_of_types() const {608int appends = frame_type_to_appends(frame_type());609assert(appends > 0 && appends < 4, "Invalid number of appends in frame");610return appends;611}612verification_type_info* types() const {613return verification_type_info::at(types_addr());614}615bool is_valid_offset(int offset) const { return true; }616617bool verify_subtype(address start, address end) const {618verification_type_info* vti = types();619if ((address)vti < end && vti->verify(start, end)) {620int nof = number_of_types();621vti = vti->next();622if (nof < 2 || vti->verify(start, end)) {623vti = vti->next();624if (nof < 3 || vti->verify(start, end)) {625return true;626}627}628}629return false;630}631632void print_on(outputStream* st, int current_offset = -1) const {633st->print("append_frame(@%d,", offset_delta() + current_offset);634verification_type_info* vti = types();635for (int i = 0; i < number_of_types(); ++i) {636vti->print_on(st);637if (i != number_of_types() - 1) {638st->print(",");639}640vti = vti->next();641}642st->print(")");643}644645void print_truncated(outputStream* st, int current_offset = -1) const {646st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",647offset_delta() + current_offset);648}649};650651class full_frame : public stack_map_frame {652private:653address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }654address num_locals_addr() const { return offset_delta_addr() + sizeof(u2); }655address locals_addr() const { return num_locals_addr() + sizeof(u2); }656address stack_slots_addr(address end_of_locals) const {657return end_of_locals; }658address stack_addr(address end_of_locals) const {659return stack_slots_addr(end_of_locals) + sizeof(u2); }660661enum { _frame_id = 255 };662663public:664static bool is_frame_type(u1 tag) {665return tag == _frame_id;666}667668static full_frame* at(address addr) {669assert(is_frame_type(*addr), "Wrong frame id");670return (full_frame*)addr;671}672673static full_frame* create_at(674address addr, int offset_delta, int num_locals,675verification_type_info* locals,676int stack_slots, verification_type_info* stack) {677full_frame* sm = (full_frame*)addr;678sm->set_frame_type(_frame_id);679sm->set_offset_delta(offset_delta);680sm->set_num_locals(num_locals);681if (locals != NULL) {682verification_type_info* cur = sm->locals();683for (int i = 0; i < num_locals; ++i) {684cur->copy_from(locals);685cur = cur->next();686locals = locals->next();687}688address end_of_locals = (address)cur;689sm->set_stack_slots(end_of_locals, stack_slots);690cur = sm->stack(end_of_locals);691for (int i = 0; i < stack_slots; ++i) {692cur->copy_from(stack);693cur = cur->next();694stack = stack->next();695}696}697return sm;698}699700static size_t calculate_size(701int num_locals, verification_type_info* locals,702int stack_slots, verification_type_info* stack) {703size_t sz = sizeof(u1) + sizeof(u2) + sizeof(u2) + sizeof(u2);704verification_type_info* vti = locals;705for (int i = 0; i < num_locals; ++i) {706sz += vti->size();707vti = vti->next();708}709vti = stack;710for (int i = 0; i < stack_slots; ++i) {711sz += vti->size();712vti = vti->next();713}714return sz;715}716717static size_t max_size(int locals, int stack) {718return sizeof(u1) + 3 * sizeof(u2) +719(locals + stack) * verification_type_info::max_size();720}721722size_t size() const {723address eol = end_of_locals();724return calculate_size(num_locals(), locals(), stack_slots(eol), stack(eol));725}726727int offset_delta() const {728return Bytes::get_Java_u2(offset_delta_addr()) + 1;729}730int num_locals() const { return Bytes::get_Java_u2(num_locals_addr()); }731verification_type_info* locals() const {732return verification_type_info::at(locals_addr());733}734address end_of_locals() const {735verification_type_info* vti = locals();736for (int i = 0; i < num_locals(); ++i) {737vti = vti->next();738}739return (address)vti;740}741int stack_slots(address end_of_locals) const {742return Bytes::get_Java_u2(stack_slots_addr(end_of_locals));743}744verification_type_info* stack(address end_of_locals) const {745return verification_type_info::at(stack_addr(end_of_locals));746}747748void set_offset_delta(int offset_delta) {749Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);750}751void set_num_locals(int num_locals) {752Bytes::put_Java_u2(num_locals_addr(), num_locals);753}754void set_stack_slots(address end_of_locals, int stack_slots) {755Bytes::put_Java_u2(stack_slots_addr(end_of_locals), stack_slots);756}757758// These return only the locals. Extra processing is required for stack759// types of full frames.760int number_of_types() const { return num_locals(); }761verification_type_info* types() const { return locals(); }762bool is_valid_offset(int offset) { return true; }763764bool verify_subtype(address start, address end) const {765verification_type_info* vti = types();766if ((address)vti >= end) {767return false;768}769int count = number_of_types();770for (int i = 0; i < count; ++i) {771if (!vti->verify(start, end)) {772return false;773}774vti = vti->next();775}776address eol = (address)vti;777if (eol + sizeof(u2) > end) {778return false;779}780count = stack_slots(eol);781vti = stack(eol);782for (int i = 0; i < stack_slots(eol); ++i) {783if (!vti->verify(start, end)) {784return false;785}786vti = vti->next();787}788return true;789}790791void print_on(outputStream* st, int current_offset = -1) const {792st->print("full_frame(@%d,{", offset_delta() + current_offset);793verification_type_info* vti = locals();794for (int i = 0; i < num_locals(); ++i) {795vti->print_on(st);796if (i != num_locals() - 1) {797st->print(",");798}799vti = vti->next();800}801st->print("},{");802address end_of_locals = (address)vti;803vti = stack(end_of_locals);804int ss = stack_slots(end_of_locals);805for (int i = 0; i < ss; ++i) {806vti->print_on(st);807if (i != ss - 1) {808st->print(",");809}810vti = vti->next();811}812st->print("})");813}814815void print_truncated(outputStream* st, int current_offset = -1) const {816st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",817offset_delta() + current_offset);818}819};820821#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \822stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \823if (item_##stack_frame_type != NULL) { \824return item_##stack_frame_type->func_name args; \825}826827#define VOID_VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \828stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \829if (item_##stack_frame_type != NULL) { \830item_##stack_frame_type->func_name args; \831return; \832}833834size_t stack_map_frame::size() const {835FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, size, ());836return 0;837}838839int stack_map_frame::offset_delta() const {840FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, offset_delta, ());841return 0;842}843844void stack_map_frame::set_offset_delta(int offset_delta) {845FOR_EACH_STACKMAP_FRAME_TYPE(846VOID_VIRTUAL_DISPATCH, set_offset_delta, (offset_delta));847}848849int stack_map_frame::number_of_types() const {850FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, number_of_types, ());851return 0;852}853854verification_type_info* stack_map_frame::types() const {855FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, types, ());856return NULL;857}858859bool stack_map_frame::is_valid_offset(int offset) const {860FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, is_valid_offset, (offset));861return true;862}863864bool stack_map_frame::verify(address start, address end) const {865if (frame_type_addr() >= start && frame_type_addr() < end) {866FOR_EACH_STACKMAP_FRAME_TYPE(867VIRTUAL_DISPATCH, verify_subtype, (start, end));868}869return false;870}871872void stack_map_frame::print_on(outputStream* st, int offs = -1) const {873FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));874}875876void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {877FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));878}879880#undef VIRTUAL_DISPATCH881#undef VOID_VIRTUAL_DISPATCH882883#define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \884stack_frame_type* stack_map_frame::as_##stack_frame_type() const { \885if (stack_frame_type::is_frame_type(frame_type())) { \886return (stack_frame_type*)this; \887} else { \888return NULL; \889} \890}891892FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)893#undef AS_SUBTYPE_DEF894895class stack_map_table {896private:897address number_of_entries_addr() const {898return (address)this;899}900address entries_addr() const {901return number_of_entries_addr() + sizeof(u2);902}903904protected:905// No constructors - should be 'private', but GCC issues a warning if it is906stack_map_table() {}907stack_map_table(const stack_map_table&) {}908909public:910911static stack_map_table* at(address addr) {912return (stack_map_table*)addr;913}914915u2 number_of_entries() const {916return Bytes::get_Java_u2(number_of_entries_addr());917}918stack_map_frame* entries() const {919return stack_map_frame::at(entries_addr());920}921922void set_number_of_entries(u2 num) {923Bytes::put_Java_u2(number_of_entries_addr(), num);924}925};926927class stack_map_table_attribute {928private:929address name_index_addr() const {930return (address)this; }931address attribute_length_addr() const {932return name_index_addr() + sizeof(u2); }933address stack_map_table_addr() const {934return attribute_length_addr() + sizeof(u4); }935936protected:937// No constructors - should be 'private', but GCC issues a warning if it is938stack_map_table_attribute() {}939stack_map_table_attribute(const stack_map_table_attribute&) {}940941public:942943static stack_map_table_attribute* at(address addr) {944return (stack_map_table_attribute*)addr;945}946947u2 name_index() const {948return Bytes::get_Java_u2(name_index_addr()); }949u4 attribute_length() const {950return Bytes::get_Java_u4(attribute_length_addr()); }951stack_map_table* table() const {952return stack_map_table::at(stack_map_table_addr());953}954955void set_name_index(u2 idx) {956Bytes::put_Java_u2(name_index_addr(), idx);957}958void set_attribute_length(u4 len) {959Bytes::put_Java_u4(attribute_length_addr(), len);960}961};962963#undef FOR_EACH_STACKMAP_FRAME_TYPE964965#endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP966967968