Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/stackMapTable.hpp
32285 views
/*1* Copyright (c) 2003, 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_STACKMAPTABLE_HPP25#define SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP2627#include "classfile/stackMapFrame.hpp"28#include "classfile/verifier.hpp"29#include "memory/allocation.hpp"30#include "oops/constantPool.hpp"31#include "oops/method.hpp"32#include "utilities/globalDefinitions.hpp"33#ifdef TARGET_ARCH_x8634# include "bytes_x86.hpp"35#endif36#ifdef TARGET_ARCH_aarch3237# include "bytes_aarch32.hpp"38#endif39#ifdef TARGET_ARCH_aarch6440# include "bytes_aarch64.hpp"41#endif42#ifdef TARGET_ARCH_sparc43# include "bytes_sparc.hpp"44#endif45#ifdef TARGET_ARCH_zero46# include "bytes_zero.hpp"47#endif48#ifdef TARGET_ARCH_arm49# include "bytes_arm.hpp"50#endif51#ifdef TARGET_ARCH_ppc52# include "bytes_ppc.hpp"53#endif5455class StackMapReader;5657// StackMapTable class is the StackMap table used by type checker58class StackMapTable : public StackObj {59private:60// Logically, the _frame_count (as well as many fields in the StackFrame)61// should be a u2, but if we defined the variable as that type it will62// be difficult to detect/recover from overflow or underflow conditions.63// Widening the type and making it signed will help detect these.64int32_t _code_length;65int32_t _frame_count; // Stackmap frame count66StackMapFrame** _frame_array;6768public:69StackMapTable(StackMapReader* reader, StackMapFrame* init_frame,70u2 max_locals, u2 max_stack,71char* code_data, int code_len, TRAPS);7273inline int32_t get_frame_count() const { return _frame_count; }74inline int get_offset(int index) const {75return _frame_array[index]->offset();76}7778// Match and/or update current_frame to the frame in stackmap table with79// specified offset. Return true if the two frames match.80bool match_stackmap(81StackMapFrame* current_frame, int32_t offset,82bool match, bool update, ErrorContext* ctx, TRAPS) const;83// Match and/or update current_frame to the frame in stackmap table with84// specified offset and frame index. Return true if the two frames match.85bool match_stackmap(86StackMapFrame* current_frame, int32_t offset, int32_t frame_index,87bool match, bool update, ErrorContext* ctx, TRAPS) const;8889// Check jump instructions. Make sure there are no uninitialized90// instances on backward branch.91void check_jump_target(StackMapFrame* frame, int32_t target, TRAPS) const;9293// The following methods are only used inside this class.9495// Returns the frame array index where the frame with offset is stored.96int get_index_from_offset(int32_t offset) const;9798void print_on(outputStream* str) const;99};100101class StackMapStream : StackObj {102private:103Array<u1>* _data;104int _index;105public:106StackMapStream(Array<u1>* ah)107: _data(ah), _index(0) {108}109u1 get_u1(TRAPS) {110if (_data == NULL || _index >= _data->length()) {111stackmap_format_error("access beyond the end of attribute", CHECK_0);112}113return _data->at(_index++);114}115u2 get_u2(TRAPS) {116if (_data == NULL || _index >= _data->length() - 1) {117stackmap_format_error("access beyond the end of attribute", CHECK_0);118}119u2 res = Bytes::get_Java_u2(_data->adr_at(_index));120_index += 2;121return res;122}123bool at_end() {124return (_data == NULL) || (_index == _data->length());125}126static void stackmap_format_error(const char* msg, TRAPS);127};128129class StackMapReader : StackObj {130private:131// information about the class and method132constantPoolHandle _cp;133ClassVerifier* _verifier;134StackMapStream* _stream;135char* _code_data;136int32_t _code_length;137138// information get from the attribute139int32_t _frame_count; // frame count140141int32_t chop(VerificationType* locals, int32_t length, int32_t chops);142VerificationType parse_verification_type(u1* flags, TRAPS);143void check_verification_type_array_size(144int32_t size, int32_t max_size, TRAPS) {145if (size < 0 || size > max_size) {146// Since this error could be caused someone rewriting the method147// but not knowing to update the stackmap data, we call the the148// verifier's error method, which may not throw an exception and149// failover to the old verifier instead.150_verifier->class_format_error(151"StackMapTable format error: bad type array size");152}153}154155enum {156SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,157SAME_EXTENDED = 251,158FULL = 255159};160161public:162// Constructor163StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data,164int32_t code_len, TRAPS) :165_verifier(v), _stream(stream),166_code_data(code_data), _code_length(code_len) {167methodHandle m = v->method();168if (m->has_stackmap_table()) {169_cp = constantPoolHandle(THREAD, m->constants());170_frame_count = _stream->get_u2(CHECK);171} else {172// There's no stackmap table present. Frame count and size are 0.173_frame_count = 0;174}175}176177inline int32_t get_frame_count() const { return _frame_count; }178StackMapFrame* next(StackMapFrame* pre_frame, bool first,179u2 max_locals, u2 max_stack, TRAPS);180181void check_end(TRAPS) {182if (!_stream->at_end()) {183StackMapStream::stackmap_format_error("wrong attribute size", CHECK);184}185}186};187188#endif // SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP189190191