You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2007/07/31 15:36:53 UTC
svn commit: r561327 - in /harmony/enhanced/drlvm/trunk:
src/test/regression/H4514/ vm/jitrino/src/codegenerator/ia32/
vm/port/include/ vm/port/src/lil/em64t/pim/ vm/port/src/lil/ia32/pim/
vm/port/src/lil/ipf/pim/ vm/vmcore/src/util/ipf/base/ vm/vmcore/...
Author: mfursov
Date: Tue Jul 31 06:36:49 2007
New Revision: 561327
URL: http://svn.apache.org/viewvc?view=rev&rev=561327
Log:
Fix for HARMONY-4433 (IPF related)
Fix for HARMONY-4568 (Native SOE in recursion-based algorithm in Jitrino.OPT)
update for regression from HARMONY-4514 - making it more sensitive to bytecode offsets.
Modified:
harmony/enhanced/drlvm/trunk/src/test/regression/H4514/Test.java
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h
harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/lil_code_generator_ipf.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf_internal.h
harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/stub_code_utils.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/Code_Emitter.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/stub_code_utils.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/vm_ipf.h
Modified: harmony/enhanced/drlvm/trunk/src/test/regression/H4514/Test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H4514/Test.java?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H4514/Test.java (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H4514/Test.java Tue Jul 31 06:36:49 2007
@@ -3,49 +3,64 @@
public class Test extends TestCase {
public void testTrace1() {
+ //some useless code
+ int i=0;
+ int j=1;
try {
assertEquals(0, 1); //the number of this line must be in tracktracelement
} catch (Throwable e) {
StackTraceElement thisFrame = findThisFrame(e);
- assertEquals(7, thisFrame.getLineNumber());
+ assertEquals(10, thisFrame.getLineNumber());
}
}
public void testTrace2() {
+ //some useless code
+ int i=0;
+ int j=1;
try {
fail();//the number of this line must be in tracktracelement
} catch (Throwable e) {
StackTraceElement thisFrame = findThisFrame(e);
- assertEquals(16, thisFrame.getLineNumber());
+ assertEquals(22, thisFrame.getLineNumber());
}
}
public void testTrace3() {
+ //some useless code
+ int i=0;
+ int j=1;
try {
assertEquals(true, false);//the number of this line must be in tracktracelement
} catch (Throwable e) {
StackTraceElement thisFrame = findThisFrame(e);
- assertEquals(25, thisFrame.getLineNumber());
+ assertEquals(34, thisFrame.getLineNumber());
}
}
public void testTrace4() {
+ //some useless code
+ int i=0;
+ int j=1;
try {
assertNotNull(null);//the number of this line must be in tracktracelement
} catch (Throwable e) {
StackTraceElement thisFrame = findThisFrame(e);
- assertEquals(35, thisFrame.getLineNumber());
+ assertEquals(47, thisFrame.getLineNumber());
}
}
public void testTrace5() {
+ //some useless code
+ int i=0;
+ int j=1;
try {
assertEquals("", "fail");//the number of this line must be in tracktracelement
} catch (Throwable e) {
StackTraceElement thisFrame = findThisFrame(e);
- assertEquals(45, thisFrame.getLineNumber());
+ assertEquals(60, thisFrame.getLineNumber());
}
}
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp Tue Jul 31 06:36:49 2007
@@ -69,6 +69,7 @@
///methods fo registering bc-offsets for inlined methods
void registerBCOffsets(Node* node, InlineInfoMap::Entry* parentEntry);
+ InlineInfoMap::Entry* processBlockOffsets(Node* node, InlineInfoMap::Entry* parentEntry);
void registerBCMappingAndInlineInfo();
void orderNodesAndMarkInlinees(StlList<MethodMarkerPseudoInst*>& container,
@@ -336,10 +337,7 @@
return getTopLevelEntryOffset(entry->parentEntry);
}
-void CodeEmitter::registerBCOffsets(Node* node, InlineInfoMap::Entry* parentEntry) {
- assert(traversalInfo[node->getId()] == 0);
- traversalInfo[node->getId()] = 1;
-
+InlineInfoMap::Entry* CodeEmitter::processBlockOffsets(Node* node, InlineInfoMap::Entry* parentEntry) {
for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) {
if (inst->getKind() == Inst::Kind_MethodEntryPseudoInst) {
if (Log::isEnabled()) {
@@ -394,6 +392,13 @@
}
}
}
+ return parentEntry;
+}
+
+void CodeEmitter::registerBCOffsets(Node* node, InlineInfoMap::Entry* parentEntry) {
+ assert(traversalInfo[node->getId()] == 0);
+ traversalInfo[node->getId()] = 1;
+ parentEntry = processBlockOffsets(node, parentEntry);
const Edges& edges = node->getOutEdges();
for (Edges::const_iterator ite = edges.begin(), ende = edges.end(); ite!=ende; ++ite) {
Edge* e = *ite;
Modified: harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h Tue Jul 31 06:36:49 2007
@@ -41,23 +41,19 @@
struct M2nFrame;
-enum frame_type {
- FRAME_UNKNOWN = 0x00,
- FRAME_NON_UNWINDABLE = 0x80,
- FRAME_JNI = 0x01 | FRAME_NON_UNWINDABLE,
- FRAME_COMPILATION = 0x02 | FRAME_NON_UNWINDABLE,
+typedef uint32 frame_type;
- FRAME_UNPOPABLE = 0x0000,
- FRAME_POPABLE = 0x0100,
- FRAME_POP_NOW = 0x0200,
- FRAME_POP_DONE = FRAME_POPABLE | FRAME_POP_NOW,
-
- FRAME_POP_MASK = 0x0700,
-
- FRAME_SAFE_POINT = 0x0800,
-
- FRAME_MODIFIED_STACK = 0x1000
-};
+extern const uint32 FRAME_UNKNOWN;
+extern const uint32 FRAME_NON_UNWINDABLE;
+extern const uint32 FRAME_JNI;
+extern const uint32 FRAME_COMPILATION;
+extern const uint32 FRAME_UNPOPABLE;
+extern const uint32 FRAME_POPABLE;
+extern const uint32 FRAME_POP_NOW;
+extern const uint32 FRAME_POP_DONE;
+extern const uint32 FRAME_POP_MASK;
+extern const uint32 FRAME_SAFE_POINT;
+extern const uint32 FRAME_MODIFIED_STACK;
// The pushing and popping of native frames is done only by stubs that
// implement the managed to native transitions. These stubs use code that is
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp Tue Jul 31 06:36:49 2007
@@ -311,7 +311,6 @@
// Stack Iterator Interface
StackIterator * si_create_from_native() {
- ASSERT_NO_INTERPRETER
return si_create_from_native(p_TLS_vmthread);
}
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp Tue Jul 31 06:36:49 2007
@@ -232,18 +232,7 @@
StackIterator* si_create_from_native()
{
- ASSERT_NO_INTERPRETER
- // Allocate iterator
- StackIterator* res = (StackIterator*)STD_MALLOC(sizeof(StackIterator));
- assert(res);
- memset(res, 0, sizeof(StackIterator));
-
- res->cci = NULL;
- res->m2nfl = m2n_get_last_frame();
- res->ip = 0;
- res->c.p_eip = &res->ip;
-
- return res;
+ return si_create_from_native(p_TLS_vmthread);
}
StackIterator* si_create_from_native(VM_thread* thread)
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/lil_code_generator_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/lil_code_generator_ipf.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/lil_code_generator_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/lil_code_generator_ipf.cpp Tue Jul 31 06:36:49 2007
@@ -600,6 +600,10 @@
return 16 + stk_output_size;
}
+ bool has_push_m2n() {
+ return has_m2n;
+ }
+
private:
//*****************
// helper functions, used by visitor functions
@@ -1966,7 +1970,13 @@
// Set new gp
emit_mov_imm_compactor(emitter, GP_REG, (uint64)gp_new);
}
- emitter.ipf_brl_call(br_many, br_sptk, br_none, BRANCH_RETURN_LINK_REG, (uint64)fn_addr);
+ emit_mov_imm_compactor(emitter, tmp_res->addr, (uint64)fn_addr, 0);
+ if (context.has_push_m2n()) {
+ emitter.ipf_mtbr(BRANCH_CALL_REG, tmp_res->addr);
+ emit_mov_imm_compactor(emitter, tmp_res->addr, (uint64)m2n_gen_flush_and_call(), 0);
+ }
+ emitter.ipf_mtbr(tmp_br, tmp_res->addr);
+ emitter.ipf_bricall(br_few, br_sptk, br_none, BRANCH_RETURN_LINK_REG, tmp_br);
if (gp_new != gp_old) {
// Restore gp
const LcgIpfLoc* gp_save_gr = context.get_gp_save_gr();
@@ -1990,9 +2000,12 @@
else {
ASSERT(0, "Unexpected kind"); // address can't be FP!
}
+ if (context.has_push_m2n()) {
+ emitter.ipf_mtbr(BRANCH_CALL_REG, call_addr_gr);
+ emit_mov_imm_compactor(emitter, call_addr_gr, (uint64)m2n_gen_flush_and_call(), 0);
+ }
emitter.ipf_mtbr(tmp_br, call_addr_gr);
- emitter.ipf_bricall(br_few, br_sptk, br_none,
- BRANCH_RETURN_LINK_REG, tmp_br);
+ emitter.ipf_bricall(br_few, br_sptk, br_none, BRANCH_RETURN_LINK_REG, tmp_br);
}
} // call
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf.cpp Tue Jul 31 06:36:49 2007
@@ -74,6 +74,7 @@
uint64* m2n_get_extra_saved(M2nFrame* m2nf)
{
+ do_flushrs();
return (uint64*)*get_stacked_register_address(m2n_get_bsp(m2nf), M2N_EXTRA_SAVED_PTR);
}
@@ -194,6 +195,44 @@
//***** Stub Interface
+// Flushes register stack of the current thread into backing store and calls target procedure.
+NativeCodePtr m2n_gen_flush_and_call() {
+ static NativeCodePtr addr = NULL;
+
+ if (addr != NULL) {
+ return addr;
+ }
+
+ tl::MemoryPool mem_pool;
+ Merced_Code_Emitter emitter(mem_pool, 2, 0);
+ emitter.disallow_instruction_exchange();
+ emitter.memory_type_is_unknown();
+
+ // We need to remember pfs & b0 here but there is no space to save them in.
+ // Register stack contains valid outputs and we don't know how many registers are used.
+ // Memory stack holds output values beyound those 8 which are on register stack.
+ // The only place is general caller-saves registers. It is save to use them with out preserving
+ // because they are alredy preserved by the corresponding M2N frame.
+
+ // r4 is used to keep a thread pointer...so let's use r5 & r6.
+
+ emitter.ipf_mfap(PRESERV_GENERAL_REG1, AR_pfs);
+ emitter.ipf_mfbr(PRESERV_GENERAL_REG2, BRANCH_RETURN_LINK_REG);
+
+ emitter.flush_buffer();
+ emitter.ipf_flushrs();
+
+ emitter.ipf_bricall(br_many, br_sptk, br_none, BRANCH_RETURN_LINK_REG, BRANCH_CALL_REG);
+
+ emitter.ipf_mtbr(BRANCH_RETURN_LINK_REG, PRESERV_GENERAL_REG2);
+ emitter.ipf_mtap(AR_pfs, PRESERV_GENERAL_REG1);
+
+ emitter.ipf_brret(br_few, br_sptk, br_none, BRANCH_RETURN_LINK_REG);
+
+ addr = finalize_stub(emitter, "");
+ return addr;
+}
+
unsigned m2n_gen_push_m2n(Merced_Code_Emitter* emitter, Method_Handle method, frame_type current_frame_type, bool handles, unsigned num_on_stack, unsigned num_local, unsigned num_out, bool do_alloc)
{
// Allocate new frame
@@ -211,7 +250,8 @@
// Save predicates, SP, and callee saves general registers
emitter->ipf_adds(M2N_SAVED_SP, num_on_stack, SP_REG);
- emitter->ipf_mfpr(M2N_SAVED_PR );
+ emitter->ipf_mfpr(M2N_SAVED_PR );
+ emitter->ipf_mfap(M2N_SAVED_UNAT, AR_unat);
emitter->ipf_mov (M2N_SAVED_R4, 4);
emitter->ipf_mov (M2N_SAVED_R5, 5);
emitter->ipf_mov (M2N_SAVED_R6, 6);
@@ -222,6 +262,61 @@
emit_mov_imm_compactor(*emitter, M2N_METHOD, (uint64)method);
emit_mov_imm_compactor(*emitter, M2N_FRAME_TYPE, (uint64)current_frame_type);
+ const int P1 = SCRATCH_PRED_REG;
+ const int P2 = SCRATCH_PRED_REG2;
+ const int OLD_RSE_MODE = SCRATCH_GENERAL_REG2;
+ const int NEW_RSE_MODE = SCRATCH_GENERAL_REG3;
+ // SCRATCH_GENERAL_REG4 & SCRATCH_GENERAL_REG5 are reserved for std places.
+ const int BSP = SCRATCH_GENERAL_REG6;
+ const int IMM_8 = SCRATCH_GENERAL_REG7;
+ const int IMM_1F8 = SCRATCH_GENERAL_REG8;
+ const int TMP_REG = SCRATCH_GENERAL_REG9;
+ // Scratch branch register.
+ const int TMP_BRANCH_REG = 6;
+
+ // Switch RSE to "forced lazy" mode. This is required to access RNAT.
+ emitter->ipf_mfap(OLD_RSE_MODE, AR_rsc);
+ emitter->ipf_dep(NEW_RSE_MODE, 0, OLD_RSE_MODE, 0, 2);
+ emitter->ipf_mtap(AR_rsc, NEW_RSE_MODE);
+
+ // Flush must be the first instruction in the group.
+ emitter->flush_buffer();
+ // Spill parent frames so that corresponding RNAT bits become valid.
+ emitter->ipf_flushrs();
+ // Extract backing store pointer
+ emitter->ipf_mfap(BSP, AR_bsp);
+ // Remember parent RNAT collection.
+ emitter->ipf_mfap(M2N_EXTRA_RNAT, AR_rnat);
+
+ // TODO: This is not fully legal reset nat bits for the whole m2n frame because it
+ // contains r4-r7 general registers which may have corresponding unat bits up.
+ emitter->ipf_mov(M2N_EXTRA_UNAT, 0);
+
+/* The following code spills M2N into backing store.
+ emitter->ipf_movl(IMM_1F8, 0, (uint64)0x1f8);
+ emitter->ipf_movl(IMM_8, 0, (uint64)0x8);
+
+ // Forcebly spill M2N frame into backing store.
+ for(int i = M2N_NUMBER_INPUTS; i < M2N_NUMBER_LOCALS; i++) {
+ emitter->ipf_and(TMP_REG, IMM_1F8, BSP);
+ emitter->ipf_cmp(icmp_eq, cmp_none, P1, P2, IMM_1F8, TMP_REG);
+ emitter->ipf_add(BSP, BSP, IMM_8, P1);
+ emitter->ipf_st_inc_imm(int_mem_size_8, mem_st_spill, mem_none, BSP, 32 + i, 8);
+ }
+
+ // Remember UNAT collection for the current frame.
+ emitter->ipf_sub(BSP, BSP, IMM_8);
+ emitter->ipf_mfap(M2N_EXTRA_UNAT, AR_unat);
+ emitter->ipf_st(int_mem_size_8, mem_st_none, mem_none, BSP, M2N_EXTRA_UNAT);
+
+ // Restore original UNAT.
+ emitter->ipf_mtap(AR_unat, M2N_SAVED_UNAT);
+ emitter->flush_buffer();
+*/
+
+ // Switch RSE to the original mode.
+ emitter->ipf_mtap(AR_rsc, OLD_RSE_MODE);
+
// Link M2nFrame into list of current thread
size_t offset_lm2nf = (size_t)&((VM_thread*)0)->last_m2n_frame;
emitter->ipf_adds(SCRATCH_GENERAL_REG2, (int)offset_lm2nf, THREAD_PTR_REG);
@@ -284,9 +379,9 @@
}
if (handles) {
- emit_call_with_gp(*emitter, (void**)m2n_pop_local_handles);
+ emit_call_with_gp(*emitter, (void**)m2n_pop_local_handles, false);
} else {
- emit_call_with_gp(*emitter, (void**)m2n_free_local_handles);
+ emit_call_with_gp(*emitter, (void**)m2n_free_local_handles, false);
}
// Restore return register
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf_internal.h?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/m2n_ipf_internal.h Tue Jul 31 06:36:49 2007
@@ -100,11 +100,14 @@
uint64* m2n_get_bsp(M2nFrame*);
uint64* m2n_get_extra_saved(M2nFrame*);
+// Flushes register stack of the current thread into backing store and calls target procedure.
+NativeCodePtr m2n_gen_flush_and_call();
+
// An M2nFrame will always have 8 input registers, some local stacked registers to save stuff, and some outputs
#define M2N_NUMBER_ALIGNS 2
#define M2N_NUMBER_INPUTS 8
-#define M2N_NUMBER_LOCALS 14
+#define M2N_NUMBER_LOCALS 17
// The following registers are used in M2nFrames to hold the indicated values
// The register numbers must be distinct, at least 40 (so they don't conflict with inputs), and less than 40+M2N_NUMBER_LOCALS
@@ -115,14 +118,18 @@
#define M2N_SAVED_SP 43
#define M2N_SAVED_GP 44
#define M2N_SAVED_PR 45
-#define M2N_SAVED_R4 46
-#define M2N_SAVED_R5 47
-#define M2N_SAVED_R6 48
-#define M2N_SAVED_R7 49
-#define M2N_EXTRA_SAVED_PTR 50
-#define M2N_OBJECT_HANDLES 51
-#define M2N_METHOD 52
-#define M2N_FRAME_TYPE 53
+#define M2N_SAVED_UNAT 46
+#define M2N_SAVED_R4 47
+#define M2N_SAVED_R5 48
+#define M2N_SAVED_R6 49
+#define M2N_SAVED_R7 50
+#define M2N_EXTRA_SAVED_PTR 51
+#define M2N_OBJECT_HANDLES 52
+#define M2N_METHOD 53
+#define M2N_FRAME_TYPE 54
+#define M2N_EXTRA_RNAT 55
+// this must be last register
+#define M2N_EXTRA_UNAT 56
// Only the callee saves general registers are normally saved in the M2nFrame along with special things like pfs, return address, etc.
// The full set of preserved registers includes callee saves floating point and branch registers as well.
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp Tue Jul 31 06:36:49 2007
@@ -71,8 +71,8 @@
M2nFrame* m2nfl;
uint64 ip;
uint64* bsp;
- uint64* last_legal_rsnat;
- uint64 extra_nats;
+ uint64 extra_rnats;
+ uint64 extra_unats;
};
//////////////////////////////////////////////////////////////////////////
@@ -82,28 +82,60 @@
// this flush. We assume that all nat bits we are interested in do not change from the time of flush
// to after we are finished with the iterator that calls this function, even if the rse engine has
// returned to a point prior to bsp.
+/*
static void si_init_nats(StackIterator* si, uint64* bsp, uint64 rnat)
{
si->last_legal_rsnat = (uint64*)((uint64)bsp & ~0x1f8);
si->extra_nats = rnat;
}
+*/
// This function flushes the rse and puts the value of bsp/bspstore into res[1] and rnat into res[0]
+/*
extern "C" void get_rnat_and_bsp(uint64* res);
extern "C" void get_rnat_and_bspstore(uint64* res);
+*/
+
+static uint64 get_rnat(uint64 * bsp) {
+ uint64 * last_m2n = (uint64 *)m2n_get_last_frame();
+ uint64 * rnat_ptr = (uint64*)((uint64)bsp | (uint64)0x1f8);
+ uint64 * extra_nat_ptr;
+
+ if (rnat_ptr <= last_m2n) {
+ return *rnat_ptr;
+ }
+
+ // All nat bits for last M2N are stored at M2N_EXTRA_UNAT.
+ // All nat bits for parent frames are stored at M2N_EXTRA_RNAT.
+
+ if (bsp >= last_m2n) {
+ extra_nat_ptr = last_m2n + (M2N_EXTRA_UNAT - 32);
+ } else {
+ extra_nat_ptr = last_m2n + (M2N_EXTRA_RNAT - 32);
+ }
+
+ if (rnat_ptr <= extra_nat_ptr) {
+ // There is rnat collection inside M2N. Need to adjust...
+ extra_nat_ptr += 1;
+ }
+
+ return *extra_nat_ptr;
+}
// Setup the stacked register for the current frame given bsp and ar.pfs (cfm for current frame)
static void si_setup_stacked_registers(StackIterator* si)
{
+ const uint64 ALL_ONES = ~0;
uint64 pfs = *si->c.p_ar_pfs;
unsigned sof = (unsigned)EXTRACT64_SOF(pfs);
uint64 nats_lo = si->c.nats_lo & 0xffffffff;
uint64 nats_hi = 0;
uint64* bsp = si->bsp;
- uint64 nats = (bsp<=si->last_legal_rsnat ? *(uint64*)((uint64)bsp|(uint64)0x1f8) : si->extra_nats);
+ uint64 nats = get_rnat(bsp);
+
unsigned index = (unsigned)(((uint64)bsp & (uint64)0x1f8) >> 3);
- uint64 mask = 1 << index;
+ uint64 mask = ((uint64)1) << index;
for(unsigned i=0; i<sof; i++) {
// Set the location of the stack register
@@ -119,12 +151,9 @@
mask <<= 1;
// If bsp is on a spilled rsnat recompute nats and mask
if (((uint64)bsp&(uint64)0x1f8) == (uint64)0x1f8) {
- if (bsp<=si->last_legal_rsnat)
- nats = *bsp;
- else
- nats = si->extra_nats;
bsp++;
mask = 1;
+ nats = get_rnat(bsp);
}
}
@@ -154,11 +183,12 @@
assert(M2N_SAVED_R7 < 64);
si->c.nats_lo = si->c.nats_lo & ~(uint64)0xf0 | (si->c.nats_lo >> (M2N_SAVED_R4-4)) & (uint64)0xf0;
- // IP, SP, PFS, preds, m2nfl
+ // IP, SP, PFS, preds, unat, m2nfl
si->c.p_eip = si->c.p_gr[M2N_SAVED_RETURN_ADDRESS];
si->c.sp = *si->c.p_gr[M2N_SAVED_SP];
si->c.p_ar_pfs = si->c.p_gr[M2N_SAVED_PFS];
si->c.preds = *si->c.p_gr[M2N_SAVED_PR];
+ si->c.ar_unat = *si->c.p_gr[M2N_SAVED_UNAT];
si->m2nfl = m2n_get_previous_frame(si->m2nfl);
}
@@ -167,18 +197,17 @@
{
uint64 pfs = *si->c.p_ar_pfs;
unsigned sol = (unsigned)EXTRACT64_SOL(pfs);
- assert(sol<=96); // ichebyki
- // ichebyki assert(sol<96);
- uint64* bsp = si->bsp;
- // Direct computation, see IPF arch manual, volume 3, table 6.2.
- uint64 b = (uint64)bsp;
- uint64 s = sol<<3;
+ assert(sol<=96);
- uint64 d2 = b-s;
- uint64 d3 = 62*8-(b&0x1f8)+s;
- if (d3>=63*8)
- if (d3>=126*8)
+ uint64 bsp = (uint64)si->bsp;
+ uint64 local_area_size = sol << 3;
+
+ // Direct computation, see IPF arch manual, volume 3, table 6.2.
+ uint64 d2 = bsp - local_area_size;
+ uint64 d3 = 62*8 - (bsp & 0x1f8) + local_area_size;
+ if (d3 >= 63*8)
+ if (d3 >= 126*8)
d2 -= 16;
else
d2 -= 8;
@@ -327,126 +356,27 @@
//////////////////////////////////////////////////////////////////////////
// Stack Iterator Interface
-StackIterator* si_create_from_native()
-{
- hythread_suspend_disable();
- // Allocate iterator
- StackIterator* res = (StackIterator*)STD_MALLOC(sizeof(StackIterator));
- assert(res);
-
- // Setup last_legal_rsnat and extra_nats
- uint64 t[2];
- get_rnat_and_bsp(t);
- si_init_nats(res, (uint64*)t[1], t[0]);
-
- // Setup current frame
- res->cci = NULL;
- res->m2nfl = m2n_get_last_frame();
- res->ip = 0;
- res->c.p_eip = &res->ip;
- hythread_suspend_enable();
- return res;
-}
-
-#if defined (PLATFORM_POSIX)
StackIterator* si_create_from_native(VM_thread* thread)
{
- hythread_suspend_disable();
// Allocate iterator
StackIterator* res = (StackIterator*)STD_MALLOC(sizeof(StackIterator));
assert(res);
- // Setup last_legal_rsnat and extra_nats
- uint64 t[2];
- get_rnat_and_bsp(t);
- si_init_nats(res, (uint64*)t[1], t[0]);
-
// Setup current frame
res->cci = NULL;
res->m2nfl = m2n_get_last_frame(thread);
res->ip = 0;
res->c.p_eip = &res->ip;
- hythread_suspend_enable();
return res;
+}
-#if 0
- // FIXME: code is outdated
- assert(0);
- abort();
-
- // Allocate iterator
- StackIterator* res = (StackIterator*)malloc(sizeof(StackIterator));
- assert(res);
-
- TRACE2("SIGNALLING", "stack iterator: create from native pthread_t " << ((pthread_t)GetCurrentThreadId()));
-
- if (thread == p_TLS_vmthread) {
- get_rnat_and_bspstore(thread->t);
- } else {
- assert(thread->suspend_request > 0);
-
- TRACE2("SIGNALLING", "thread state before " << thread << " " <<
- thread->t[0] << " " << thread->t[1] << " " << thread->suspended_state);
- //if (thread->suspended_state == NOT_SUSPENDED) {
- TRACE2("SIGNALLING", "sending SIGUSR2 to thread " << thread);
- assert(thread->thread_id != 0);
-
- if (sem_init(&thread->suspend_self, 0, 0) != 0) {
- DIE("sem_init() failed" << strerror(errno));
- }
-
- thread->t[0] = NOT_VALID;
- thread->t[1] = NOT_VALID;
-
- TRACE2("SIGNALLING", "BEFORE KILL thread = " << thread << " killing " << thread->thread_id);
-
- if (pthread_kill(thread->thread_id, SIGUSR2) != 0) {
- DIE("pthread_kill(" << thread->thread_id << ", SIGUSR2) failed :" << strerror(errno));
- }
-
- si_reload_registers();
-
- TRACE2("SIGNALLING", "BEFORE WAIT thread = " << thread);
-
- int ret;
- do {
- ret = sem_wait(&thread->suspend_self);
- TRACE2("SIGNALLING", "sem_wait " << (&thread->suspend_self) <<
- " exited, errno = " << errno);
- } while((ret != 0) && (errno == EINTR));
-
- TRACE2("SIGNALLING", "AFTER WAIT thread = " << thread);
-
- sem_destroy(&thread->suspend_self);
- assert(thread->suspended_state == SUSPENDED_IN_SIGNAL_HANDLER);
- thread->suspended_state = NOT_SUSPENDED;
- // assert(thread->t[0] != NOT_VALID);
- // assert(thread->t[1] != NOT_VALID);
- }
-
- TRACE2("SIGNALLING", "thread state after " << thread << " " << thread->t[0] << " " << thread->t[1] << " " << m2n_get_last_frame(thread));
-
- TRACE2("SIGNALLING", "stack iterator: create from native, rnat, bsp/bspstore " << thread->t[0] << " " << thread->t[1]);
-
- // Setup last_legal_rsnat and extra_nats
- uint64 rnat = thread->t[0];
- uint64* bsp = (uint64*)thread->t[1];
-
- si_init_nats(res, bsp, rnat);
-
- // Check that bsp covers everything
- assert((uint64)m2n_get_last_frame(thread)+(M2N_NUMBER_LOCALS+9)*8 <= (uint64)bsp);
-
- // Setup current frame
- res->cci = NULL;
- res->m2nfl = m2n_get_last_frame(thread);
- res->ip = 0;
- res->c.p_eip = &res->ip;
-
- return res;
-#endif
+StackIterator* si_create_from_native()
+{
+ return si_create_from_native(p_TLS_vmthread);
}
+/*
+#if defined (PLATFORM_POSIX)
#elif defined (PLATFORM_NT)
// Get the bspstore and rnat values of another thread from the OS.
@@ -488,6 +418,7 @@
#else
#error Stack iterator is not implemented for the given platform
#endif
+*/
// On IPF stack iterators must be created from threads (suspended) in native code.
// We do not support threads suspended in managed code yet.
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp Tue Jul 31 06:36:49 2007
@@ -72,7 +72,7 @@
emitter.ipf_mov(out_arg0+1, IN_REG1);
emitter.ipf_mov(out_arg0+2, 0);
emitter.ipf_mov(out_arg0+3, 0);
- emit_call_with_gp(emitter, (void **)exn_athrow, 5);
+ emit_call_with_gp(emitter, (void **)exn_athrow, true, 5);
} //gen_vm_rt_athrow_internal_compactor
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp Tue Jul 31 06:36:49 2007
@@ -222,7 +222,7 @@
emitter.ipf_mov(out_arg0 + arg, IN_REG0 + arg);
}
- emit_call_with_gp(emitter, func);
+ emit_call_with_gp(emitter, func, true);
// 20030512 If compressing references, translate a NULL result to a managed null (heap_base).
if (translate_returned_ref) {
@@ -320,7 +320,7 @@
emitter.ipf_mov(out0+0, IN_REG0);
emitter.ipf_mov(out0+1, IN_REG1);
emitter.ipf_adds(out0+2, (int)offset_gc_local, THREAD_PTR_REG);
- emit_call_with_gp(emitter, (void **)p_update_allocation_stats);
+ emit_call_with_gp(emitter, (void **)p_update_allocation_stats, false);
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
enforce_calling_conventions(&emitter);
#endif // VM_STATS
@@ -371,7 +371,7 @@
emitter.ipf_mov(out0+0, IN_REG0);
emitter.ipf_mov(out0+1, IN_REG1);
emitter.ipf_adds(out0+2, (int)offset_gc_local, THREAD_PTR_REG);
- emit_call_with_gp(emitter, fast_obj_alloc_proc);
+ emit_call_with_gp(emitter, fast_obj_alloc_proc, false);
// If the fast allocation procedure returned a non-NULL result then return, else fall through to the slow allocation path.
emitter.ipf_cmp(icmp_eq, cmp_none, SCRATCH_PRED_REG, SCRATCH_PRED_REG2, 0, RETURN_VALUE_REG);
@@ -387,7 +387,7 @@
emitter.ipf_mov(out_arg0+0, IN_REG0);
emitter.ipf_mov(out_arg0+1, IN_REG1);
emitter.ipf_adds(out_arg0+2, (int)offset_gc_local, THREAD_PTR_REG);
- emit_call_with_gp(emitter, slow_obj_alloc_proc);
+ emit_call_with_gp(emitter, slow_obj_alloc_proc, true);
// pop m2n frame and return
m2n_gen_pop_m2n(&emitter, false, MPR_Gr);
@@ -416,7 +416,7 @@
emitter.ipf_mov(out0+0, IN_REG0);
emitter.ipf_mov(out0+1, IN_REG1);
emitter.ipf_adds(out0+2, (int)offset_gc_local, THREAD_PTR_REG);
- emit_call_with_gp(emitter, (void **)p_vm_new_vector_update_stats);
+ emit_call_with_gp(emitter, (void **)p_vm_new_vector_update_stats, false);
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
enforce_calling_conventions(&emitter);
}
@@ -434,7 +434,7 @@
emitter.ipf_mov(out0, IN_REG0);
emitter.ipf_mov(out0+1, IN_REG1);
emitter.ipf_adds(out0+2, (int)offset_gc_local, THREAD_PTR_REG);
- emit_call_with_gp(emitter, fast_obj_alloc_proc);
+ emit_call_with_gp(emitter, fast_obj_alloc_proc, false);
// If the fast allocation procedure returned a non-NULL result then return, else fall through to the slow allocation path.
emitter.ipf_cmp(icmp_eq, cmp_none, SCRATCH_PRED_REG, SCRATCH_PRED_REG2, 0, RETURN_VALUE_REG);
@@ -449,7 +449,7 @@
emitter.ipf_mov(out_arg0+0, IN_REG0);
emitter.ipf_mov(out_arg0+1, IN_REG1);
emitter.ipf_adds(out_arg0+2, (int)offset_gc_local, THREAD_PTR_REG);
- emit_call_with_gp(emitter, slow_obj_alloc_proc);
+ emit_call_with_gp(emitter, slow_obj_alloc_proc, true);
// pop m2n frame and return
m2n_gen_pop_m2n(&emitter, false, MPR_Gr);
@@ -761,7 +761,7 @@
emitter.ipf_add(sc1, sc2, sc3);
emitter.ipf_ld(int_mem_size_8, mem_ld_none, mem_none, out0+0, sc1);
emitter.ipf_mov(out0+1, super_class);
- emit_call_with_gp(emitter, (void **)p_class_is_subtype);
+ emit_call_with_gp(emitter, (void **)p_class_is_subtype, false);
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
if (is_instanceof)
@@ -793,7 +793,7 @@
emitter.ipf_mov(out0+i, IN_REG0+i);
}
- emit_call_with_gp(emitter, function);
+ emit_call_with_gp(emitter, function, false);
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
enforce_calling_conventions(&emitter);
@@ -828,7 +828,7 @@
emitter.ipf_mov(out0+0, IN_REG0);
emitter.ipf_mov(out0+1, IN_REG1);
emitter.ipf_mov(out0+2, IN_REG2);
- emit_call_with_gp(emitter, (void **)p_vm_rt_aastore);
+ emit_call_with_gp(emitter, (void **)p_vm_rt_aastore, false);
// Restore pfs, b0, and gp
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
@@ -1105,7 +1105,7 @@
Boolean (*p_is_class_initialized)(Class *clss);
p_is_class_initialized = is_class_initialized;
- emit_call_with_gp(emitter, (void**)p_is_class_initialized);
+ emit_call_with_gp(emitter, (void**)p_is_class_initialized, false);
emitter.ipf_cmp(icmp_ne, cmp_none, SCRATCH_PRED_REG, SCRATCH_PRED_REG2, RETURN_VALUE_REG, SCRATCH_GENERAL_REG3);
emitter.ipf_brret(br_many, br_sptk, br_none, BRANCH_RETURN_LINK_REG, SCRATCH_PRED_REG);
@@ -1115,7 +1115,7 @@
emitter.ipf_mov(out_arg0+0, IN_REG0);
void (*p_class_initialize)(Class *clss);
p_class_initialize = vm_rt_class_initialize;
- emit_call_with_gp(emitter, (void **)p_class_initialize);
+ emit_call_with_gp(emitter, (void **)p_class_initialize, true);
// pop m2n frame and return
m2n_gen_pop_m2n(&emitter, false, MPR_None);
enforce_calling_conventions(&emitter);
@@ -1364,7 +1364,7 @@
// Call struct_Class_to_java_lang_Class() to convert the struct Class* argument to a java_lang_Class reference.
int out_arg0 = m2n_gen_push_m2n(&emitter, 0, FRAME_UNKNOWN, false, 0, 0, 1);
emitter.ipf_mov(out_arg0, IN_REG0);
- emit_call_with_gp(emitter, (void **)p_struct_Class_to_java_lang_Class);
+ emit_call_with_gp(emitter, (void **)p_struct_Class_to_java_lang_Class, true);
m2n_gen_pop_m2n(&emitter, false, MPR_Gr);
enforce_calling_conventions(&emitter);
@@ -1376,7 +1376,7 @@
// Call struct_Class_to_java_lang_Class() to convert the struct Class* argument to a java_lang_Class reference.
int out_arg0 = m2n_gen_push_m2n(&emitter, 0, FRAME_UNKNOWN, false, 0, 0, 1);
emitter.ipf_mov(out_arg0, IN_REG0);
- emit_call_with_gp(emitter, (void **)p_struct_Class_to_java_lang_Class);
+ emit_call_with_gp(emitter, (void **)p_struct_Class_to_java_lang_Class, true);
m2n_gen_pop_m2n(&emitter, false, MPR_Gr);
enforce_calling_conventions(&emitter);
@@ -1522,7 +1522,7 @@
out0, save_pfs, save_b0, save_gp);
emitter.ipf_mov(out0, IN_REG0);
- emit_call_with_gp(emitter, (void **)p_generic_hashcode);
+ emit_call_with_gp(emitter, (void **)p_generic_hashcode, false);
// Restore pfs, b0, and gp
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
@@ -1549,7 +1549,7 @@
emitter.ipf_mov(out0+3, IN_REG3);
emitter.ipf_mov(out0+4, IN_REG4);
- emit_call_with_gp(emitter, (void **)p_array_copy);
+ emit_call_with_gp(emitter, (void **)p_array_copy, false);
// Restore pfs, b0, and gp
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
@@ -1572,7 +1572,7 @@
(void **)func,
out0, save_pfs, save_b0, save_gp);
- emit_call_with_gp(emitter, (void **)func);
+ emit_call_with_gp(emitter, (void **)func, false);
// Restore pfs, b0, and gp
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
@@ -1647,7 +1647,7 @@
emitter.ipf_mov(out0+5, IN_REG4);
int (*func)(JNIEnv*, Java_java_io_FileInputStream*, int, Vector_Handle, int, int) = readinternal_override;
- emit_call_with_gp(emitter, (void **)func);
+ emit_call_with_gp(emitter, (void **)func, false);
// Restore pfs, b0, and gp
emitter.ipf_mov(GP_REG, save_gp);
@@ -2186,7 +2186,7 @@
emitter.ipf_adds(out0+0, first_element_offset, sc2);
emitter.ipf_adds(out0+1, first_element_offset, sc1);
emitter.ipf_add(out0+2, length, length);
- emit_call_with_gp(emitter, (void **)p_memmove);
+ emit_call_with_gp(emitter, (void **)p_memmove, false);
// Restore pfs, b0, and gp
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
@@ -2331,7 +2331,7 @@
{
emitter.ipf_mov(out0+i, IN_REG0+i);
}
- emit_call_with_gp(emitter, fptr);
+ emit_call_with_gp(emitter, fptr, false);
// Restore pfs, b0, and gp
emit_dealloc_for_single_call(emitter, save_pfs, save_b0, save_gp);
@@ -2530,7 +2530,7 @@
// Call increment_helper_count.
emit_movl_compactor(emitter, out0, (uint64)f);
- emit_call_with_gp(emitter, (void **)p_increment_helper_count);
+ emit_call_with_gp(emitter, (void **)p_increment_helper_count, false);
// Restore fp args
emitter.ipf_adds(SP_REG, 16, SP_REG);
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/stub_code_utils.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/stub_code_utils.cpp?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/stub_code_utils.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/stub_code_utils.cpp Tue Jul 31 06:36:49 2007
@@ -75,10 +75,11 @@
emitter.ipf_mtbr(BRANCH_RETURN_LINK_REG, save_b0_reg, pred);
}
-
+NativeCodePtr m2n_gen_flush_and_call();
void emit_call_with_gp(Merced_Code_Emitter& emitter,
void **proc_ptr,
+ bool flushrs,
int saved_gp_reg)
{
void *new_gp = proc_ptr[1];
@@ -94,7 +95,14 @@
uint64 branch_target = (uint64)(*proc_ptr);
- emitter.ipf_brl_call(br_many, br_sptk, br_none, BRANCH_RETURN_LINK_REG, branch_target);
+ emit_mov_imm_compactor(emitter, SCRATCH_GENERAL_REG, branch_target, 0);
+ if (flushrs) {
+ emitter.ipf_mtbr(BRANCH_CALL_REG, SCRATCH_GENERAL_REG);
+ emit_mov_imm_compactor(emitter, SCRATCH_GENERAL_REG, (uint64)m2n_gen_flush_and_call(), 0);
+ }
+ emitter.ipf_mtbr(SCRATCH_BRANCH_REG, SCRATCH_GENERAL_REG);
+ emitter.ipf_bricall(br_few, br_sptk, br_none, BRANCH_RETURN_LINK_REG, SCRATCH_BRANCH_REG);
+
// Restore the saved GP.
if (new_gp != vm_gp && saved_gp_reg != 0)
emitter.ipf_mov(GP_REG, saved_gp_reg);
@@ -102,7 +110,7 @@
void emit_branch_with_gp(Merced_Code_Emitter& emitter,
- void **proc_ptr)
+ void **proc_ptr)
{
void *new_gp = proc_ptr[1];
void *vm_gp = get_vm_gp_value();
@@ -115,7 +123,7 @@
uint64 branch_target = (uint64)(*proc_ptr);
- emit_movl_compactor(emitter, SCRATCH_GENERAL_REG, branch_target, 0);
+ emit_mov_imm_compactor(emitter, SCRATCH_GENERAL_REG, branch_target, 0);
emitter.ipf_mtbr(SCRATCH_BRANCH_REG, SCRATCH_GENERAL_REG);
emitter.ipf_bri(br_cond, br_few, br_sptk, br_none, SCRATCH_BRANCH_REG);
@@ -241,7 +249,7 @@
emit_movl_compactor(emitter, out0, (uint64) msg);
emitter.ipf_mov(out0+1, print_reg);
// call a helper function
- emit_call_with_gp(emitter, (void **) print_helper);
+ emit_call_with_gp(emitter, (void **) print_helper, false);
emitter.ipf_adds(SP_REG, 16, SP_REG);
// restore the scratch regs
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/Code_Emitter.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/Code_Emitter.h?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/Code_Emitter.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/Code_Emitter.h Tue Jul 31 06:36:49 2007
@@ -331,6 +331,10 @@
{ encoder->ipf_movl(dest, upper_32, lower_32, pred);
_gen_an_IR_1i_0(curr_bc_addr, ST_il, pred, dest/**/); }
+ void ipf_movi64 (unsigned dest, uint64 imm64, unsigned pred=0)
+ { encoder->ipf_movi64(dest, imm64, pred);
+ _gen_an_IR_1i_0(curr_bc_addr, ST_il, pred, dest/**/); }
+
void ipf_brl_call(Branch_Prefetch_Hint ph, Branch_Whether_Hint wh, Branch_Dealloc_Hint dh, unsigned b1, uint64 imm64, unsigned pred=0)
{
encoder->ipf_brl_call(ph, wh, dh, b1, imm64, pred);
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/stub_code_utils.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/stub_code_utils.h?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/stub_code_utils.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/stub_code_utils.h Tue Jul 31 06:36:49 2007
@@ -68,13 +68,14 @@
// If saved_gp_reg is not specified, then gp is neither saved nor restored.
void emit_call_with_gp(Merced_Code_Emitter& emitter,
void **proc_ptr,
+ bool flushrs,
int saved_gp_reg = 0);
// Emit a branch instruction. Before the branch, the gp is set to the
// value specified in the function pointer.
// This function is normally used to implement tail calls.
void emit_branch_with_gp(Merced_Code_Emitter& emitter,
- void **proc_ptr);
+ void **proc_ptr);
void emit_movl_compactor(Merced_Code_Emitter& emitter, unsigned dst_reg, uint64 u64_value, unsigned pred=0);
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/vm_ipf.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/vm_ipf.h?view=diff&rev=561327&r1=561326&r2=561327
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/vm_ipf.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/include/vm_ipf.h Tue Jul 31 06:36:49 2007
@@ -39,6 +39,7 @@
#define SCRATCH_PRED_REG9 14
#define SCRATCH_PRED_REG10 15
#define SCRATCH_BRANCH_REG 6
+#define SCRATCH_BRANCH_REG2 7
#define BRANCH_RETURN_LINK_REG 0
#define GP_REG 1
#define RETURN_VALUE_REG 8
@@ -60,12 +61,16 @@
#define SCRATCH_GENERAL_REG16 29
#define SCRATCH_GENERAL_REG17 30
#define SCRATCH_GENERAL_REG18 31
+#define PRESERV_GENERAL_REG1 5
+#define PRESERV_GENERAL_REG2 6
#define SP_REG 12
#define FIRST_PRES_FP_REG 16
#define LAST_PRES_FP_REG 31
#define FIRST_FP_ARG_REG 8
#define LAST_FP_ARG_REG 15
+// br2 is used for keeping function address to be called.
+#define BRANCH_CALL_REG SCRATCH_BRANCH_REG2
#define IN_REG0 32
#define IN_REG1 33