#define NEED_PTHREADS_QUASI_ATOMICS 1
#endif
-#elif defined(__sh__)
-#define NEED_PTHREADS_QUASI_ATOMICS 1
-
#else
#error "Unsupported atomic operations for this platform"
#endif
include $(LOCAL_PATH)/Dvm.mk
-LOCAL_SHARED_LIBRARIES += liblog libcutils libnativehelper libz libdl libcorkscrew
-
-ifeq ($(HAVE_SELINUX),true)
-LOCAL_C_INCLUDES += external/libselinux/include
-LOCAL_SHARED_LIBRARIES += libselinux
-LOCAL_CFLAGS += -DHAVE_SELINUX
-endif # HAVE_SELINUX
+LOCAL_SHARED_LIBRARIES += \
+ libcorkscrew \
+ libcutils \
+ libdl \
+ liblog \
+ libnativehelper \
+ libselinux \
+ libz
LOCAL_STATIC_LIBRARIES += libdex
snprintf(path, sizeof(path), "/proc/%d/task", getpid());
DIR* d = opendir(path);
- if (d) {
- dirent de;
- dirent* result;
+ if (d != NULL) {
+ dirent* entry = NULL;
bool first = true;
- while (!readdir_r(d, &de, &result) && result) {
+ while ((entry = readdir(d)) != NULL) {
char* end;
- pid_t tid = strtol(de.d_name, &end, 10);
+ pid_t tid = strtol(entry->d_name, &end, 10);
if (!*end && !isDalvikThread(tid)) {
if (first) {
dvmPrintDebugMessage(target, "NATIVE THREADS:\n");
OpKind firstOp = kOpBkpt;
OpKind secondOp = kOpBkpt;
bool callOut = false;
+ bool checkZero = false;
void *callTgt;
switch (mir->dalvikInsn.opcode) {
case OP_DIV_LONG:
case OP_DIV_LONG_2ADDR:
callOut = true;
+ checkZero = true;
callTgt = (void*)__divdi3;
break;
case OP_REM_LONG:
case OP_REM_LONG_2ADDR:
callOut = true;
callTgt = (void*)__moddi3;
+ checkZero = true;
break;
case OP_AND_LONG_2ADDR:
case OP_AND_LONG:
genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
} else {
dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
+ loadValueDirectWideFixed(cUnit, rlSrc2, r_ARG2, r_ARG3);
loadValueDirectWideFixed(cUnit, rlSrc1, r_ARG0, r_ARG1);
LOAD_FUNC_ADDR(cUnit, r_T9, (int) callTgt);
- loadValueDirectWideFixed(cUnit, rlSrc2, r_ARG2, r_ARG3);
+ if (checkZero) {
+ int tReg = r_T1; // Using fixed registers during call sequence
+ opRegRegReg(cUnit, kOpOr, tReg, r_ARG2, r_ARG3);
+ genRegImmCheck(cUnit, kMipsCondEq, tReg, 0, mir->offset, NULL);
+ }
opReg(cUnit, kOpBlx, r_T9);
newLIR3(cUnit, kMipsLw, r_GP, STACK_OFFSET_GP, r_SP);
dvmCompilerClobberCallRegs(cUnit);
s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
{
const int kInstrLen = 3;
- u2 size;
- s4 firstKey;
- const s4* entries;
/*
* Packed switch data format:
return kInstrLen;
}
- size = *switchData++;
+ u2 size = *switchData++;
assert(size > 0);
- firstKey = *switchData++;
+ s4 firstKey = *switchData++;
firstKey |= (*switchData++) << 16;
- if (testVal < firstKey || testVal >= firstKey + size) {
+ int index = testVal - firstKey;
+ if (index < 0 || index >= size) {
LOGVV("Value %d not found in switch (%d-%d)",
testVal, firstKey, firstKey+size-1);
return kInstrLen;
/* The entries are guaranteed to be aligned on a 32-bit boundary;
* we can treat them as a native int array.
*/
- entries = (const s4*) switchData;
+ const s4* entries = (const s4*) switchData;
assert(((u4)entries & 0x3) == 0);
- assert(testVal - firstKey >= 0 && testVal - firstKey < size);
+ assert(index >= 0 && index < size);
LOGVV("Value %d found in slot %d (goto 0x%02x)",
- testVal, testVal - firstKey,
- s4FromSwitchData(&entries[testVal - firstKey]));
- return s4FromSwitchData(&entries[testVal - firstKey]);
+ testVal, index,
+ s4FromSwitchData(&entries[index]));
+ return s4FromSwitchData(&entries[index]);
}
/*
+++ /dev/null
-%verify "executed"
-/*
- * Unlike other alt stubs, we don't want to call dvmCheckBefore() here.
- * Instead, just treat this as a trampoline to reach the real alt
- * handler (which will do the dvmCheckBefore() call.
- */
- mov ip, rINST, lsr #8 @ ip<- extended opcode
- add ip, ip, #256 @ add offset for extended opcodes
- GOTO_OPCODE(ip) @ go to proper extended handler
-
+++ /dev/null
-%verify "executed"
-%verify "null object"
-%verify "class cast exception thrown, with correct class name"
-%verify "class cast exception not thrown on same class"
-%verify "class cast exception not thrown on subclass"
-%verify "class not resolved"
-%verify "class already resolved"
- /*
- * Check to see if a cast from one class to another is allowed.
- */
- /* check-cast/ jumbo vBBBB, class #AAAAAAAA */
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- FETCH(a3, 3) # a3<- BBBB
- sll a2,a2,16
- or a2, a0, a2 # a2<- AAAAaaaa
-
- GET_VREG(rOBJ, a3) # rOBJ<- object
- LOAD_rSELF_methodClassDex(a0) # a0<- pDvmDex
- LOAD_base_offDvmDex_pResClasses(a0, a0) # a0<- pDvmDex->pResClasses
- # is object null?
- beqz rOBJ, .L${opcode}_okay # null obj, cast always succeeds
- LOAD_eas2(a1, a0, a2) # a1<- resolved class
- LOAD_base_offObject_clazz(a0, rOBJ) # a0<- obj->clazz
- # have we resolved this before?
- beqz a1, .L${opcode}_resolve # not resolved, do it now
-.L${opcode}_resolved:
- # same class (trivial success)?
- bne a0, a1, .L${opcode}_fullcheck # no, do full check
- b .L${opcode}_okay # yes, finish up
-
- /*
- * Trivial test failed, need to perform full check. This is common.
- * a0 holds obj->clazz
- * a1 holds class resolved from BBBB
- * rOBJ holds object
- */
-.L${opcode}_fullcheck:
- move rBIX,a1 # avoid ClassObject getting clobbered
- JAL(dvmInstanceofNonTrivial) # v0<- boolean result
- # failed?
- bnez v0, .L${opcode}_okay # no, success
- b .L${opcode}_castfailure
-
-%break
-
-
-.L${opcode}_castfailure:
- # A cast has failed. We need to throw a ClassCastException with the
- # class of the object that failed to be cast.
- EXPORT_PC() # about to throw
- LOAD_base_offObject_clazz(a0, rOBJ) # a0<- obj->clazz
- move a1,rBIX # r1<- desired class
- JAL(dvmThrowClassCastException)
- b common_exceptionThrown
-
- /*
- * Advance PC and get next opcode
- *
- */
-.L${opcode}_okay:
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
- /*
- * Resolution required. This is the least-likely path.
- *
- * a2 holds AAAAAAAA
- * rOBJ holds object
- */
-.L${opcode}_resolve:
- EXPORT_PC() # resolve() could throw
- LOAD_rSELF_method(a3) # a3<- self->method
- move a1, a2 # a1<- AAAAAAAA
- li a2, 0 # a2<- false
- LOAD_base_offMethod_clazz(a0, a3) # a0<- method->clazz
- JAL(dvmResolveClass) # v0<- resolved ClassObject ptr
- # got null?
- beqz v0, common_exceptionThrown # yes, handle exception
- move a1, v0 # a1<- class resolved from AAAAAAAA
- LOAD_base_offObject_clazz(a0, rOBJ) # a0<- obj->clazz
- b .L${opcode}_resolved # pick up where we left off
-
-
+++ /dev/null
-%verify "executed"
-%verify "Class already resolved"
-%verify "Class not yet resolved"
-%verify "Class cannot be resolved"
- /* const-class/jumbo vBBBB, Class@AAAAAAAA */
- FETCH(a0, 1) # a0<- aaaa (lo)
- LOAD_rSELF_methodClassDex(a2) # a2 <- self->methodClassDex
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResClasses(a2, a2) # a2 <- dvmDex->pResClasses
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- FETCH(rOBJ, 3) # rOBJ<- BBBB
- LOAD_eas2(v0, a2, a1) # v0 <- pResClasses[BBBB]
-
- bnez v0, .L${opcode}_resolve # v0!=0 => resolved-ok
- /*
- * Continuation if the Class has not yet been resolved.
- * a1: AAAAAAAA (Class ref)
- * rOBJ: target register
- */
- EXPORT_PC()
- LOAD_rSELF_method(a0) # a0 <- self->method
- li a2, 1 # a2 <- true
- LOAD_base_offMethod_clazz(a0, a0) # a0 <- method->clazz
- JAL(dvmResolveClass) # v0 <- Class reference
- # failed==0?
- beqz v0, common_exceptionThrown # yup, handle the exception
-
-.L${opcode}_resolve:
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(v0, rOBJ, t0) # vBBBB <- v0
-
-
+++ /dev/null
-%verify "executed"
- srl t0, rINST, 8 # t0<- extended opcode
- addu t0, t0, 256 # add offset for extended opcodes
- GOTO_OPCODE(t0) # go to proper extended handler
+++ /dev/null
-%default { "isrange":"0" }
-%verify "executed"
-%verify "unimplemented array type"
- /*
- * Create a new array with elements filled from registers.
- *
- * TODO: convert most of this into a common subroutine, shared with
- * OP_FILLED_NEW_ARRAY.S.
- */
- /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
-
- LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
- FETCH(a0, 1) # r0<- aaaa (lo)
- FETCH(a1, 2) # r1<- AAAA (hi)
- LOAD_base_offDvmDex_pResClasses(a3, a3) # a3 <- pDvmDex->pResClasses
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- LOAD_eas2(a0, a3, a1) # a0 <- resolved class
- GET_OPA(rOBJ) # rOBJ <- AA or BA
- EXPORT_PC() # need for resolve and alloc
- # already resolved?
- bnez a0, .L${opcode}_continue # yes, continue on
- LOAD_rSELF_method(a3) # a3 <- self->method
- li a2, 0 # a2 <- false
- LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
- JAL(dvmResolveClass) # v0 <- call(clazz, ref)
- move a0, v0
- # got null?
- beqz v0, common_exceptionThrown # yes, handle exception
- b .L${opcode}_continue
-%break
-
- /*
- * On entry:
- * a0 holds array class
- * rOBJ holds AA or BA
- */
-.L${opcode}_continue:
- LOAD_base_offClassObject_descriptor(a3, a0) # a3 <- arrayClass->descriptor
- li a2, ALLOC_DONT_TRACK # a2 <- alloc flags
- lbu rINST, 1(a3) # rINST <- descriptor[1]
- FETCH(a1, 3) # a1<- BBBB (length)
- seq t0, rINST, 'I' # array of ints?
- seq t1, rINST, 'L' # array of objects?
- or t0, t1
- seq t1, rINST, '[' # array of arrays?
- or t0, t1
- move rBIX, a1 # save length in rBIX
- beqz t0, .L${opcode}_notimpl # no, not handled yet
- JAL(dvmAllocArrayByClass) # v0 <- call(arClass, length, flags)
- # null return?
- beqz v0, common_exceptionThrown # alloc failed, handle exception
-
- FETCH(a1, 4) # a1 CCCC
- sw v0, offThread_retval(rSELF) # retval.l <- new array
- sw rINST, (offThread_retval+4)(rSELF) # retval.h <- type
- addu a0, v0, offArrayObject_contents # a0 <- newArray->contents
- subu rBIX, rBIX, 1 # length--, check for neg
- FETCH_ADVANCE_INST(5) # advance to next instr, load rINST
- bltz rBIX, 2f # was zero, bail
-
- # copy values from registers into the array
- # a0=array, a1=CCCC, t0=BBBB(length)
- move t0, rBIX
- EAS2(a2, rFP, a1) # a2 <- &fp[CCCC]
-1:
- lw a3, 0(a2) # a3 <- *a2++
- addu a2, 4
- subu t0, t0, 1 # count--
- sw a3, (a0) # *contents++ = vX
- addu a0, 4
- bgez t0, 1b
-
-2:
- lw a0, offThread_retval(rSELF) # a0 <- object
- lw a1, (offThread_retval+4)(rSELF) # a1 <- type
- seq t1, a1, 'I' # Is int array?
- bnez t1, 3f
- lw a2, offThread_cardTable(rSELF) # a2 <- card table base
- srl t3, a0, GC_CARD_SHIFT
- addu t2, a2, t3
- sb a2, (t2)
-3:
- GET_INST_OPCODE(t0) # ip <- opcode from rINST
- GOTO_OPCODE(t0) # execute it
-
-
- /*
- * Throw an exception indicating that we have not implemented this
- * mode of filled-new-array.
- */
-.L${opcode}_notimpl:
- la a0, .LstrFilledNewArrayNotImpl
- JAL(dvmThrowInternalError)
- b common_exceptionThrown
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%verify "negative value is sign-extended"
-%include "mips/OP_IGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%verify "large values are not sign-extended"
-%include "mips/OP_IGET_JUMBO.S"
+++ /dev/null
-%default { "load":"lw", "barrier":" # noop", "sqnum":"0" }
-%verify "executed"
-%verify "null object"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 32-bit instance field get.
- *
- * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
- * iget-char/jumbo, iget-short/jumbo
- */
- /* exop vBBBB, vCCCC, field@AAAAAAAA */
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- FETCH(a0, 4) # a0<- CCCC
- LOAD_rSELF_methodClassDex(a3) # a3 <- DvmDex
- sll a2,a2,16
- or a1, a1, a2 # a1<- AAAAaaaa
- LOAD_base_offDvmDex_pResFields(a2, a3) # a2 <- pDvmDex->pResFields
- GET_VREG(rOBJ, a0) # rOBJ <- fp[B], the object pointer
- LOAD_eas2(a0, a2, a1) # a0 <- resolved InstField ptr
- # is resolved entry null?
- bnez a0, .L${opcode}_finish # no, already resolved
- LOAD_rSELF_method(a2) # a2 <- current method
- EXPORT_PC() # resolve() could throw
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveInstField) # v0 <- resolved InstField ptr
- b .L${opcode}_resolved # resolved, continue
-
-%break
-
-.L${opcode}_resolved:
- # test results
- move a0, v0
- beqz a0,common_exceptionThrown
- /*
- * Currently:
- * v0 holds resolved field
- * rOBJ holds object (caller saved)
- */
-.L${opcode}_finish:
- #BAL(common_squeak${sqnum})
- LOAD_base_offInstField_byteOffset(a3, a0) # a3 <- byte offset of field
- # check object for null
- beqz rOBJ, common_errNullObject # object was null
- addu a3, a3, rOBJ # form address
- $load a0, (a3) # a0 <- obj.field (8/16/32 bits)
- $barrier # acquiring load
- FETCH(a2, 3) # a2<- BBBB
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- SET_VREG(a0, a2) # fp[BBBB]<- a0
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
-
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IGET_OBJECT_JUMBO.S" {"barrier":"SMP_DMB"}
+++ /dev/null
-%verify "executed"
-%verify "negative value is sign-extended"
-%include "mips/OP_IGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IGET_JUMBO.S" {"barrier":"SMP_DMB"}
+++ /dev/null
-%default {"volatile":"0"}
-%verify "executed"
-%verify "null object"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 64-bit instance field get.
- */
- /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- FETCH(a0, 4) # a0<- CCCC
- LOAD_rSELF_methodClassDex(a3) # a3 <- DvmDex
- sll a2,a2,16
- or a1, a1, a2 # a1<- AAAAaaaa
- LOAD_base_offDvmDex_pResFields(a2, a3) # a2 <- pResFields
- GET_VREG(rOBJ, a0) # rOBJ <- fp[CCCC], the object pointer
- LOAD_eas2(a0, a2, a1) # a0 <- resolved InstField ptr
- # is resolved entry null?
- bnez a0, .L${opcode}_finish # no, already resolved
- LOAD_rSELF_method(a2) # a2 <- current method
- EXPORT_PC() # resolve() could throw
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveInstField) # v0 <- resolved InstField ptr
- b .L${opcode}_resolved # resolved, continue
-
-%break
-
-.L${opcode}_resolved:
- # test return code
- move a0, v0
- bnez v0, .L${opcode}_finish
- b common_exceptionThrown
-
- /*
- * Currently:
- * a0 holds resolved field
- * rOBJ holds object
- */
-.L${opcode}_finish:
- LOAD_base_offInstField_byteOffset(a3, a0) # a3 <- byte offset of field
- beqz rOBJ, common_errNullObject # object was null
- GET_OPA4(a2) # a2 <- A+
- addu rOBJ, rOBJ, a3 # form address
- .if $volatile
- vLOAD64(a0, a1, rOBJ) # a0/a1 <- obj.field (64-bit align ok)
- .else
- LOAD64(a0, a1, rOBJ) # a0/a1 <- obj.field (64-bit align ok)
- .endif
- FETCH(a2, 3) # r2<- BBBB
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- EAS2(a3, rFP, a2) # a3 <- &fp[BBBB]
- GET_INST_OPCODE(t0) # extract opcode from rINST
- STORE64(a0, a1, a3) # fp[BBBB] <- a0/a1
- GOTO_OPCODE(t0) # jump to next instruction
-
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IGET_WIDE_JUMBO.S" {"volatile":"1"}
+++ /dev/null
-%verify "executed"
-%verify "null object"
-%verify "class cast exception thrown, with correct class name"
-%verify "class cast exception not thrown on same class"
-%verify "class cast exception not thrown on subclass"
-%verify "class not resolved"
-%verify "class already resolved"
- /*
- * Check to see if an object reference is an instance of a class.
- *
- * Most common situation is a non-null object, being compared against
- * an already-resolved class.
- *
- * TODO: convert most of this into a common subroutine, shared with
- * OP_INSTANCE_OF.S.
- */
- /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
- FETCH(a3, 4) # a3<- vCCCC
- FETCH(rOBJ, 3) # rOBJ<- vBBBB
- GET_VREG(a0, a3) # a0 <- vCCCC (object)
- LOAD_rSELF_methodClassDex(a2) # a2 <- pDvmDex
- # is object null?
- beqz a0, .L${opcode}_store # null obj, not an instance, store a0
- FETCH(a1, 1) # r1<- aaaa (lo)
- FETCH(a3, 2) # r3<- AAAA (hi)
- LOAD_base_offDvmDex_pResClasses(a2, a2) # a2 <- pDvmDex->pResClasses
- sll a3,a3,16
- or a3, a1, a3 # a3<- AAAAaaaa
-
- LOAD_eas2(a1, a2, a3) # a1 <- resolved class
- LOAD_base_offObject_clazz(a0, a0) # a0 <- obj->clazz
- # have we resolved this before?
- beqz a1, .L${opcode}_resolve # not resolved, do it now
- b .L${opcode}_resolved # resolved, continue
-
-%break
-
- /*
- * Class resolved, determine type of check necessary. This is common.
- * r0 holds obj->clazz
- * r1 holds class resolved from AAAAAAAA
- * r9 holds BBBB
- */
-
-.L${opcode}_resolved: # a0=obj->clazz, a1=resolved class
- # same class (trivial success)?
- beq a0, a1, .L${opcode}_trivial # yes, trivial finish
- # fall through to ${opcode}_fullcheck
-
- /*
- * Trivial test failed, need to perform full check. This is common.
- * a0 holds obj->clazz
- * a1 holds class resolved from AAAAAAAA
- * rOBJ holds BBBB
- */
-.L${opcode}_fullcheck:
- JAL(dvmInstanceofNonTrivial) # v0 <- boolean result
- move a0, v0
- b .L${opcode}_store # go to ${opcode}_store
-
-.L${opcode}_trivial:
- li a0, 1 # indicate success
- # fall thru
- /*
- * a0 holds boolean result
- * rOBJ holds BBBB
- */
-.L${opcode}_store:
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- SET_VREG(a0, rOBJ) # vBBBB <- a0
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
-
- /*
- * Resolution required. This is the least-likely path.
- *
- * a3 holds AAAAAAAA
- * rOBJ holds BBBB
- */
-.L${opcode}_resolve:
- EXPORT_PC() # resolve() could throw
- LOAD_rSELF_method(a0) # a0 <- self->method
- move a1, a3 # a1 <- AAAAAAAA
- li a2, 1 # a2 <- true
- LOAD_base_offMethod_clazz(a0, a0) # a0 <- method->clazz
- JAL(dvmResolveClass) # v0 <- resolved ClassObject ptr
- # got null?
- move a1, v0 # a1 <- class resolved from BBB
- beqz v0, common_exceptionThrown # yes, handle exception
- FETCH(ra, 4) # a3<- vCCCC
- move a1, a0 # a1<- class resolved from AAAAAAAA
-
- GET_VREG(a0, a3) # a0 <- vCCCC (object)
- LOAD_base_offObject_clazz(a0, a0) # a0 <- obj->clazz
- b .L${opcode}_resolved # pick up where we left off
-
+++ /dev/null
-%default { "isrange":"0", "routine":"NoRange" }
-%verify "executed"
-%verify "unknown method"
- /*
- * Handle a direct method call.
- *
- * (We could defer the "is 'this' pointer null" test to the common
- * method invocation code, and use a flag to indicate that static
- * calls don't count. If we do this as part of copying the arguments
- * out we could avoiding loading the first arg twice.)
- *
- */
- /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResMethods(a3, a3) # a3 <- pDvmDex->pResMethods
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- FETCH(rBIX, 4) # rBIX <- GFED or CCCC
- LOAD_eas2(a0, a3, a1) # a0 <- resolved methodToCall
- .if (!$isrange)
- and rBIX, rBIX, 15 # rBIX <- D (or stays CCCC)
- .endif
- EXPORT_PC() # must export for invoke
- GET_VREG(rOBJ, rBIX) # rOBJ <- "this" ptr
- # already resolved?
- bnez a0, 1f # resolved, call the function
-
- lw a3, offThread_method(rSELF) # a3 <- self->method
- LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
- li a2, METHOD_DIRECT # resolver method type
- JAL(dvmResolveMethod) # v0 <- call(clazz, ref, flags)
- move a0, v0
- # got null?
- beqz v0, common_exceptionThrown # yes, handle exception
-
-1:
- bnez rOBJ, common_invokeMethodJumbo # a0=method, rOBJ="this"
- b common_errNullObject # yes, throw exception
-
-
-
+++ /dev/null
-%default { "isrange":"0", "routine":"NoRange" }
-%verify "executed"
-%verify "unknown method"
-%verify "null object"
- /*
- * Handle an interface method call.
- */
- /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
- FETCH(a2, 4) # a2<- CCCC
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- EXPORT_PC() # must export for invoke
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- GET_VREG(rOBJ, a2) # rOBJ <- first arg ("this")
- LOAD_rSELF_methodClassDex(a3) # a3 <- methodClassDex
- LOAD_rSELF_method(a2) # a2 <- method
- # null obj?
- beqz rOBJ, common_errNullObject # yes, fail
- LOAD_base_offObject_clazz(a0, rOBJ) # a0 <- thisPtr->clazz
- JAL(dvmFindInterfaceMethodInCache) # v0 <- call(class, ref, method, dex)
- move a0, v0
- # failed?
- beqz v0, common_exceptionThrown # yes, handle exception
- b common_invokeMethodJumbo # (a0=method, rOBJ="this")
+++ /dev/null
-%verify "executed"
-%include "mips/OP_INVOKE_OBJECT_INIT_RANGE.S" {"jumbo":"1", "cccc":"4"}
*/
.L${opcode}_debugger:
lw a1, offThread_mainHandlerTable(rSELF)
- .if $jumbo
- li t0, OP_INVOKE_DIRECT_JUMBO
- .else
li t0, OP_INVOKE_DIRECT_RANGE
- .endif
GOTO_OPCODE_BASE(a1, t0) # execute it
+++ /dev/null
-%verify "executed"
-%verify "unknown method"
- /*
- * Handle a static method call.
- */
- /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResMethods(a3, a3) # a3 <- pDvmDex->pResMethods
- sll a1,a1,16
- or a1, a0, a1 # r1<- AAAAaaaa
- li rOBJ, 0 # null "this" in delay slot
- LOAD_eas2(a0, a3, a1) # a0 <- resolved methodToCall
-#if defined(WITH_JIT)
- EAS2(rBIX, a3, a1) # rBIX<- &resolved_metherToCall
-#endif
- EXPORT_PC() # must export for invoke
- # already resolved?
- bnez a0, common_invokeMethodJumboNoThis # (a0 = method)
- b .L${opcode}_resolve
-%break
-
-.L${opcode}_resolve:
- LOAD_rSELF_method(a3) # a3 <- self->method
- LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
- li a2, METHOD_STATIC # resolver method type
- JAL(dvmResolveMethod) # v0 <- call(clazz, ref, flags)
- move a0, v0
-#if defined(WITH_JIT)
- /*
- * Check to see if we're actively building a trace. If so,
- * we need to keep this instruction out of it.
- * rBIX: &resolved_methodToCall
- */
- lhu a2, offThread_subMode(rSELF)
- beqz v0, common_exceptionThrown # null, handle exception
- and a2, kSubModeJitTraceBuild # trace under construction?
- beqz a2, common_invokeMethodJumboNoThis # no, (a0=method, rOBJ="this")
- lw a1, 0(rBIX) # reload resolved method
- # finished resloving?
- bnez a1, common_invokeMethodJumboNoThis # yes, (a0=method, rOBJ="this")
- move rBIX, a0 # preserve method
- move a0, rSELF
- move a1, rPC
- JAL(dvmJitEndTraceSelect) # (self, pc)
- move a0, rBIX
- b common_invokeMethodJumboNoThis # whew, finally!
-#else
- # got null?
- bnez v0, common_invokeMethodJumboNoThis # (a0=method, rOBJ="this")
- b common_exceptionThrown # yes, handle exception
-#endif
+++ /dev/null
-%verify "executed"
-%verify "unknown method"
- /*
- * Handle a "super" method call.
- */
- /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
- FETCH(t0, 4) # t0<- CCCC
- LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResMethods(a3, a3) # a3 <- pDvmDex->pResMethods
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- GET_VREG(rOBJ, t0) # rOBJ <- "this" ptr
- LOAD_eas2(a0, a3, a1) # a0 <- resolved baseMethod
- # null "this"?
- LOAD_rSELF_method(t1) # t1 <- current method
- beqz rOBJ, common_errNullObject # null "this", throw exception
- # cmp a0, 0; already resolved?
- LOAD_base_offMethod_clazz(rBIX, t1) # rBIX <- method->clazz
- EXPORT_PC() # must export for invoke
- bnez a0, .L${opcode}_continue # resolved, continue on
-
- move a0, rBIX # a0 <- method->clazz
- li a2, METHOD_VIRTUAL # resolver method type
- JAL(dvmResolveMethod) # v0 <- call(clazz, ref, flags)
- move a0, v0
- # got null?
- beqz v0, common_exceptionThrown # yes, handle exception
- b .L${opcode}_continue
-%break
-
- /*
- * At this point:
- * a0 = resolved base method
- * rBIX = method->clazz
- */
-.L${opcode}_continue:
- LOAD_base_offClassObject_super(a1, rBIX) # a1 <- method->clazz->super
- LOADu2_offMethod_methodIndex(a2, a0) # a2 <- baseMethod->methodIndex
- LOAD_base_offClassObject_vtableCount(a3, a1) # a3 <- super->vtableCount
- EXPORT_PC() # must export for invoke
- # compare (methodIndex, vtableCount)
- bgeu a2, a3, .L${opcode}_nsm # method not present in superclass
- LOAD_base_offClassObject_vtable(a1, a1) # a1 <- ...clazz->super->vtable
- LOAD_eas2(a0, a1, a2) # a0 <- vtable[methodIndex]
- b common_invokeMethodJumbo # a0=method rOBJ="this"
-
- /*
- * Throw a NoSuchMethodError with the method name as the message.
- * a0 = resolved base method
- */
-.L${opcode}_nsm:
- LOAD_base_offMethod_name(a1, a0) # a1 <- method name
- b common_errNoSuchMethod
-
+++ /dev/null
-%verify "executed"
-%verify "unknown method"
-%verify "null object"
- /*
- * Handle a virtual method call.
- */
- /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResMethods(a3, a3) # a3 <- pDvmDex->pResMethods
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- LOAD_eas2(a0, a3, a1) # a0 <- resolved baseMethod
- EXPORT_PC() # must export for invoke
- # already resolved?
- bnez a0, .L${opcode}_continue # yes, continue on
-
- LOAD_rSELF_method(a3) # a3 <- self->method
- LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
- li a2, METHOD_VIRTUAL # resolver method type
- JAL(dvmResolveMethod) # v0 <- call(clazz, ref, flags)
- move a0, v0
- # got null?
- bnez v0, .L${opcode}_continue # no, continue
- b common_exceptionThrown # yes, handle exception
-%break
-
- /*
- * At this point:
- * a0 = resolved base method
- * rBIX= C or CCCC (index of first arg, which is the "this" ptr)
- */
-.L${opcode}_continue:
- FETCH(rBIX,4) # rBIX <- CCCC
- GET_VREG(rOBJ, rBIX) # rOBJ <- "this" ptr
- LOADu2_offMethod_methodIndex(a2, a0) # a2 <- baseMethod->methodIndex
- # is "this" null?
- beqz rOBJ, common_errNullObject # null "this", throw exception
- LOAD_base_offObject_clazz(a3, rOBJ) # a3 <- thisPtr->clazz
- LOAD_base_offClassObject_vtable(a3, a3) # a3 <- thisPtr->clazz->vtable
- LOAD_eas2(a0, a3, a2) # a0 <- vtable[methodIndex]
- b common_invokeMethodJumbo # (a0=method, rOBJ="this")
-
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_JUMBO.S"
+++ /dev/null
-%default { "store":"sw","postbarrier":"# noop ", "prebarrier":" # noop", "sqnum":"0" }
-%verify "executed"
-%verify "null object"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 32-bit instance field put.
- *
- * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
- * iput-short/jumbo
- */
- /* exop vBBBB, vCCCC, field@AAAAAAAA */
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- FETCH(a0, 4) # a0<- CCCC
- LOAD_rSELF_methodClassDex(a3) # a3 <- DvmDex
- sll a2,a2,16
- or a1, a1, a2 # a1<- AAAAaaaa
- LOAD_base_offDvmDex_pResFields(a2, a3) # a2 <- pDvmDex->pResFields
- GET_VREG(rOBJ, a0) # rOBJ <- fp[B], the object pointer
- LOAD_eas2(a0, a2, a1) # a0 <- resolved InstField ptr
- # is resolved entry null?
- bnez a0, .L${opcode}_finish # no, already resolved
- LOAD_rSELF_method(a2) # a2 <- current method
- EXPORT_PC() # resolve() could throw
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveInstField) # v0 <- resolved InstField ptr
- b .L${opcode}_resolved # resolved, continue
-
-%break
-
-.L${opcode}_resolved:
- move a0, v0
- beqz a0, common_exceptionThrown
- # fall through to ${opcode}_finish
-
-
- /*
- * Currently:
- * a0 holds resolved field
- * rOBJ holds object
- */
-.L${opcode}_finish:
- #BAL(common_squeak${sqnum})
- LOAD_base_offInstField_byteOffset(a3, a0) # a3 <- byte offset of field
- FETCH(a1, 3) # a1<- BBBB
- GET_VREG(a0, a1) # a0 <- fp[BBBB]
- # check object for null
- beqz rOBJ, common_errNullObject # object was null
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- addu rOBJ, rOBJ, a3 # form address
- $prebarrier # releasing store
- $store a0, (rOBJ) # obj.field (8/16/32 bits) <- a0
- $postbarrier
- GOTO_OPCODE(t0) # jump to next instruction
-
+++ /dev/null
-%default { "store":"sw", "postbarrier":" # noop", "prebarrier":" # noop", "sqnum":"0" }
-%verify "executed"
-%verify "null object"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 32-bit instance field put.
- */
- /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- FETCH(a0, 4) # a0<- CCCC
- LOAD_rSELF_methodClassDex(a3) # a3 <- DvmDex
- sll a1,a1,16
- or a1, a1, a2 # a1<- AAAAaaaa
- LOAD_base_offDvmDex_pResFields(a2, a3) # a2 <- pDvmDex->pResFields
- GET_VREG(rOBJ, a0) # rOBJ <- fp[B], the object pointer
- LOAD_eas2(a0, a2, a1) # a0 <- resolved InstField ptr
- # is resolved entry null?
- bnez a0, .L${opcode}_finish # no, already resolved
- LOAD_rSELF_method(a2) # a2 <- current method
- EXPORT_PC() # resolve() could throw
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveInstField) # v0 <- resolved InstField ptr
- b .L${opcode}_resolved
-
-%break
-
- /*
- * Currently:
- * a0 holds resolved field
- * rOBJ holds object
- */
-.L${opcode}_resolved:
- move a0, v0
- beqz a0, common_exceptionThrown
- # fall through to ${opcode}_finish
-
-.L${opcode}_finish:
- #BAL(common_squeak${sqnum})
- LOAD_base_offInstField_byteOffset(a3, a0) # a3 <- byte offset of field
- FETCH(a1, 3) # a1<- BBBB
- GET_VREG(a0, a1) # a0 <- fp[BBBB]
- lw a2, offThread_cardTable(rSELF) # a2 <- card table base
- # check object for null
- beqz rOBJ, common_errNullObject # object was null
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- addu t2, rOBJ, a3 # form address
- $prebarrier # releasing store
- $store a0, (t2) # obj.field (32 bits) <- a0
- $postbarrier
- beqz a0, 1f # stored a null reference?
- srl t1, rOBJ, GC_CARD_SHIFT
- addu t2, a2, t1
- sb a2, (t2) # mark card if not
-1:
- GOTO_OPCODE(t0) # jump to next instruction
-
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_OBJECT_JUMBO.S" {"prebarrier":"SMP_DMB_ST", "postbarrier":"SMP_DMB"}
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_JUMBO.S" {"prebarrier":"SMP_DMB_ST", "postbarrier":"SMP_DMB"}
+++ /dev/null
-%default {"volatile":"0"}
-%verify "executed"
-%verify "null object"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- FETCH(a0, 4) # a0<- CCCC
- LOAD_rSELF_methodClassDex(a3) # a3 <- DvmDex
- sll a2,a2,16
- or a1, a1, a2 # a1<- AAAAaaaa
-
- LOAD_base_offDvmDex_pResFields(a2, a3) # a2 <- pResFields
- GET_VREG(rOBJ, a0) # rOBJ <- fp[B], the object pointer
- LOAD_eas2(a0, a2, a1) # a0 <- resolved InstField ptr
- # is resolved entry null?
- bnez a0, .L${opcode}_finish # no, already resolved
- LOAD_rSELF_method(a2) # a2 <- current method
- EXPORT_PC() # resolve() could throw
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveInstField) # v0 <- resolved InstField ptr
- b .L${opcode}_resolved # resolved, continue
-
-%break
-
-.L${opcode}_resolved:
- move a0, v0
- beqz a0, common_exceptionThrown
- # fall through to ${opcode}_finish
- /*
- * Currently:
- * a0 holds resolved field
- * rOBJ holds object
- */
-.L${opcode}_finish:
- FETCH(a2, 3) # a1<- BBBB
- LOAD_base_offInstField_byteOffset(a3, a0) # a3 <- byte offset of field
- EAS2(a2, rFP, a2) # a2 <- &fp[BBBB]
- # check object for null
- beqz rOBJ, common_errNullObject # object was null
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- LOAD64(a0, a1, a2) # a0/a1 <- fp[BBBB]
- GET_INST_OPCODE(rBIX) # extract opcode from rINST
- addu a2, rOBJ, a3 # form address
- .if $volatile
- JAL(dvmQuasiAtomicSwap64Sync) # stores r0/r1 into addr r2
-# STORE64(a0, a1, a2) # obj.field (64 bits, aligned) <- a0 a1
- .else
- STORE64(a0, a1, a2) # obj.field (64 bits, aligned) <- a0 a1
- .endif
- GOTO_OPCODE(rBIX) # jump to next instruction
-
-
+++ /dev/null
-%verify "executed"
-%include "mips/OP_IPUT_WIDE_JUMBO.S" {"volatile":"1"}
+++ /dev/null
-%verify "executed"
-%verify "negative array length"
-%verify "allocation fails"
- /*
- * Allocate an array of objects, specified with the array class
- * and a count.
- *
- * The verifier guarantees that this is an array class, so we don't
- * check for it here.
- */
- /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
- FETCH(a2, 1) # a2<- aaaa (lo)
- FETCH(a3, 2) # a3<- AAAA (hi)
- FETCH(a0, 4) # a0<- vCCCC
- sll a3,a3,16 #
- or a2, a2, a3 # a2<- AAAAaaaa
-
- LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
- GET_VREG(a1, a0) # a1 <- vCCCC (array length)
- LOAD_base_offDvmDex_pResClasses(a3, a3) # a3 <- pDvmDex->pResClasses
- LOAD_eas2(a0, a3, a2) # a0 <- resolved class
- # check length
- bltz a1, common_errNegativeArraySize # negative length, bail - len in a1
- EXPORT_PC() # req'd for resolve, alloc
- # already resolved?
- beqz a0, .L${opcode}_resolve # not resolved,
- b .L${opcode}_finish
-%break
-
- /*
- * Finish allocation.
- *
- * a0 holds class
- * a1 holds array length
- */
-.L${opcode}_finish:
- li a2, ALLOC_DONT_TRACK # don't track in local refs table
- JAL(dvmAllocArrayByClass) # v0 <- call(clazz, length, flags)
- FETCH(a2, 3) # r2<- vBBBB
- # failed?
- beqz v0, common_exceptionThrown # yes, handle the exception
- FETCH_ADVANCE_INST(5) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG(v0, a2) # vBBBB <- v0
- GOTO_OPCODE(t0) # jump to next instruction
-#%break
-
-
-
- /*
- * Resolve class. (This is an uncommon case.)
- *
- * a1 holds array length
- * a2 holds class ref AAAAAAAA
- */
-.L${opcode}_resolve:
- LOAD_rSELF_method(a3) # a3 <- self->method
- move rOBJ, a1 # rOBJ <- length (save)
- move a1, a2 # a1 <- AAAAAAAA
- li a2, 0 # a2 <- false
- LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
- JAL(dvmResolveClass) # v0 <- call(clazz, ref)
- move a1, rOBJ # a1 <- length (restore)
- # got null?
- beqz v0, common_exceptionThrown # yes, handle exception
- move a0, v0
- b .L${opcode}_finish # continue with to ${opcode}_finish
-
-
+++ /dev/null
-%verify "executed"
-%verify "class not resolved"
-%verify "class cannot be resolved"
-%verify "class not initialized"
-%verify "class fails to initialize"
-%verify "class already resolved/initialized"
-%verify "class is abstract or interface"
-%verify "allocation fails"
- /*
- * Create a new instance of a class.
- */
- /* new-instance/jumbo vBBBB, class@AAAAAAAA */
- FETCH(a0, 1) # a0<- aaaa (lo)DvmDex
- FETCH(a1, 2) # a1<- AAAA (hi)BBB
- LOAD_base_offDvmDex_pResClasses(a3, a3) # a3 <- pDvmDex->pResClasses
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- LOAD_eas2(a0, a3, a1) # a0 <- resolved class
-#if defined(WITH_JIT)
- EAS2(rBIX, a3, a1) # rBIX <- &resolved_class
-#endif
- EXPORT_PC() # req'd for init, resolve, alloc
- # already resolved?
- beqz a0, .L${opcode}_resolve # no, resolve it now
-.L${opcode}_resolved: # a0=class
- lbu a1, offClassObject_status(a0) # a1 <- ClassStatus enum
- # has class been initialized?
- li t0, CLASS_INITIALIZED
- move rOBJ, a0 # save a0
- bne a1, t0, .L${opcode}_needinit # no, init class now
-
-.L${opcode}_initialized: # a0=class
- LOAD_base_offClassObject_accessFlags(a3, a0) # a3 <- clazz->accessFlags
- li a1, ALLOC_DONT_TRACK # flags for alloc call
- # a0=class
- JAL(dvmAllocObject) # v0 <- new object
- FETCH(a3, 3) # a3<- BBBB
-#if defined(WITH_JIT)
- /*
- * The JIT needs the class to be fully resolved before it can
- * include this instruction in a trace.
- */
- lhu a1, offThread_subMode(rSELF)
- beqz v0, common_exceptionThrown # yes, handle the exception
- and a1, kSubModeJitTraceBuild # under construction?
- bnez a1, .L${opcode}_jitCheck
-#else
- # failed?
- beqz v0, common_exceptionThrown # yes, handle the exception
-#endif
- b .L${opcode}_continue
-
-%break
-
-.L${opcode}_continue:
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG(v0, a3) # vBBBB <- v0
- GOTO_OPCODE(t0) # jump to next instruction
-
-#if defined(WITH_JIT)
- /*
- * Check to see if we need to stop the trace building early.
- * v0: new object
- * a3: vAA
- */
-.L${opcode}_jitCheck:
- lw a1, 0(rBIX) # reload resolved class
- # okay?
- bnez a1, .L${opcode}_continue # yes, finish
- move rOBJ, v0 # preserve new object
- move rBIX, a3 # preserve vAA
- move a0, rSELF
- move a1, rPC
- JAL(dvmJitEndTraceSelect) # (self, pc)
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG(rOBJ, rBIX) # vAA <- new object
- GOTO_OPCODE(t0) # jump to next instruction
-#endif
-
- /*
- * Class initialization required.
- *
- * a0 holds class object
- */
-.L${opcode}_needinit:
- JAL(dvmInitClass) # initialize class
- move a0, rOBJ # restore a0
- # check boolean result
- bnez v0, .L${opcode}_initialized # success, continue
- b common_exceptionThrown # failed, deal with init exception
-
-
- /*
- * Resolution required. This is the least-likely path.
- *
- * a1 holds AAAAAAAA
- */
-.L${opcode}_resolve:
- LOAD_rSELF_method(a3) # a3 <- self->method
- li a2, 0 # a2 <- false
- LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
- JAL(dvmResolveClass) # v0 <- resolved ClassObject ptr
- move a0, v0
- # got null?
- bnez v0, .L${opcode}_resolved # no, continue
- b common_exceptionThrown # yes, handle exception
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_JUMBO.S"
+++ /dev/null
-%default { "barrier":" # no-op " }
-%verify "executed"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 32-bit SGET handler.
- *
- * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
- * sget-char/jumbo, sget-short/jumbo
- */
- /* exop vBBBB, field@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a2) # a2 <- DvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResFields(rBIX, a2) # rBIX <- dvmDex->pResFields
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- LOAD_eas2(a0, rBIX, a1) # a0 <- resolved StaticField ptr
- # is resolved entry !null?
- bnez a0, .L${opcode}_finish
-
- /*
- * Continuation if the field has not yet been resolved.
- * a1: AAAAAAAA field ref
- * rBIX: dvmDex->pResFields
- */
- LOAD_rSELF_method(a2) # a2 <- current method
-#if defined(WITH_JIT)
- EAS2(rBIX, rBIX, a1) # rBIX<- &dvmDex->pResFields[field]
-#endif
- EXPORT_PC() # resolve() could throw, so export now
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveStaticField) # v0 <- resolved StaticField ptr
- move a0, v0
- # success?
- beqz v0, common_exceptionThrown # no, handle exception
-#if defined(WITH_JIT)
- /*
- * If the JIT is actively building a trace we need to make sure
- * that the field is fully resolved before including this instruction.
- */
- JAL(common_verifyField)
-#endif
- b .L${opcode}_finish # resume
-%break
-
-.L${opcode}_finish:
- LOAD_base_offStaticField_value(a1, a0) # a1 <- field value
- $barrier # acquiring load
- FETCH(a2, 3) # r2<- BBBB
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG_GOTO(a1, a2, t0) # fp[BBBB] <- a1
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_OBJECT_JUMBO.S" {"barrier":"SMP_DMB"}
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_JUMBO.S" {"barrier":"SMP_DMB"}
+++ /dev/null
-%default {"volatile":"0"}
-%verify "executed"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 64-bit SGET handler.
- */
- /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a2) # a2 <- DvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResFields(a2, a2) # a2 <- dvmDex->pResFields
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- LOAD_eas2(a0, a2, a1) # a0 <- resolved StaticField ptr
- # is resolved entry null?
- bnez a0, .L${opcode}_finish
-
- /*
- * Continuation if the field has not yet been resolved.
- * a1: AAAAAAAA field ref
- *
- * Returns StaticField pointer in v0.
- */
- LOAD_rSELF_method(a2) # a2 <- current method
- EXPORT_PC() # resolve() could throw, so export now
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveStaticField) # a0 <- resolved StaticField ptr
- move a0, v0
- # success?
- beqz v0, common_exceptionThrown # no, handle exception
- b .L${opcode}_finish # resume
-%break
-
-.L${opcode}_finish:
- FETCH(a1, 3) # a1<- BBBB
- .if $volatile
- vLOAD64_off(a2, a3, a0, offStaticField_value) # a2/a3 <- field value (aligned)
- .else
- LOAD64_off(a2, a3, a0, offStaticField_value) # a2/a3 <- field value (aligned)
- .endif
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- EAS2(a1, rFP, a1) # a1 <- &fp[BBBB]
- STORE64(a2, a3, a1) # vBBBB/vBBBB+1 <- a2/a3
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SGET_WIDE_JUMBO.S" {"volatile":"1"}
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_JUMBO.S"
+++ /dev/null
-%default { "postbarrier":" # no-op ", "prebarrier":" # no-op " }
-%verify "executed"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 32-bit SPUT handler.
- *
- * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
- * sput-short/jumbo
- */
- /* exop vBBBB, field@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a2) # a2 <- DvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResFields(rBIX, a2) # rBIX <- dvmDex->pResFields
- sll a1,a1,16
- or a1, a0, a1 # a1<- AAAAaaaa
- LOAD_eas2(a0, rBIX, a1) # a0 <- resolved StaticField ptr
- bnez a0, .L${opcode}_finish # is resolved entry null?
-
- /*
- * Continuation if the field has not yet been resolved.
- * a1: AAAAAAAA field ref
- * rBIX: dvmDex->pResFields
- */
- LOAD_rSELF_method(a2) # a2 <- current method
-#if defined(WITH_JIT)
- EAS2(rBIX, rBIX, a1) # rBIX<- &dvmDex->pResFields[field]
-#endif
- EXPORT_PC() # resolve() may throw, so export now
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveStaticField) # v0 <- resolved StaticField ptr
- move a0, v0
- beqz v0, common_exceptionThrown # success? no, handle exception
-#if defined(WITH_JIT)
- /*
- * If the JIT is actively building a trace we need to make sure
- * that the field is fully resolved before including this instruction.
- */
- JAL(common_verifyField)
-#endif
- b .L${opcode}_finish # resume
-%break
-
-.L${opcode}_finish:
- # field ptr in a0
- FETCH(a2, 3) # a2<- BBBB
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- GET_VREG(a1, a2) # a1 <- fp[BBBB]
- GET_INST_OPCODE(t0) # extract opcode from rINST
- $prebarrier # releasing store
- sw a1, offStaticField_value(a0) # field <- vBBBB
- $postbarrier
- GOTO_OPCODE(t0) # jump to next instruction
+++ /dev/null
-%default { "postbarrier":" # no-op ", "prebarrier":" # no-op " }
-%verify "executed"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 32-bit SPUT handler for objects
- */
- /* sput-object/jumbo vBBBB, field@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a2) # a2 <- DvmDex
- FETCH(a0, 1) # a0<- aaaa (lo)
- FETCH(a1, 2) # a1<- AAAA (hi)
- LOAD_base_offDvmDex_pResFields(rBIX, a2) # rBIX <- dvmDex->pResFields
- sll a1,a1,16
- or a1,a0,a1 # a1<- AAAAaaaa
-
- LOAD_eas2(a0, rBIX, a1) # a0 <- resolved StaticField ptr
- bnez a0, .L${opcode}_finish # is resolved entry null?
-
- /* Continuation if the field has not yet been resolved.
- * a1: BBBB field ref
- * rBIX: dvmDex->pResFields
- */
- LOAD_rSELF_method(a2) # a2 <- current method
-#if defined(WITH_JIT)
- EAS2(rBIX, rBIX, a1) # rBIX<- &dvmDex->pResFields[field]
-#endif
- EXPORT_PC() # resolve() may throw, so export now
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveStaticField) # v0 <- resolved StaticField ptr
- move a0, v0
- beqz v0, common_exceptionThrown # success? no, handle exception
-#if defined(WITH_JIT)
- /*
- * If the JIT is actively building a trace we need to make sure
- * that the field is fully resolved before including this instruction.
- */
- JAL(common_verifyField)
-#endif
- b .L${opcode}_finish # resume
-
-%break
-.L${opcode}_finish: # field ptr in a0
- FETCH(a2, 3) # a2<- BBBB
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- GET_VREG(a1, a2) # a1 <- fp[BBBB]
- lw a2, offThread_cardTable(rSELF) # a2 <- card table base
- lw t1, offField_clazz(a0) # t1 <- field->clazz
- GET_INST_OPCODE(t0) # extract opcode from rINST
- $prebarrier # releasing store
- sw a1, offStaticField_value(a0) # field <- vBBBB
- $postbarrier
- beqz a1, 1f
- srl t2, t1, GC_CARD_SHIFT
- addu t3, a2, t2
- sb a2, (t3)
- 1:
- GOTO_OPCODE(t0) # jump to next instruction
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_OBJECT_JUMBO.S" {"prebarrier":"SMP_DMB_ST", "postbarrier":"SMP_DMB"}
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_JUMBO.S"
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_JUMBO.S" {"prebarrier":"SMP_DMB_ST", "postbarrier":"SMP_DMB"}
+++ /dev/null
-%default {"volatile":"0"}
-%verify "executed"
-%verify "field already resolved"
-%verify "field not yet resolved"
-%verify "field cannot be resolved"
- /*
- * Jumbo 64-bit SPUT handler.
- */
- /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
- LOAD_rSELF_methodClassDex(a2) # a2 <- DvmDex
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- LOAD_base_offDvmDex_pResFields(rBIX, a2) # rBIX <- dvmDex->pResFields
- sll a2,a2,16
- or a1, a1, a2 # a1<- AAAAaaaa
- FETCH(rOBJ, 3) # rOBJ<- BBBB solved StaticField ptr
- EAS2(rOBJ, rFP, t0) # rOBJ<- &fp[BBBB]
- # is resolved entry null?
- beqz a2, .L${opcode}_resolve # yes, do resolve
-.L${opcode}_finish: # field ptr in a2, BBBB in rOBJ
- FETCH_ADVANCE_INST(4) # advance rPC, load rINST
- LOAD64(a0, a1, rOBJ) # a0/a1 <- vBBBB/vBBBB+1
- GET_INST_OPCODE(rBIX) # extract opcode from rINST
- .if $volatile
- addu a2, offStaticField_value # a2<- pointer to data
- JAL(dvmQuasiAtomicSwap64Sync) # stores a0/a1 into addr a2
- .else
- STORE64_off(a0, a1, a2, offStaticField_value) # field <- vBBBB/vBBBB+1
- .endif
- GOTO_OPCODE(rBIX) # jump to next instruction
-%break
-
- /*
- * Continuation if the field has not yet been resolved.
- * a1: AAAAAAAA field ref
- * rOBJ: &fp[BBBB]
- * rBIX: dvmDex->pResFields
- *
- * Returns StaticField pointer in a2.
- */
-.L${opcode}_resolve:
- LOAD_rSELF_method(a2) # a2 <- current method
-#if defined(WITH_JIT)
- EAS2(rBIX, rBIX, a1) # rBIX<- &dvmDex->pResFields[field]
-#endif
- EXPORT_PC() # resolve() could throw, so export now
- LOAD_base_offMethod_clazz(a0, a2) # a0 <- method->clazz
- JAL(dvmResolveStaticField) # v0 <- resolved StaticField ptr
- # success ?
- move a0, v0
- beqz v0, common_exceptionThrown # no, handle exception
-#if defined(WITH_JIT)
- /*
- * If the JIT is actively building a trace we need to make sure
- * that the field is fully resolved before including this instruction.
- */
- JAL(common_verifyField)
-#endif
- move a2, v0
- b .L${opcode}_finish # resume
+++ /dev/null
-%verify "executed"
-%include "mips/OP_SPUT_WIDE_JUMBO.S" {"volatile":"1"}
+++ /dev/null
-%verify executed
- /*
- * Handle a jumbo throw-verification-error instruction. This throws an
- * exception for an error discovered during verification. The
- * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
- */
- /* exop BBBB, Class@AAAAAAAA */
- FETCH(a1, 1) # a1<- aaaa (lo)
- FETCH(a2, 2) # a2<- AAAA (hi)
- LOAD_rSELF_method(a0) # a0 <- self->method
- sll a2,a2,16
- or a2, a1, a2 # a2<- AAAAaaaa
- EXPORT_PC() # export the PC
- FETCH(a1, 3) # a1<- BBBB
- JAL(dvmThrowVerificationError) # always throws
- b common_exceptionThrown # handle exception
-
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
+++ /dev/null
-%include "mips/unused.S"
#endif
/*
- * Common code for jumbo method invocation.
- * NOTE: this adjusts rPC to account for the difference in instruction width.
- * As a result, the savedPc in the stack frame will not be wholly accurate. So
- * long as that is only used for source file line number calculations, we're
- * okay.
- */
-common_invokeMethodJumboNoThis:
-#if defined(WITH_JIT)
- /* On entry: a0 is "Method* methodToCall */
- li rOBJ, 0 # clear "this"
-#endif
-common_invokeMethodJumbo:
- /* On entry: a0 is "Method* methodToCall, rOBJ is "this" */
-.LinvokeNewJumbo:
-#if defined(WITH_JIT)
- lhu a1, offThread_subMode(rSELF)
- andi a1, kSubModeJitTraceBuild
- beqz a1, 1f
- JAL(save_callsiteinfo)
-#endif
-/* prepare to copy args to "outs" area of current frame */
-1:
- add rPC, rPC, 4 # adjust pc to make return consistent
- FETCH(a2, 1)
- SAVEAREA_FROM_FP(rBIX, rFP) # rBIX <- stack save area
- beqz a2, .LinvokeArgsDone # if no args, skip the rest
- FETCH(a1, 2) # a1 <- CCCC
- b .LinvokeRangeArgs # handle args like invoke range
-
-
-/*
* Common code for method invocation with range.
*
* On entry:
*/
.LOP_INVOKE_OBJECT_INIT_RANGE_debugger:
lw a1, offThread_mainHandlerTable(rSELF)
- .if 0
- li t0, OP_INVOKE_DIRECT_JUMBO
- .else
li t0, OP_INVOKE_DIRECT_RANGE
- .endif
GOTO_OPCODE_BASE(a1, t0) # execute it
/* continuation for OP_IPUT_OBJECT_VOLATILE */
#endif
/*
- * Common code for jumbo method invocation.
- * NOTE: this adjusts rPC to account for the difference in instruction width.
- * As a result, the savedPc in the stack frame will not be wholly accurate. So
- * long as that is only used for source file line number calculations, we're
- * okay.
- */
-common_invokeMethodJumboNoThis:
-#if defined(WITH_JIT)
- /* On entry: a0 is "Method* methodToCall */
- li rOBJ, 0 # clear "this"
-#endif
-common_invokeMethodJumbo:
- /* On entry: a0 is "Method* methodToCall, rOBJ is "this" */
-.LinvokeNewJumbo:
-#if defined(WITH_JIT)
- lhu a1, offThread_subMode(rSELF)
- andi a1, kSubModeJitTraceBuild
- beqz a1, 1f
- JAL(save_callsiteinfo)
-#endif
-/* prepare to copy args to "outs" area of current frame */
-1:
- add rPC, rPC, 4 # adjust pc to make return consistent
- FETCH(a2, 1)
- SAVEAREA_FROM_FP(rBIX, rFP) # rBIX <- stack save area
- beqz a2, .LinvokeArgsDone # if no args, skip the rest
- FETCH(a1, 2) # a1 <- CCCC
- b .LinvokeRangeArgs # handle args like invoke range
-
-
-/*
* Common code for method invocation with range.
*
* On entry:
#include "Dalvik.h"
#include "native/InternalNativePriv.h"
-#ifdef HAVE_SELINUX
#include <selinux/android.h>
-#endif
#include <signal.h>
#include <sys/types.h>
#include <cutils/sched_policy.h>
#include <cutils/multiuser.h>
#include <sched.h>
+#include <sys/utsname.h>
#if defined(HAVE_PRCTL)
# include <sys/prctl.h>
return 0;
}
-#ifdef HAVE_SELINUX
/*
* Set SELinux security context.
*
return 0;
#endif
}
+
+static bool needsNoRandomizeWorkaround() {
+#if !defined(__arm__)
+ return false;
+#else
+ int major;
+ int minor;
+ struct utsname uts;
+ if (uname(&uts) == -1) {
+ return false;
+ }
+
+ if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
+ return false;
+ }
+
+ // Kernels before 3.4.* need the workaround.
+ return (major < 3) || ((major == 3) && (minor < 4));
#endif
+}
/*
* Utility routine to fork zygote and specialize the child process.
ArrayObject *rlimits = (ArrayObject *)args[4];
u4 mountMode = MOUNT_EXTERNAL_NONE;
int64_t permittedCapabilities, effectiveCapabilities;
-#ifdef HAVE_SELINUX
char *seInfo = NULL;
char *niceName = NULL;
-#endif
if (isSystemServer) {
/*
} else {
mountMode = args[5];
permittedCapabilities = effectiveCapabilities = 0;
-#ifdef HAVE_SELINUX
StringObject* seInfoObj = (StringObject*)args[6];
if (seInfoObj) {
seInfo = dvmCreateCstrFromString(seInfoObj);
dvmAbort();
}
}
-#endif
}
if (!gDvm.zygote) {
dvmAbort();
}
- int current = personality(0xffffFFFF);
- int success = personality((ADDR_NO_RANDOMIZE | current));
- if (success == -1) {
- ALOGW("Personality switch failed. current=%d error=%d\n", current, errno);
+ if (needsNoRandomizeWorkaround()) {
+ int current = personality(0xffffFFFF);
+ int success = personality((ADDR_NO_RANDOMIZE | current));
+ if (success == -1) {
+ ALOGW("Personality switch failed. current=%d error=%d\n", current, errno);
+ }
}
err = setCapabilities(permittedCapabilities, effectiveCapabilities);
dvmAbort();
}
-#ifdef HAVE_SELINUX
err = setSELinuxContext(uid, isSystemServer, seInfo, niceName);
if (err < 0) {
ALOGE("cannot set SELinux context: %s\n", strerror(errno));
// lock when we forked.
free(seInfo);
free(niceName);
-#endif
/*
* Our system thread ID has changed. Get the new one.
}
} else if (pid > 0) {
/* the parent process */
-#ifdef HAVE_SELINUX
free(seInfo);
free(niceName);
-#endif
}
return pid;