7145346: VerifyStackAtCalls is broken
Replace call_epilog() encoding with macroassembler use. Moved duplicated code to x86.ad. Fixed return_addr() definition. Reviewed-by: never
This commit is contained in:
parent
9e339b8ded
commit
867f3ba889
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -37,10 +37,87 @@ source %{
|
|||||||
static address double_signmask() { return (address)double_signmask_pool; }
|
static address double_signmask() { return (address)double_signmask_pool; }
|
||||||
static address double_signflip() { return (address)double_signflip_pool; }
|
static address double_signflip() { return (address)double_signflip_pool; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
|
||||||
|
st->print("nop \t# %d bytes pad for loops and calls", _count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const {
|
||||||
|
MacroAssembler _masm(&cbuf);
|
||||||
|
__ nop(_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint MachNopNode::size(PhaseRegAlloc*) const {
|
||||||
|
return _count;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const {
|
||||||
|
st->print("# breakpoint");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
|
||||||
|
MacroAssembler _masm(&cbuf);
|
||||||
|
__ int3();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
|
||||||
|
return MachNode::size(ra_);
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
encode %{
|
||||||
|
|
||||||
|
enc_class preserve_SP %{
|
||||||
|
debug_only(int off0 = cbuf.insts_size());
|
||||||
|
MacroAssembler _masm(&cbuf);
|
||||||
|
// RBP is preserved across all calls, even compiled calls.
|
||||||
|
// Use it to preserve RSP in places where the callee might change the SP.
|
||||||
|
__ movptr(rbp_mh_SP_save, rsp);
|
||||||
|
debug_only(int off1 = cbuf.insts_size());
|
||||||
|
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
||||||
|
%}
|
||||||
|
|
||||||
|
enc_class restore_SP %{
|
||||||
|
MacroAssembler _masm(&cbuf);
|
||||||
|
__ movptr(rsp, rbp_mh_SP_save);
|
||||||
|
%}
|
||||||
|
|
||||||
|
enc_class call_epilog %{
|
||||||
|
if (VerifyStackAtCalls) {
|
||||||
|
// Check that stack depth is unchanged: find majik cookie on stack
|
||||||
|
int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
|
||||||
|
MacroAssembler _masm(&cbuf);
|
||||||
|
Label L;
|
||||||
|
__ cmpptr(Address(rsp, framesize), (int32_t)0xbadb100d);
|
||||||
|
__ jccb(Assembler::equal, L);
|
||||||
|
// Die if stack mismatch
|
||||||
|
__ int3();
|
||||||
|
__ bind(L);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform independent definitions (same for 32- and 64-bit)
|
// INSTRUCTIONS -- Platform independent definitions (same for 32- and 64-bit)
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
instruct ShouldNotReachHere() %{
|
||||||
|
match(Halt);
|
||||||
|
format %{ "int3\t# ShouldNotReachHere" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ int3();
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
instruct addF_reg(regF dst, regF src) %{
|
instruct addF_reg(regF dst, regF src) %{
|
||||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||||
match(Set dst (AddF dst src));
|
match(Set dst (AddF dst src));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -341,12 +341,6 @@ int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
|
|||||||
return round_to(current_offset, alignment_required()) - current_offset;
|
return round_to(current_offset, alignment_required()) - current_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
|
|
||||||
st->print("INT3");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EMIT_RM()
|
// EMIT_RM()
|
||||||
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
||||||
unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3);
|
unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3);
|
||||||
@ -1130,22 +1124,6 @@ uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
|
|||||||
return implementation( NULL, ra_, true, NULL );
|
return implementation( NULL, ra_, true, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
#ifndef PRODUCT
|
|
||||||
void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
|
|
||||||
st->print("NOP \t# %d bytes pad for loops and calls", _count);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
|
|
||||||
MacroAssembler _masm(&cbuf);
|
|
||||||
__ nop(_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint MachNopNode::size(PhaseRegAlloc *) const {
|
|
||||||
return _count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
@ -1831,21 +1809,6 @@ encode %{
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class preserve_SP %{
|
|
||||||
debug_only(int off0 = cbuf.insts_size());
|
|
||||||
MacroAssembler _masm(&cbuf);
|
|
||||||
// RBP is preserved across all calls, even compiled calls.
|
|
||||||
// Use it to preserve RSP in places where the callee might change the SP.
|
|
||||||
__ movptr(rbp_mh_SP_save, rsp);
|
|
||||||
debug_only(int off1 = cbuf.insts_size());
|
|
||||||
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class restore_SP %{
|
|
||||||
MacroAssembler _masm(&cbuf);
|
|
||||||
__ movptr(rsp, rbp_mh_SP_save);
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
|
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
|
||||||
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
|
||||||
// who we intended to call.
|
// who we intended to call.
|
||||||
@ -3794,9 +3757,9 @@ frame %{
|
|||||||
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
|
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
|
||||||
// Otherwise, it is above the locks and verification slot and alignment word
|
// Otherwise, it is above the locks and verification slot and alignment word
|
||||||
return_addr(STACK - 1 +
|
return_addr(STACK - 1 +
|
||||||
round_to(1+VerifyStackAtCalls+
|
round_to((Compile::current()->in_preserve_stack_slots() +
|
||||||
Compile::current()->fixed_slots(),
|
Compile::current()->fixed_slots()),
|
||||||
(StackAlignmentInBytes/wordSize)));
|
stack_alignment_in_slots()));
|
||||||
|
|
||||||
// Body of function which returns an integer array locating
|
// Body of function which returns an integer array locating
|
||||||
// arguments either in registers or in stack slots. Passed an array
|
// arguments either in registers or in stack slots. Passed an array
|
||||||
@ -13424,6 +13387,25 @@ instruct safePoint_poll(eFlagsReg cr) %{
|
|||||||
ins_pipe( ialu_reg_mem );
|
ins_pipe( ialu_reg_mem );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// This name is KNOWN by the ADLC and cannot be changed.
|
||||||
|
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
||||||
|
// for this guy.
|
||||||
|
instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
|
||||||
|
match(Set dst (ThreadLocal));
|
||||||
|
effect(DEF dst, KILL cr);
|
||||||
|
|
||||||
|
format %{ "MOV $dst, Thread::current()" %}
|
||||||
|
ins_encode %{
|
||||||
|
Register dstReg = as_Register($dst$$reg);
|
||||||
|
__ get_thread(dstReg);
|
||||||
|
%}
|
||||||
|
ins_pipe( ialu_reg_fat );
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------PEEPHOLE RULES-----------------------------------------------------
|
//----------PEEPHOLE RULES-----------------------------------------------------
|
||||||
// These must follow all instruction definitions as they use the names
|
// These must follow all instruction definitions as they use the names
|
||||||
// defined in the instructions definitions.
|
// defined in the instructions definitions.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -610,13 +610,6 @@ int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
|
|||||||
return round_to(current_offset, alignment_required()) - current_offset;
|
return round_to(current_offset, alignment_required()) - current_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const
|
|
||||||
{
|
|
||||||
st->print("INT3");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EMIT_RM()
|
// EMIT_RM()
|
||||||
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
|
||||||
unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
|
unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
|
||||||
@ -1528,26 +1521,6 @@ uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const
|
|||||||
return implementation(NULL, ra_, true, NULL);
|
return implementation(NULL, ra_, true, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
#ifndef PRODUCT
|
|
||||||
void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const
|
|
||||||
{
|
|
||||||
st->print("nop \t# %d bytes pad for loops and calls", _count);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const
|
|
||||||
{
|
|
||||||
MacroAssembler _masm(&cbuf);
|
|
||||||
__ nop(_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint MachNopNode::size(PhaseRegAlloc*) const
|
|
||||||
{
|
|
||||||
return _count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||||
@ -2255,21 +2228,6 @@ encode %{
|
|||||||
RELOC_DISP32);
|
RELOC_DISP32);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class preserve_SP %{
|
|
||||||
debug_only(int off0 = cbuf.insts_size());
|
|
||||||
MacroAssembler _masm(&cbuf);
|
|
||||||
// RBP is preserved across all calls, even compiled calls.
|
|
||||||
// Use it to preserve RSP in places where the callee might change the SP.
|
|
||||||
__ movptr(rbp_mh_SP_save, rsp);
|
|
||||||
debug_only(int off1 = cbuf.insts_size());
|
|
||||||
assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class restore_SP %{
|
|
||||||
MacroAssembler _masm(&cbuf);
|
|
||||||
__ movptr(rsp, rbp_mh_SP_save);
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class Java_Static_Call(method meth)
|
enc_class Java_Static_Call(method meth)
|
||||||
%{
|
%{
|
||||||
// JAVA STATIC CALL
|
// JAVA STATIC CALL
|
||||||
@ -3208,9 +3166,9 @@ frame
|
|||||||
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
|
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
|
||||||
// Otherwise, it is above the locks and verification slot and alignment word
|
// Otherwise, it is above the locks and verification slot and alignment word
|
||||||
return_addr(STACK - 2 +
|
return_addr(STACK - 2 +
|
||||||
round_to(2 + 2 * VerifyStackAtCalls +
|
round_to((Compile::current()->in_preserve_stack_slots() +
|
||||||
Compile::current()->fixed_slots(),
|
Compile::current()->fixed_slots()),
|
||||||
WordsPerLong * 2));
|
stack_alignment_in_slots()));
|
||||||
|
|
||||||
// Body of function which returns an integer array locating
|
// Body of function which returns an integer array locating
|
||||||
// arguments either in registers or in stack slots. Passed an array
|
// arguments either in registers or in stack slots. Passed an array
|
||||||
@ -11668,6 +11626,21 @@ instruct RethrowException()
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// This name is KNOWN by the ADLC and cannot be changed.
|
||||||
|
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
||||||
|
// for this guy.
|
||||||
|
instruct tlsLoadP(r15_RegP dst) %{
|
||||||
|
match(Set dst (ThreadLocal));
|
||||||
|
effect(DEF dst);
|
||||||
|
|
||||||
|
size(0);
|
||||||
|
format %{ "# TLS is in R15" %}
|
||||||
|
ins_encode( /*empty encoding*/ );
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
//----------PEEPHOLE RULES-----------------------------------------------------
|
//----------PEEPHOLE RULES-----------------------------------------------------
|
||||||
// These must follow all instruction definitions as they use the names
|
// These must follow all instruction definitions as they use the names
|
||||||
// defined in the instructions definitions.
|
// defined in the instructions definitions.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,137 +24,3 @@
|
|||||||
|
|
||||||
// X86 Bsd Architecture Description File
|
// X86 Bsd Architecture Description File
|
||||||
|
|
||||||
//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
|
|
||||||
// This block specifies the encoding classes used by the compiler to output
|
|
||||||
// byte streams. Encoding classes generate functions which are called by
|
|
||||||
// Machine Instruction Nodes in order to generate the bit encoding of the
|
|
||||||
// instruction. Operands specify their base encoding interface with the
|
|
||||||
// interface keyword. There are currently supported four interfaces,
|
|
||||||
// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
|
|
||||||
// operand to generate a function which returns its register number when
|
|
||||||
// queried. CONST_INTER causes an operand to generate a function which
|
|
||||||
// returns the value of the constant when queried. MEMORY_INTER causes an
|
|
||||||
// operand to generate four functions which return the Base Register, the
|
|
||||||
// Index Register, the Scale Value, and the Offset Value of the operand when
|
|
||||||
// queried. COND_INTER causes an operand to generate six functions which
|
|
||||||
// return the encoding code (ie - encoding bits for the instruction)
|
|
||||||
// associated with each basic boolean condition for a conditional instruction.
|
|
||||||
// Instructions specify two basic values for encoding. They use the
|
|
||||||
// ins_encode keyword to specify their encoding class (which must be one of
|
|
||||||
// the class names specified in the encoding block), and they use the
|
|
||||||
// opcode keyword to specify, in order, their primary, secondary, and
|
|
||||||
// tertiary opcode. Only the opcode sections which a particular instruction
|
|
||||||
// needs for encoding need to be specified.
|
|
||||||
encode %{
|
|
||||||
// Build emit functions for each basic byte or larger field in the intel
|
|
||||||
// encoding scheme (opcode, rm, sib, immediate), and call them from C++
|
|
||||||
// code in the enc_class source block. Emit functions will live in the
|
|
||||||
// main source block for now. In future, we can generalize this by
|
|
||||||
// adding a syntax that specifies the sizes of fields in an order,
|
|
||||||
// so that the adlc can build the emit functions automagically
|
|
||||||
|
|
||||||
enc_class bsd_tlsencode (eRegP dst) %{
|
|
||||||
Register dstReg = as_Register($dst$$reg);
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->get_thread(dstReg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class bsd_breakpoint %{
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog %{
|
|
||||||
if( VerifyStackAtCalls ) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
|
|
||||||
if(framesize >= 128) {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0xBC);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d32(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0x7C);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d8(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 5; // size of call to breakpoint, 1 for CC
|
|
||||||
emit_opcode(cbuf,0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst, KILL cr);
|
|
||||||
|
|
||||||
format %{ "MOV $dst, Thread::current()" %}
|
|
||||||
ins_encode( bsd_tlsencode(dst) );
|
|
||||||
ins_pipe( ialu_reg_fat );
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct TLS(eRegP dst) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
|
|
||||||
expand %{
|
|
||||||
tlsLoadP(dst);
|
|
||||||
%}
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere( )
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "INT3 ; ShouldNotReachHere" %}
|
|
||||||
// QQQ TODO for now call breakpoint
|
|
||||||
// opcode(0xCC);
|
|
||||||
// ins_encode(Opc);
|
|
||||||
ins_encode(bsd_breakpoint);
|
|
||||||
ins_pipe( pipe_slow );
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Platform dependent source
|
|
||||||
|
|
||||||
source %{
|
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
|
||||||
|
|
||||||
// Debugger doesn't really catch this but best we can do so far QQQ
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -55,8 +55,7 @@ encode %{
|
|||||||
// adding a syntax that specifies the sizes of fields in an order,
|
// adding a syntax that specifies the sizes of fields in an order,
|
||||||
// so that the adlc can build the emit functions automagically
|
// so that the adlc can build the emit functions automagically
|
||||||
|
|
||||||
enc_class Java_To_Runtime(method meth)
|
enc_class Java_To_Runtime(method meth) %{
|
||||||
%{
|
|
||||||
// No relocation needed
|
// No relocation needed
|
||||||
|
|
||||||
// movq r10, <meth>
|
// movq r10, <meth>
|
||||||
@ -70,104 +69,15 @@ encode %{
|
|||||||
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class bsd_breakpoint
|
|
||||||
%{
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog
|
|
||||||
%{
|
|
||||||
if (VerifyStackAtCalls) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize =
|
|
||||||
ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
|
|
||||||
if (framesize) {
|
|
||||||
if (framesize < 0x80) {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0x7C);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d8(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
} else {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0xBC);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d32(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 5; // size of call to breakpoint, 1 for CC
|
|
||||||
emit_opcode(cbuf, 0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(r15_RegP dst)
|
|
||||||
%{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst);
|
|
||||||
|
|
||||||
size(0);
|
|
||||||
format %{ "# TLS is in R15" %}
|
|
||||||
ins_encode( /*empty encoding*/ );
|
|
||||||
ins_pipe(ialu_reg_reg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere()
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "int3\t# ShouldNotReachHere" %}
|
|
||||||
// QQQ TODO for now call breakpoint
|
|
||||||
// opcode(0xCC);
|
|
||||||
// ins_encode(Opc);
|
|
||||||
ins_encode(bsd_breakpoint);
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Platform dependent source
|
// Platform dependent source
|
||||||
|
|
||||||
source
|
source %{
|
||||||
%{
|
|
||||||
|
|
||||||
int MachCallRuntimeNode::ret_addr_offset() {
|
int MachCallRuntimeNode::ret_addr_offset() {
|
||||||
return 13; // movq r10,#addr; callq (r10)
|
return 13; // movq r10,#addr; callq (r10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer& cbuf) {
|
|
||||||
// Debugger doesn't really catch this but best we can do so far QQQ
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,137 +24,3 @@
|
|||||||
|
|
||||||
// X86 Linux Architecture Description File
|
// X86 Linux Architecture Description File
|
||||||
|
|
||||||
//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
|
|
||||||
// This block specifies the encoding classes used by the compiler to output
|
|
||||||
// byte streams. Encoding classes generate functions which are called by
|
|
||||||
// Machine Instruction Nodes in order to generate the bit encoding of the
|
|
||||||
// instruction. Operands specify their base encoding interface with the
|
|
||||||
// interface keyword. There are currently supported four interfaces,
|
|
||||||
// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
|
|
||||||
// operand to generate a function which returns its register number when
|
|
||||||
// queried. CONST_INTER causes an operand to generate a function which
|
|
||||||
// returns the value of the constant when queried. MEMORY_INTER causes an
|
|
||||||
// operand to generate four functions which return the Base Register, the
|
|
||||||
// Index Register, the Scale Value, and the Offset Value of the operand when
|
|
||||||
// queried. COND_INTER causes an operand to generate six functions which
|
|
||||||
// return the encoding code (ie - encoding bits for the instruction)
|
|
||||||
// associated with each basic boolean condition for a conditional instruction.
|
|
||||||
// Instructions specify two basic values for encoding. They use the
|
|
||||||
// ins_encode keyword to specify their encoding class (which must be one of
|
|
||||||
// the class names specified in the encoding block), and they use the
|
|
||||||
// opcode keyword to specify, in order, their primary, secondary, and
|
|
||||||
// tertiary opcode. Only the opcode sections which a particular instruction
|
|
||||||
// needs for encoding need to be specified.
|
|
||||||
encode %{
|
|
||||||
// Build emit functions for each basic byte or larger field in the intel
|
|
||||||
// encoding scheme (opcode, rm, sib, immediate), and call them from C++
|
|
||||||
// code in the enc_class source block. Emit functions will live in the
|
|
||||||
// main source block for now. In future, we can generalize this by
|
|
||||||
// adding a syntax that specifies the sizes of fields in an order,
|
|
||||||
// so that the adlc can build the emit functions automagically
|
|
||||||
|
|
||||||
enc_class linux_tlsencode (eRegP dst) %{
|
|
||||||
Register dstReg = as_Register($dst$$reg);
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->get_thread(dstReg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class linux_breakpoint %{
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog %{
|
|
||||||
if( VerifyStackAtCalls ) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
|
|
||||||
if(framesize >= 128) {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0xBC);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d32(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0x7C);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d8(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 5; // size of call to breakpoint, 1 for CC
|
|
||||||
emit_opcode(cbuf,0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst, KILL cr);
|
|
||||||
|
|
||||||
format %{ "MOV $dst, Thread::current()" %}
|
|
||||||
ins_encode( linux_tlsencode(dst) );
|
|
||||||
ins_pipe( ialu_reg_fat );
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct TLS(eRegP dst) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
|
|
||||||
expand %{
|
|
||||||
tlsLoadP(dst);
|
|
||||||
%}
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere( )
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "INT3 ; ShouldNotReachHere" %}
|
|
||||||
// QQQ TODO for now call breakpoint
|
|
||||||
// opcode(0xCC);
|
|
||||||
// ins_encode(Opc);
|
|
||||||
ins_encode(linux_breakpoint);
|
|
||||||
ins_pipe( pipe_slow );
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Platform dependent source
|
|
||||||
|
|
||||||
source %{
|
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
|
||||||
|
|
||||||
// Debugger doesn't really catch this but best we can do so far QQQ
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
|
|
||||||
return MachNode::size(ra_);
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -55,8 +55,7 @@ encode %{
|
|||||||
// adding a syntax that specifies the sizes of fields in an order,
|
// adding a syntax that specifies the sizes of fields in an order,
|
||||||
// so that the adlc can build the emit functions automagically
|
// so that the adlc can build the emit functions automagically
|
||||||
|
|
||||||
enc_class Java_To_Runtime(method meth)
|
enc_class Java_To_Runtime(method meth) %{
|
||||||
%{
|
|
||||||
// No relocation needed
|
// No relocation needed
|
||||||
|
|
||||||
// movq r10, <meth>
|
// movq r10, <meth>
|
||||||
@ -70,105 +69,15 @@ encode %{
|
|||||||
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class linux_breakpoint
|
|
||||||
%{
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog
|
|
||||||
%{
|
|
||||||
if (VerifyStackAtCalls) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize =
|
|
||||||
ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
|
|
||||||
if (framesize) {
|
|
||||||
if (framesize < 0x80) {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0x7C);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d8(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
} else {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0xBC);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d32(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 5; // size of call to breakpoint, 1 for CC
|
|
||||||
emit_opcode(cbuf, 0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(r15_RegP dst)
|
|
||||||
%{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst);
|
|
||||||
|
|
||||||
size(0);
|
|
||||||
format %{ "# TLS is in R15" %}
|
|
||||||
ins_encode( /*empty encoding*/ );
|
|
||||||
ins_pipe(ialu_reg_reg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere()
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "int3\t# ShouldNotReachHere" %}
|
|
||||||
// QQQ TODO for now call breakpoint
|
|
||||||
// opcode(0xCC);
|
|
||||||
// ins_encode(Opc);
|
|
||||||
ins_encode(linux_breakpoint);
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Platform dependent source
|
// Platform dependent source
|
||||||
|
|
||||||
source
|
source %{
|
||||||
%{
|
|
||||||
|
|
||||||
int MachCallRuntimeNode::ret_addr_offset() {
|
int MachCallRuntimeNode::ret_addr_offset() {
|
||||||
return 13; // movq r10,#addr; callq (r10)
|
return 13; // movq r10,#addr; callq (r10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer& cbuf) {
|
|
||||||
// Debugger doesn't really catch this but best we can do so far QQQ
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
|
|
||||||
// distance could be far and requires load and call through register
|
|
||||||
return MachNode::size(ra_);
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,144 +24,3 @@
|
|||||||
|
|
||||||
// X86 Solaris Architecture Description File
|
// X86 Solaris Architecture Description File
|
||||||
|
|
||||||
//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
|
|
||||||
// This block specifies the encoding classes used by the compiler to output
|
|
||||||
// byte streams. Encoding classes generate functions which are called by
|
|
||||||
// Machine Instruction Nodes in order to generate the bit encoding of the
|
|
||||||
// instruction. Operands specify their base encoding interface with the
|
|
||||||
// interface keyword. There are currently supported four interfaces,
|
|
||||||
// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
|
|
||||||
// operand to generate a function which returns its register number when
|
|
||||||
// queried. CONST_INTER causes an operand to generate a function which
|
|
||||||
// returns the value of the constant when queried. MEMORY_INTER causes an
|
|
||||||
// operand to generate four functions which return the Base Register, the
|
|
||||||
// Index Register, the Scale Value, and the Offset Value of the operand when
|
|
||||||
// queried. COND_INTER causes an operand to generate six functions which
|
|
||||||
// return the encoding code (ie - encoding bits for the instruction)
|
|
||||||
// associated with each basic boolean condition for a conditional instruction.
|
|
||||||
// Instructions specify two basic values for encoding. They use the
|
|
||||||
// ins_encode keyword to specify their encoding class (which must be one of
|
|
||||||
// the class names specified in the encoding block), and they use the
|
|
||||||
// opcode keyword to specify, in order, their primary, secondary, and
|
|
||||||
// tertiary opcode. Only the opcode sections which a particular instruction
|
|
||||||
// needs for encoding need to be specified.
|
|
||||||
encode %{
|
|
||||||
// Build emit functions for each basic byte or larger field in the intel
|
|
||||||
// encoding scheme (opcode, rm, sib, immediate), and call them from C++
|
|
||||||
// code in the enc_class source block. Emit functions will live in the
|
|
||||||
// main source block for now. In future, we can generalize this by
|
|
||||||
// adding a syntax that specifies the sizes of fields in an order,
|
|
||||||
// so that the adlc can build the emit functions automagically
|
|
||||||
|
|
||||||
enc_class solaris_tlsencode (eRegP dst) %{
|
|
||||||
Register dstReg = as_Register($dst$$reg);
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->get_thread(dstReg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class solaris_breakpoint %{
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
// Really need to fix this
|
|
||||||
masm->push(rax);
|
|
||||||
masm->push(rcx);
|
|
||||||
masm->push(rdx);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
masm->pop(rdx);
|
|
||||||
masm->pop(rcx);
|
|
||||||
masm->pop(rax);
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog %{
|
|
||||||
if( VerifyStackAtCalls ) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
|
|
||||||
if(framesize >= 128) {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0xBC);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d32(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0x7C);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d8(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 11; // size of call to breakpoint (and register preserve), 1 for CC
|
|
||||||
emit_opcode(cbuf,0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst, KILL cr);
|
|
||||||
|
|
||||||
format %{ "MOV $dst, Thread::current()" %}
|
|
||||||
ins_encode( solaris_tlsencode(dst) );
|
|
||||||
ins_pipe( ialu_reg_fat );
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct TLS(eRegP dst) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
|
|
||||||
expand %{
|
|
||||||
tlsLoadP(dst);
|
|
||||||
%}
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere( )
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "INT3 ; ShouldNotReachHere" %}
|
|
||||||
// QQQ TODO for now call breakpoint
|
|
||||||
// opcode(0xCC);
|
|
||||||
// ins_encode(Opc);
|
|
||||||
ins_encode(solaris_breakpoint);
|
|
||||||
ins_pipe( pipe_slow );
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Platform dependent source
|
|
||||||
|
|
||||||
source %{
|
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
|
||||||
|
|
||||||
// Debugger doesn't really catch this but best we can do so far QQQ
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
|
|
||||||
return MachNode::size(ra_);
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -55,8 +55,7 @@ encode %{
|
|||||||
// adding a syntax that specifies the sizes of fields in an order,
|
// adding a syntax that specifies the sizes of fields in an order,
|
||||||
// so that the adlc can build the emit functions automagically
|
// so that the adlc can build the emit functions automagically
|
||||||
|
|
||||||
enc_class Java_To_Runtime(method meth)
|
enc_class Java_To_Runtime(method meth) %{
|
||||||
%{
|
|
||||||
// No relocation needed
|
// No relocation needed
|
||||||
|
|
||||||
// movq r10, <meth>
|
// movq r10, <meth>
|
||||||
@ -70,118 +69,24 @@ encode %{
|
|||||||
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class solaris_breakpoint
|
|
||||||
%{
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog
|
|
||||||
%{
|
|
||||||
if (VerifyStackAtCalls) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize =
|
|
||||||
ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
|
|
||||||
if (framesize) {
|
|
||||||
if (framesize < 0x80) {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0x7C);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d8(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
} else {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0xBC);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d32(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 5; // size of call to breakpoint, 1 for CC
|
|
||||||
emit_opcode(cbuf, 0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class post_call_verify_mxcsr %{
|
enc_class post_call_verify_mxcsr %{
|
||||||
MacroAssembler masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
if (RestoreMXCSROnJNICalls) {
|
if (RestoreMXCSROnJNICalls) {
|
||||||
masm.ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std()));
|
__ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std()));
|
||||||
}
|
}
|
||||||
else if (CheckJNICalls) {
|
else if (CheckJNICalls) {
|
||||||
masm.call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry())));
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(r15_RegP dst)
|
|
||||||
%{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst);
|
|
||||||
|
|
||||||
size(0);
|
|
||||||
format %{ "# TLS is in R15" %}
|
|
||||||
ins_encode( /*empty encoding*/ );
|
|
||||||
ins_pipe(ialu_reg_reg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere()
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "int3\t# ShouldNotReachHere" %}
|
|
||||||
// QQQ TODO for now call breakpoint
|
|
||||||
// opcode(0xCC);
|
|
||||||
// ins_encode(Opc);
|
|
||||||
ins_encode(solaris_breakpoint);
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
// Platform dependent source
|
// Platform dependent source
|
||||||
|
|
||||||
source
|
source %{
|
||||||
%{
|
|
||||||
|
|
||||||
int MachCallRuntimeNode::ret_addr_offset()
|
int MachCallRuntimeNode::ret_addr_offset() {
|
||||||
{
|
|
||||||
return 13; // movq r10,#addr; callq (r10)
|
return 13; // movq r10,#addr; callq (r10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer& cbuf)
|
|
||||||
{
|
|
||||||
// Debugger doesn't really catch this but best we can do so far QQQ
|
|
||||||
MacroAssembler* masm = new MacroAssembler(&cbuf);
|
|
||||||
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
|
||||||
{
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const
|
|
||||||
{
|
|
||||||
// distance could be far and requires load and call through register
|
|
||||||
return MachNode::size(ra_);
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,134 +24,3 @@
|
|||||||
|
|
||||||
// X86 Win32 Architecture Description File
|
// X86 Win32 Architecture Description File
|
||||||
|
|
||||||
//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
|
|
||||||
// This block specifies the encoding classes used by the compiler to output
|
|
||||||
// byte streams. Encoding classes generate functions which are called by
|
|
||||||
// Machine Instruction Nodes in order to generate the bit encoding of the
|
|
||||||
// instruction. Operands specify their base encoding interface with the
|
|
||||||
// interface keyword. There are currently supported four interfaces,
|
|
||||||
// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
|
|
||||||
// operand to generate a function which returns its register number when
|
|
||||||
// queried. CONST_INTER causes an operand to generate a function which
|
|
||||||
// returns the value of the constant when queried. MEMORY_INTER causes an
|
|
||||||
// operand to generate four functions which return the Base Register, the
|
|
||||||
// Index Register, the Scale Value, and the Offset Value of the operand when
|
|
||||||
// queried. COND_INTER causes an operand to generate six functions which
|
|
||||||
// return the encoding code (ie - encoding bits for the instruction)
|
|
||||||
// associated with each basic boolean condition for a conditional instruction.
|
|
||||||
// Instructions specify two basic values for encoding. They use the
|
|
||||||
// ins_encode keyword to specify their encoding class (which must be one of
|
|
||||||
// the class names specified in the encoding block), and they use the
|
|
||||||
// opcode keyword to specify, in order, their primary, secondary, and
|
|
||||||
// tertiary opcode. Only the opcode sections which a particular instruction
|
|
||||||
// needs for encoding need to be specified.
|
|
||||||
encode %{
|
|
||||||
// Build emit functions for each basic byte or larger field in the intel
|
|
||||||
// encoding scheme (opcode, rm, sib, immediate), and call them from C++
|
|
||||||
// code in the enc_class source block. Emit functions will live in the
|
|
||||||
// main source block for now. In future, we can generalize this by
|
|
||||||
// adding a syntax that specifies the sizes of fields in an order,
|
|
||||||
// so that the adlc can build the emit functions automagically
|
|
||||||
|
|
||||||
enc_class tlsencode (eRegP dst, eRegP src) %{
|
|
||||||
emit_rm(cbuf, 0x2, $dst$$reg, $src$$reg);
|
|
||||||
emit_d32(cbuf, ThreadLocalStorage::get_thread_ptr_offset() );
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class call_epilog %{
|
|
||||||
if( VerifyStackAtCalls ) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
|
|
||||||
if(framesize >= 128) {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0xBC);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d32(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf,0x7C);
|
|
||||||
emit_d8(cbuf,0x24);
|
|
||||||
emit_d8(cbuf,framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
emit_opcode(cbuf,0x74);
|
|
||||||
emit_d8(cbuf,1);
|
|
||||||
// Die if stack mismatch
|
|
||||||
emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// The prefix of this name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
instruct tlsLoadP_prefixLoadP(eRegP t1) %{
|
|
||||||
effect(DEF t1);
|
|
||||||
|
|
||||||
format %{ "MOV $t1,FS:[0x00] "%}
|
|
||||||
opcode(0x8B, 0x64);
|
|
||||||
ins_encode(OpcS, OpcP, conmemref(t1));
|
|
||||||
ins_pipe( ialu_reg_fat );
|
|
||||||
%}
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
// %%% Should do this with a clause like: bottom_type(TypeRawPtr::BOTTOM);
|
|
||||||
instruct tlsLoadP(eRegP dst, eRegP t1) %{
|
|
||||||
effect(DEF dst, USE t1);
|
|
||||||
|
|
||||||
format %{ "MOV $dst,[$t1 + TLS::thread_ptr_offset()]" %}
|
|
||||||
opcode(0x8B);
|
|
||||||
ins_encode(OpcP, tlsencode(dst, t1));
|
|
||||||
ins_pipe( ialu_reg_reg_fat );
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct TLS(eRegP dst) %{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
expand %{
|
|
||||||
eRegP t1;
|
|
||||||
tlsLoadP_prefixLoadP(t1);
|
|
||||||
tlsLoadP(dst, t1);
|
|
||||||
%}
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere( )
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "INT3 ; ShouldNotReachHere" %}
|
|
||||||
opcode(0xCC);
|
|
||||||
ins_encode(OpcP);
|
|
||||||
ins_pipe( pipe_slow );
|
|
||||||
%}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Platform dependent source
|
|
||||||
//
|
|
||||||
source %{
|
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
|
||||||
cbuf.insts()->emit_int8((unsigned char) 0xcc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
@ -67,69 +67,6 @@ encode %{
|
|||||||
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class call_epilog %{
|
|
||||||
if (VerifyStackAtCalls) {
|
|
||||||
// Check that stack depth is unchanged: find majik cookie on stack
|
|
||||||
int framesize =
|
|
||||||
ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
|
|
||||||
if (framesize) {
|
|
||||||
if (framesize < 0x80) {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0x7C);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d8(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
} else {
|
|
||||||
emit_opcode(cbuf, Assembler::REX_W);
|
|
||||||
emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
|
|
||||||
emit_d8(cbuf, 0xBC);
|
|
||||||
emit_d8(cbuf, 0x24);
|
|
||||||
emit_d32(cbuf, framesize); // Find majik cookie from ESP
|
|
||||||
emit_d32(cbuf, 0xbadb100d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// jmp EQ around INT3
|
|
||||||
// QQQ TODO
|
|
||||||
const int jump_around = 5; // size of call to breakpoint, 1 for CC
|
|
||||||
emit_opcode(cbuf, 0x74);
|
|
||||||
emit_d8(cbuf, jump_around);
|
|
||||||
// QQQ temporary
|
|
||||||
emit_break(cbuf);
|
|
||||||
// Die if stack mismatch
|
|
||||||
// emit_opcode(cbuf,0xCC);
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
%}
|
|
||||||
|
|
||||||
// INSTRUCTIONS -- Platform dependent
|
|
||||||
|
|
||||||
|
|
||||||
//----------OS and Locking Instructions----------------------------------------
|
|
||||||
|
|
||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
|
||||||
// for this guy.
|
|
||||||
instruct tlsLoadP(r15_RegP dst)
|
|
||||||
%{
|
|
||||||
match(Set dst (ThreadLocal));
|
|
||||||
effect(DEF dst);
|
|
||||||
|
|
||||||
size(0);
|
|
||||||
format %{ "# TLS is in R15" %}
|
|
||||||
ins_encode( /*empty encoding*/ );
|
|
||||||
ins_pipe(ialu_reg_reg);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Die now
|
|
||||||
instruct ShouldNotReachHere( )
|
|
||||||
%{
|
|
||||||
match(Halt);
|
|
||||||
// Use the following format syntax
|
|
||||||
format %{ "INT3 ; ShouldNotReachHere" %}
|
|
||||||
opcode(0xCC);
|
|
||||||
ins_encode(OpcP);
|
|
||||||
ins_pipe( pipe_slow );
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -142,17 +79,4 @@ int MachCallRuntimeNode::ret_addr_offset()
|
|||||||
return 13; // movq r10,#addr; callq (r10)
|
return 13; // movq r10,#addr; callq (r10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger
|
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
|
||||||
cbuf.insts()->emit_int8((unsigned char) 0xcc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|
||||||
emit_break(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1946,18 +1946,29 @@ void PhaseChaitin::dump_frame() const {
|
|||||||
reg2offset_unchecked(OptoReg::add(_matcher._old_SP,-1)) - reg2offset_unchecked(_matcher._new_SP)+jintSize);
|
reg2offset_unchecked(OptoReg::add(_matcher._old_SP,-1)) - reg2offset_unchecked(_matcher._new_SP)+jintSize);
|
||||||
|
|
||||||
// Preserve area dump
|
// Preserve area dump
|
||||||
|
int fixed_slots = C->fixed_slots();
|
||||||
|
OptoReg::Name begin_in_preserve = OptoReg::add(_matcher._old_SP, -(int)C->in_preserve_stack_slots());
|
||||||
|
OptoReg::Name return_addr = _matcher.return_addr();
|
||||||
|
|
||||||
reg = OptoReg::add(reg, -1);
|
reg = OptoReg::add(reg, -1);
|
||||||
while (OptoReg::is_stack(reg)) {
|
while (OptoReg::is_stack(reg)) {
|
||||||
tty->print("#r%3.3d %s+%2d: ",reg,fp,reg2offset_unchecked(reg));
|
tty->print("#r%3.3d %s+%2d: ",reg,fp,reg2offset_unchecked(reg));
|
||||||
if( _matcher.return_addr() == reg )
|
if (return_addr == reg) {
|
||||||
tty->print_cr("return address");
|
tty->print_cr("return address");
|
||||||
else if( _matcher.return_addr() == OptoReg::add(reg,1) &&
|
} else if (reg >= begin_in_preserve) {
|
||||||
|
// Preserved slots are present on x86
|
||||||
|
if (return_addr == OptoReg::add(reg, VMRegImpl::slots_per_word))
|
||||||
|
tty->print_cr("saved fp register");
|
||||||
|
else if (return_addr == OptoReg::add(reg, 2*VMRegImpl::slots_per_word) &&
|
||||||
VerifyStackAtCalls)
|
VerifyStackAtCalls)
|
||||||
tty->print_cr("0xBADB100D +VerifyStackAtCalls");
|
tty->print_cr("0xBADB100D +VerifyStackAtCalls");
|
||||||
else if ((int)OptoReg::reg2stack(reg) < C->fixed_slots())
|
|
||||||
tty->print_cr("Fixed slot %d", OptoReg::reg2stack(reg));
|
|
||||||
else
|
else
|
||||||
tty->print_cr("pad2, in_preserve");
|
tty->print_cr("in_preserve");
|
||||||
|
} else if ((int)OptoReg::reg2stack(reg) < fixed_slots) {
|
||||||
|
tty->print_cr("Fixed slot %d", OptoReg::reg2stack(reg));
|
||||||
|
} else {
|
||||||
|
tty->print_cr("pad2, stack alignment");
|
||||||
|
}
|
||||||
reg = OptoReg::add(reg, -1);
|
reg = OptoReg::add(reg, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user