7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters
Reviewed-by: twisti, kvn, jrose
This commit is contained in:
parent
bb3a527f9a
commit
0c0705ca8c
@ -270,7 +270,7 @@ void MethodHandles::RicochetFrame::leave_ricochet_frame(MacroAssembler* _masm,
|
|||||||
// Emit code to verify that FP is pointing at a valid ricochet frame.
|
// Emit code to verify that FP is pointing at a valid ricochet frame.
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
enum {
|
enum {
|
||||||
ARG_LIMIT = 255, SLOP = 35,
|
ARG_LIMIT = 255, SLOP = 45,
|
||||||
// use this parameter for checking for garbage stack movements:
|
// use this parameter for checking for garbage stack movements:
|
||||||
UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
|
UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
|
||||||
// the slop defends against false alarms due to fencepost errors
|
// the slop defends against false alarms due to fencepost errors
|
||||||
@ -1581,14 +1581,17 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
|||||||
// argslot = src_addr + swap_bytes
|
// argslot = src_addr + swap_bytes
|
||||||
// destslot = dest_addr
|
// destslot = dest_addr
|
||||||
// while (argslot <= destslot) *(argslot - swap_bytes) = *(argslot + 0), argslot++;
|
// while (argslot <= destslot) *(argslot - swap_bytes) = *(argslot + 0), argslot++;
|
||||||
__ add(O1_destslot, wordSize, O1_destslot);
|
// dest_slot denotes an exclusive upper limit
|
||||||
|
int limit_bias = OP_ROT_ARGS_DOWN_LIMIT_BIAS;
|
||||||
|
if (limit_bias != 0)
|
||||||
|
__ add(O1_destslot, - limit_bias * wordSize, O1_destslot);
|
||||||
move_arg_slots_down(_masm,
|
move_arg_slots_down(_masm,
|
||||||
Address(O0_argslot, swap_slots * wordSize),
|
Address(O0_argslot, swap_slots * wordSize),
|
||||||
O1_destslot,
|
O1_destslot,
|
||||||
-swap_slots,
|
-swap_slots,
|
||||||
O0_argslot, O2_scratch);
|
O0_argslot, O2_scratch);
|
||||||
|
|
||||||
__ sub(O1_destslot, wordSize, O1_destslot);
|
__ sub(O1_destslot, swap_slots * wordSize, O1_destslot);
|
||||||
}
|
}
|
||||||
// pop the original first chunk into the destination slot, now free
|
// pop the original first chunk into the destination slot, now free
|
||||||
switch (swap_slots) {
|
switch (swap_slots) {
|
||||||
|
@ -1644,14 +1644,16 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
|||||||
// rax = src_addr + swap_bytes
|
// rax = src_addr + swap_bytes
|
||||||
// rbx = dest_addr
|
// rbx = dest_addr
|
||||||
// while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++;
|
// while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++;
|
||||||
__ addptr(rbx_destslot, wordSize);
|
// dest_slot denotes an exclusive upper limit
|
||||||
|
int limit_bias = OP_ROT_ARGS_DOWN_LIMIT_BIAS;
|
||||||
|
if (limit_bias != 0)
|
||||||
|
__ addptr(rbx_destslot, - limit_bias * wordSize);
|
||||||
move_arg_slots_down(_masm,
|
move_arg_slots_down(_masm,
|
||||||
Address(rax_argslot, swap_slots * wordSize),
|
Address(rax_argslot, swap_slots * wordSize),
|
||||||
rbx_destslot,
|
rbx_destslot,
|
||||||
-swap_slots,
|
-swap_slots,
|
||||||
rax_argslot, rdx_temp);
|
rax_argslot, rdx_temp);
|
||||||
|
__ subptr(rbx_destslot, swap_slots * wordSize);
|
||||||
__ subptr(rbx_destslot, wordSize);
|
|
||||||
}
|
}
|
||||||
// pop the original first chunk into the destination slot, now free
|
// pop the original first chunk into the destination slot, now free
|
||||||
for (int i = 0; i < swap_slots; i++) {
|
for (int i = 0; i < swap_slots; i++) {
|
||||||
|
@ -236,9 +236,13 @@ void MethodHandleChain::print_impl(TRAPS) {
|
|||||||
case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
|
case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
|
||||||
case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
|
case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
|
||||||
case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM:
|
case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM:
|
||||||
case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: {
|
||||||
|
tty->print(" src_type = %s", type2name(chain.adapter_conversion_src_type()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS:
|
case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS:
|
||||||
case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
|
case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
|
||||||
int dest_arg_slot = chain.adapter_conversion_vminfo();
|
int dest_arg_slot = chain.adapter_conversion_vminfo();
|
||||||
@ -503,25 +507,28 @@ MethodHandleWalker::walk(TRAPS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
|
case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
|
||||||
int dest_arg_slot = chain().adapter_conversion_vminfo();
|
int limit_raw = chain().adapter_conversion_vminfo();
|
||||||
if (!has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) {
|
bool rot_down = (arg_slot < limit_raw);
|
||||||
|
int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
|
||||||
|
int limit_slot = limit_raw - limit_bias;
|
||||||
|
if ((uint)limit_slot > (uint)_outgoing.length()) {
|
||||||
lose("bad rotate index", CHECK_(empty));
|
lose("bad rotate index", CHECK_(empty));
|
||||||
}
|
}
|
||||||
// Rotate the source argument (plus following N slots) into the
|
// Rotate the source argument (plus following N slots) into the
|
||||||
// position occupied by the dest argument (plus following N slots).
|
// position occupied by the dest argument (plus following N slots).
|
||||||
int rotate_count = type2size[chain().adapter_conversion_src_type()];
|
int rotate_count = type2size[chain().adapter_conversion_src_type()];
|
||||||
// (no other rotate counts are currently supported)
|
// (no other rotate counts are currently supported)
|
||||||
if (arg_slot < dest_arg_slot) {
|
if (rot_down) {
|
||||||
for (int i = 0; i < rotate_count; i++) {
|
for (int i = 0; i < rotate_count; i++) {
|
||||||
ArgToken temp = _outgoing.at(arg_slot);
|
ArgToken temp = _outgoing.at(arg_slot);
|
||||||
_outgoing.remove_at(arg_slot);
|
_outgoing.remove_at(arg_slot);
|
||||||
_outgoing.insert_before(dest_arg_slot + rotate_count - 1, temp);
|
_outgoing.insert_before(limit_slot - 1, temp);
|
||||||
}
|
}
|
||||||
} else { // arg_slot > dest_arg_slot
|
} else { // arg_slot > limit_slot => rotate_up
|
||||||
for (int i = 0; i < rotate_count; i++) {
|
for (int i = 0; i < rotate_count; i++) {
|
||||||
ArgToken temp = _outgoing.at(arg_slot + rotate_count - 1);
|
ArgToken temp = _outgoing.at(arg_slot + rotate_count - 1);
|
||||||
_outgoing.remove_at(arg_slot + rotate_count - 1);
|
_outgoing.remove_at(arg_slot + rotate_count - 1);
|
||||||
_outgoing.insert_before(dest_arg_slot, temp);
|
_outgoing.insert_before(limit_slot, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
|
assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
|
||||||
@ -1416,8 +1423,9 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
|
|||||||
case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break;
|
case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break;
|
||||||
case T_VOID: emit_bc(Bytecodes::_return); break;
|
case T_VOID: emit_bc(Bytecodes::_return); break;
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
if (_rklass.not_null() && _rklass() != SystemDictionary::Object_klass())
|
if (_rklass.not_null() && _rklass() != SystemDictionary::Object_klass() && !Klass::cast(_rklass())->is_interface()) {
|
||||||
emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass()));
|
emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass()));
|
||||||
|
}
|
||||||
emit_bc(Bytecodes::_areturn);
|
emit_bc(Bytecodes::_areturn);
|
||||||
break;
|
break;
|
||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
|
@ -205,9 +205,6 @@ void MethodHandles::generate_adapters() {
|
|||||||
CodeBuffer code(_adapter_code);
|
CodeBuffer code(_adapter_code);
|
||||||
MethodHandlesAdapterGenerator g(&code);
|
MethodHandlesAdapterGenerator g(&code);
|
||||||
g.generate();
|
g.generate();
|
||||||
|
|
||||||
// Transfer code comments
|
|
||||||
_adapter_code->set_comments(code.comments());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1980,52 +1977,77 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _adapter_swap_args:
|
case _adapter_swap_args:
|
||||||
case _adapter_rot_args:
|
|
||||||
{
|
{
|
||||||
if (!src || src != dest) {
|
if (!src || !dest) {
|
||||||
err = "adapter requires src/dest conversion subfields for swap"; break;
|
err = "adapter requires src/dest conversion subfields for swap"; break;
|
||||||
}
|
}
|
||||||
int swap_size = type2size[src];
|
int src_size = type2size[src];
|
||||||
|
if (src_size != type2size[dest]) {
|
||||||
|
err = "adapter requires equal sizes for src/dest"; break;
|
||||||
|
}
|
||||||
int src_slot = argslot;
|
int src_slot = argslot;
|
||||||
int dest_slot = vminfo;
|
int dest_slot = vminfo;
|
||||||
bool rotate_up = (src_slot > dest_slot); // upward rotation
|
|
||||||
int src_arg = argnum;
|
int src_arg = argnum;
|
||||||
int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot);
|
int dest_arg = argument_slot_to_argnum(src_mtype(), dest_slot);
|
||||||
verify_vmargslot(target, dest_arg, dest_slot, CHECK);
|
verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
|
||||||
if (!(dest_slot >= src_slot + swap_size) &&
|
if (!(dest_slot >= src_slot + src_size) &&
|
||||||
!(src_slot >= dest_slot + swap_size)) {
|
!(src_slot >= dest_slot + src_size)) {
|
||||||
err = "source, destination slots must be distinct";
|
err = "source, destination slots must be distinct"; break;
|
||||||
} else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
|
} else if (!(src_slot > dest_slot)) {
|
||||||
err = "source of swap must be deeper in stack";
|
err = "source of swap must be deeper in stack"; break;
|
||||||
} else if (ek == _adapter_swap_args) {
|
|
||||||
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
|
|
||||||
java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
|
|
||||||
dest_arg);
|
|
||||||
} else if (ek == _adapter_rot_args) {
|
|
||||||
if (rotate_up) {
|
|
||||||
assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
|
|
||||||
// rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
|
|
||||||
// that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
|
|
||||||
for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
|
|
||||||
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
|
|
||||||
java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
|
|
||||||
i);
|
|
||||||
}
|
|
||||||
} else { // rotate down
|
|
||||||
assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
|
|
||||||
// rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
|
|
||||||
// that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
|
|
||||||
for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
|
|
||||||
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
|
|
||||||
java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
|
|
||||||
i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
|
||||||
|
java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
|
||||||
|
dest_arg);
|
||||||
if (err == NULL)
|
if (err == NULL)
|
||||||
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
|
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
|
||||||
java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
|
java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
|
||||||
src_arg);
|
src_arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case _adapter_rot_args:
|
||||||
|
{
|
||||||
|
if (!src || !dest) {
|
||||||
|
err = "adapter requires src/dest conversion subfields for rotate"; break;
|
||||||
|
}
|
||||||
|
int src_slot = argslot;
|
||||||
|
int limit_raw = vminfo;
|
||||||
|
bool rot_down = (src_slot < limit_raw);
|
||||||
|
int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
|
||||||
|
int limit_slot = limit_raw - limit_bias;
|
||||||
|
int src_arg = argnum;
|
||||||
|
int limit_arg = argument_slot_to_argnum(src_mtype(), limit_slot);
|
||||||
|
verify_vmargslot(mh, limit_arg, limit_slot, CHECK);
|
||||||
|
if (src_slot == limit_slot) {
|
||||||
|
err = "source, destination slots must be distinct"; break;
|
||||||
|
}
|
||||||
|
if (!rot_down) { // rotate slots up == shift arguments left
|
||||||
|
// limit_slot is an inclusive lower limit
|
||||||
|
assert((src_slot > limit_slot) && (src_arg < limit_arg), "");
|
||||||
|
// rotate up: [limit_slot..src_slot-ss] --> [limit_slot+ss..src_slot]
|
||||||
|
// that is: [src_arg+1..limit_arg] --> [src_arg..limit_arg-1]
|
||||||
|
for (int i = src_arg+1; i <= limit_arg && err == NULL; i++) {
|
||||||
|
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
|
||||||
|
java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
|
||||||
|
i);
|
||||||
|
}
|
||||||
|
} else { // rotate slots down == shfit arguments right
|
||||||
|
// limit_slot is an exclusive upper limit
|
||||||
|
assert((src_slot < limit_slot - limit_bias) && (src_arg > limit_arg + limit_bias), "");
|
||||||
|
// rotate down: [src_slot+ss..limit_slot) --> [src_slot..limit_slot-ss)
|
||||||
|
// that is: (limit_arg..src_arg-1] --> (dst_arg+1..src_arg]
|
||||||
|
for (int i = limit_arg+1; i <= src_arg-1 && err == NULL; i++) {
|
||||||
|
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
|
||||||
|
java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
|
||||||
|
i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == NULL) {
|
||||||
|
int dest_arg = (rot_down ? limit_arg+1 : limit_arg);
|
||||||
|
err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
|
||||||
|
java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
|
||||||
|
src_arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _adapter_spread_args:
|
case _adapter_spread_args:
|
||||||
@ -2813,6 +2835,8 @@ JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
|
|||||||
return MethodHandles::stack_move_unit();
|
return MethodHandles::stack_move_unit();
|
||||||
case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
|
case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
|
||||||
return MethodHandles::adapter_conversion_ops_supported_mask();
|
return MethodHandles::adapter_conversion_ops_supported_mask();
|
||||||
|
case MethodHandles::GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS:
|
||||||
|
return MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2824,6 +2848,8 @@ JVM_END
|
|||||||
/* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \
|
/* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \
|
||||||
/* hold back this one until JDK stabilizes */ \
|
/* hold back this one until JDK stabilizes */ \
|
||||||
/* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \
|
/* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \
|
||||||
|
/* hold back this one until JDK stabilizes */ \
|
||||||
|
/* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \
|
||||||
template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
|
template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
|
||||||
template(MethodHandles,ETF_DIRECT_HANDLE) \
|
template(MethodHandles,ETF_DIRECT_HANDLE) \
|
||||||
template(MethodHandles,ETF_METHOD_NAME) \
|
template(MethodHandles,ETF_METHOD_NAME) \
|
||||||
|
@ -581,12 +581,16 @@ class MethodHandles: AllStatic {
|
|||||||
GC_JVM_PUSH_LIMIT = 0,
|
GC_JVM_PUSH_LIMIT = 0,
|
||||||
GC_JVM_STACK_MOVE_UNIT = 1,
|
GC_JVM_STACK_MOVE_UNIT = 1,
|
||||||
GC_CONV_OP_IMPLEMENTED_MASK = 2,
|
GC_CONV_OP_IMPLEMENTED_MASK = 2,
|
||||||
|
GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3,
|
||||||
|
|
||||||
// format of result from getTarget / encode_target:
|
// format of result from getTarget / encode_target:
|
||||||
ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
|
ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
|
||||||
ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
|
ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
|
||||||
ETF_METHOD_NAME = 2, // ultimate method as MemberName
|
ETF_METHOD_NAME = 2, // ultimate method as MemberName
|
||||||
ETF_REFLECT_METHOD = 3 // ultimate method as java.lang.reflect object (sans refClass)
|
ETF_REFLECT_METHOD = 3, // ultimate method as java.lang.reflect object (sans refClass)
|
||||||
|
|
||||||
|
// ad hoc constants
|
||||||
|
OP_ROT_ARGS_DOWN_LIMIT_BIAS = -1
|
||||||
};
|
};
|
||||||
static int get_named_constant(int which, Handle name_box, TRAPS);
|
static int get_named_constant(int which, Handle name_box, TRAPS);
|
||||||
static oop encode_target(Handle mh, int format, TRAPS); // report vmtarget (to Java code)
|
static oop encode_target(Handle mh, int format, TRAPS); // report vmtarget (to Java code)
|
||||||
@ -828,7 +832,7 @@ address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->
|
|||||||
//
|
//
|
||||||
class MethodHandlesAdapterGenerator : public StubCodeGenerator {
|
class MethodHandlesAdapterGenerator : public StubCodeGenerator {
|
||||||
public:
|
public:
|
||||||
MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {}
|
MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code, PrintMethodHandleStubs) {}
|
||||||
|
|
||||||
void generate();
|
void generate();
|
||||||
};
|
};
|
||||||
|
@ -3715,6 +3715,9 @@ class CommandLineFlags {
|
|||||||
diagnostic(intx, MethodHandlePushLimit, 3, \
|
diagnostic(intx, MethodHandlePushLimit, 3, \
|
||||||
"number of additional stack slots a method handle may push") \
|
"number of additional stack slots a method handle may push") \
|
||||||
\
|
\
|
||||||
|
diagnostic(bool, PrintMethodHandleStubs, false, \
|
||||||
|
"Print generated stub code for method handles") \
|
||||||
|
\
|
||||||
develop(bool, TraceMethodHandles, false, \
|
develop(bool, TraceMethodHandles, false, \
|
||||||
"trace internal method handle operations") \
|
"trace internal method handle operations") \
|
||||||
\
|
\
|
||||||
|
@ -80,9 +80,10 @@ void StubCodeDesc::print_on(outputStream* st) const {
|
|||||||
|
|
||||||
// Implementation of StubCodeGenerator
|
// Implementation of StubCodeGenerator
|
||||||
|
|
||||||
StubCodeGenerator::StubCodeGenerator(CodeBuffer* code) {
|
StubCodeGenerator::StubCodeGenerator(CodeBuffer* code, bool print_code) {
|
||||||
_masm = new MacroAssembler(code);
|
_masm = new MacroAssembler(code);
|
||||||
_first_stub = _last_stub = NULL;
|
_first_stub = _last_stub = NULL;
|
||||||
|
_print_code = print_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -94,7 +95,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StubCodeGenerator::~StubCodeGenerator() {
|
StubCodeGenerator::~StubCodeGenerator() {
|
||||||
if (PrintStubCode) {
|
if (PrintStubCode || _print_code) {
|
||||||
CodeBuffer* cbuf = _masm->code();
|
CodeBuffer* cbuf = _masm->code();
|
||||||
CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start());
|
CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start());
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
|
@ -98,9 +98,10 @@ class StubCodeGenerator: public StackObj {
|
|||||||
|
|
||||||
StubCodeDesc* _first_stub;
|
StubCodeDesc* _first_stub;
|
||||||
StubCodeDesc* _last_stub;
|
StubCodeDesc* _last_stub;
|
||||||
|
bool _print_code;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StubCodeGenerator(CodeBuffer* code);
|
StubCodeGenerator(CodeBuffer* code, bool print_code = false);
|
||||||
~StubCodeGenerator();
|
~StubCodeGenerator();
|
||||||
|
|
||||||
MacroAssembler* assembler() const { return _masm; }
|
MacroAssembler* assembler() const { return _masm; }
|
||||||
|
Loading…
Reference in New Issue
Block a user