From: Jack Ren <jack.ren@intel.com>
Date: Tue, 1 Mar 2011 21:10:42 +0800
Subject: [PATCH 1/2] sync with korg/master commit
dd19f5b91a1032e60871febb143850fd81000c5a
following patches are applied in one time:
commit
dd19f5b91a1032e60871febb143850fd81000c5a
Merge:
2b3d7e8 a62c84f
Author: Romain Guy <romainguy@android.com>
Date: Thu Feb 24 11:24:47 2011 -0800
Merge "Fix for a crash when GC weak references."
commit
2b3d7e8eccd7cbf64b2ac41c05073a9191d0d3b3
Merge:
ef4b061 b4719ed
Author: Raphael Moll <ralf@android.com>
Date: Tue Feb 22 14:55:59 2011 -0800
Merge "Open dexdump files in binary mode."
commit
b4719eda048c4dc4a4b6e5280c7a2b8299051078
Author: Raphael Moll <ralf@android.com>
Date: Wed Feb 16 13:39:27 2011 -0800
Open dexdump files in binary mode.
Requires change Ia5c0a59e from system/core
(which defines O_BINARY globally.)
commit
a62c84f62a27a08d6bef6da0b96913d616dd659f
Author: Mattias Petersson <mattias.petersson@sonyericsson.com>
Date: Tue Dec 21 09:28:04 2010 +0100
Fix for a crash when GC weak references.
When a weak reference had been cleared there was a small risk that
the VM crashed when the cleared reference was garbage collected.
This is an example of code that can cause the problem:
Integer referent = new Integer(10);
wref = new WeakReference<Integer>(referent);
wref.clear(); //set the referent to null
When a garbage collection starts, all objects are scanned, looking
for objects that can be collected. During this phase, a list of
weak references is created. A check is performed to ensure that
only references with a non-null referent are added to this list.
In most cases, for the example above, the referent will be null
at this point, and it will never be added to the list. But if
the timing is extremely bad it looks like it is possible for the
reference to end up on the list before the referent has been set
to null, and the referent is set to null a little while later.
This means that we now have a reference on the list with a null
referent.
A bit later in the garbage collection flow, the list of weak
s is traversed in order to clear the references that
can be collected. Here we got the crash because the code asserted
that the referent of the references in the list should be
non-null. And in some rare cases it actually was null. The fix
is simply to remove the assert.
commit
ef4b0613d6952770aefac07d503955eb7b962d2b
Merge:
464104b e9503ef
Author: Andy McFadden <fadden@android.com>
Date: Mon Nov 8 19:38:19 2010 -0800
am
e9503ef8: am
886130bc: (-s ours) Two patches.
* commit '
e9503ef8c460f4818062ecc80a9e0b4f8c6745b8':
Two patches.
Change-Id: I04c1c9204af8197a4352358d805af40f1312d2ea
Signed-off-by: Bruce Beare <bruce.j.beare@intel.com>
jarfile=dx.jar
libdir="$progdir"
+
if [ ! -r "$libdir/$jarfile" ]; then
+ # set dx.jar location for the SDK case
libdir=`dirname "$progdir"`/platform-tools/lib
fi
+
if [ ! -r "$libdir/$jarfile" ]; then
+ # set dx.jar location for the Android tree case
libdir=`dirname "$progdir"`/framework
fi
/*
* Pop open the (presumed) DEX file.
*/
- fd = open(fileName, O_RDONLY);
+ fd = open(fileName, O_RDONLY | O_BINARY);
if (fd < 0) {
if (!quiet) {
fprintf(stderr, "ERROR: unable to open '%s': %s\n",
memset(pArchive, 0, sizeof(ZipArchive));
- fd = open(fileName, O_RDONLY, 0);
+ fd = open(fileName, O_RDONLY | O_BINARY, 0);
if (fd < 0) {
err = errno ? errno : -1;
LOGV("Unable to open '%s': %s\n", fileName, strerror(err));
void dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt)
{
if (gDvm.jdwpState == NULL) {
- LOGV("Debugger thread not active, ignoring DDM send (t=0x%08x l=%d)\n",
- type, len);
+ LOGV("Debugger thread not active, ignoring DDM send (t=0x%08x)\n",
+ type);
return;
}
free(gDvm.bootClassPathStr);
gDvm.bootClassPathStr = strdup(path);
- /*
- * TODO: support -Xbootclasspath/a and /p, which append or
- * prepend to the default bootclasspath. We set the default
- * path earlier.
- */
+ } else if (strncmp(argv[i], "-Xbootclasspath/a:",
+ sizeof("-Xbootclasspath/a:")-1) == 0) {
+ const char* appPath = argv[i] + sizeof("-Xbootclasspath/a:")-1;
+
+ if (*(appPath) == '\0') {
+ dvmFprintf(stderr, "Missing appending bootclasspath path list\n");
+ return -1;
+ }
+ char* allPath;
+
+ if (asprintf(&allPath, "%s:%s", gDvm.bootClassPathStr, appPath) < 0) {
+ dvmFprintf(stderr, "Can't append to bootclasspath path list\n");
+ return -1;
+ }
+ free(gDvm.bootClassPathStr);
+ gDvm.bootClassPathStr = allPath;
+
+ } else if (strncmp(argv[i], "-Xbootclasspath/p:",
+ sizeof("-Xbootclasspath/p:")-1) == 0) {
+ const char* prePath = argv[i] + sizeof("-Xbootclasspath/p:")-1;
+
+ if (*(prePath) == '\0') {
+ dvmFprintf(stderr, "Missing prepending bootclasspath path list\n");
+ return -1;
+ }
+ char* allPath;
+
+ if (asprintf(&allPath, "%s:%s", prePath, gDvm.bootClassPathStr) < 0) {
+ dvmFprintf(stderr, "Can't prepend to bootclasspath path list\n");
+ return -1;
+ }
+ free(gDvm.bootClassPathStr);
+ gDvm.bootClassPathStr = allPath;
} else if (strncmp(argv[i], "-D", 2) == 0) {
/* set property */
lea (%esp), %ebp
/*
- * Update and align (16 bytes) stack pointer
- */
-
- lea -32(%esp), %esp
-
- /*
* Check if argInfo is valid. Is always valid so should remove this check?
*/
subl %ecx, %esp # %esp<- expanded for arg region
/*
- * Is the alignment right?
+ * Prepare for 16 byte alignment
*/
-#if 1
- test $4, %esp
- jnz 1f
- subl $4, %esp
-1:
- test $8, %esp
- jnz 1f
- subl $8, %esp
-1:
-#endif
+ and $0xfffffff0, %esp
+ subl $24, %esp
+
movl 8(%ebp), %eax # %eax<- clazz
cmpl $0, %eax # Check virtual or static
*/
cmpl $3,%ebx
- je S8
+ je S8
cmpl $4,%ebx
je S4
cmpl $7,%ebx
je S1
cmpl $6,%ebx
- jne S2
+ jne S2
U2:
movzwl %ax, %eax
movl %eax, (%ecx) # save 32-bit return
#op OP_APUT_SHORT c
#op OP_APUT_WIDE c
#op OP_ARRAY_LENGTH c
+#op OP_BREAKPOINT c
#op OP_CHECK_CAST c
#op OP_CMPG_DOUBLE c
#op OP_CMPG_FLOAT c
#op OP_DOUBLE_TO_FLOAT c
#op OP_DOUBLE_TO_INT c
#op OP_DOUBLE_TO_LONG c
+#op OP_EXECUTE_INLINE_RANGE c
#op OP_EXECUTE_INLINE c
#op OP_FILL_ARRAY_DATA c
#op OP_FILLED_NEW_ARRAY_RANGE c
#op OP_XOR_INT c
#op OP_XOR_LONG_2ADDR c
#op OP_XOR_LONG c
-
# TODO: provide native implementations
-op OP_BREAKPOINT c
-op OP_EXECUTE_INLINE_RANGE c
op OP_IGET_VOLATILE c
op OP_IPUT_VOLATILE c
op OP_SGET_VOLATILE c
op OP_IPUT_WIDE_VOLATILE c
op OP_SGET_WIDE_VOLATILE c
op OP_SPUT_WIDE_VOLATILE c
-
op-end
# arch-specific entry point to interpreter
* For: monitor-exit
*
* Description: Release a monitor for the indicated object. If this instruction needs
- * to throw an execption, it must do so as if teh pc has already
+ * to throw an execption, it must do so as if the pc has already
* advanced pased the instruction.
*
* Format: AA|op (11x)
/* ------------------------------ */
.balign 64
.L_OP_BREAKPOINT: /* 0xec */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+/* File: x86-atom/OP_BREAKPOINT.S */
+/* File: x86/unused.S */
+ jmp common_abort
- /*
- * File: stub.S
- */
- SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
- pushl rGLUE # push parameter glue
- call dvmMterp_OP_BREAKPOINT # call c-based implementation
- lea 4(%esp), %esp
- LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
- FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
*
* Format:
*
- * Syntax: vAA, {vC, vD, vE, vF}, inline@BBBB
+ * Syntax: A, {vC, vD, vE, vF}, inline@BBBB
*/
FETCH 1, %ecx # %ecx<- BBBB
movl rGLUE, %eax # %eax<- MterpGlue pointer
addl $offGlue_retval, %eax # %eax<- &glue->retval
EXPORT_PC
- shr $4, rINST # rINST<- B
+ shr $4, rINST # rINST<- A
movl %eax, -8(%esp) # push parameter glue->retval
lea -24(%esp), %esp
jmp .LOP_EXECUTE_INLINE_continue
/* ------------------------------ */
.balign 64
.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
- /* Copyright (C) 2008 The Android Open Source Project
+/* File: x86-atom/OP_EXECUTE_INLINE_RANGE.S */
+ /* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
/*
- * File: stub.S
+ * File: OP_EXECUTE_INLINE_RANGE.S
+ *
+ * Code: Executes a "native inline" instruction. Uses no substitutions.
+ *
+ * For: execute-inline
+ *
+ * Description: Executes a "native inline" instruction. This instruction
+ * is generated by the optimizer.
+ *
+ * Format:
+ *
+ * Syntax: AA, {vCCCC..v(CCCC+AA-1)}, inline@BBBB
*/
- SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
- pushl rGLUE # push parameter glue
- call dvmMterp_OP_EXECUTE_INLINE_RANGE # call c-based implementation
- lea 4(%esp), %esp
- LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
- FINISH_A # jump to next instruction
+ FETCH 1, %ecx # %ecx<- BBBB
+ movl rGLUE, %eax # %eax<- MterpGlue pointer
+ addl $offGlue_retval, %eax # %eax<- &glue->retval
+ EXPORT_PC
+ movl %eax, -8(%esp) # push parameter glue->retval
+ lea -24(%esp), %esp
+ jmp .LOP_EXECUTE_INLINE_RANGE_continue
+
/* ------------------------------ */
.balign 64
.L_OP_INVOKE_DIRECT_EMPTY: /* 0xf0 */
lea 24(%esp), %esp # update stack pointer
je common_exceptionThrown # handle exception
FGETOP_JMP 3, %eax # jump to next instruction; getop, jmp
+/* continuation for OP_EXECUTE_INLINE_RANGE */
+
+ /*
+ * Extract args, call function.
+ * rINST = #of args (0-4)
+ * %ecx = call index
+ */
+
+.LOP_EXECUTE_INLINE_RANGE_continue:
+ FETCH 2, %edx # %edx<- FEDC
+ cmp $1, rINST # determine number of arguments
+ jl 0f # handle zero args
+ je 1f # handle one arg
+ cmp $3, rINST
+ jl 2f # handle two args
+ je 3f # handle three args
+4:
+ movl 12(rFP, %edx, 4), rINST # rINST<- vF
+ movl rINST, 12(%esp) # push parameter vF
+3:
+ movl 8(rFP, %edx, 4), rINST # rINST<- vE
+ movl rINST, 8(%esp) # push parameter E
+2:
+ movl 4(rFP, %edx, 4), rINST # rINST<- vD
+ movl rINST, 4(%esp) # push parameter D
+1:
+ movl (rFP, %edx, 4), %edx # rINST<- vC
+ movl %edx, (%esp) # push parameter C
+0:
+ shl $4, %ecx
+ movl $gDvmInlineOpsTable, %eax # %eax<- address for table of inline operations
+ call *(%eax, %ecx) # call function
+
+ cmp $0, %eax # check boolean result of inline
+ FFETCH_ADV 3, %eax # %eax<- next instruction hi; fetch, advance
+ lea 24(%esp), %esp # update stack pointer
+ je common_exceptionThrown # handle exception
+ FGETOP_JMP 3, %eax # jump to next instruction; getop, jmp
+
.size dvmAsmSisterStart, .-dvmAsmSisterStart
.global dvmAsmSisterEnd
dvmAsmSisterEnd:
HANDLE_SPUT_X(OP_SPUT_WIDE_VOLATILE, "-wide-volatile", LongVolatile, _WIDE)
OP_END
-/* File: c/OP_BREAKPOINT.c */
-HANDLE_OPCODE(OP_BREAKPOINT)
-#if (INTERP_TYPE == INTERP_DBG)
- {
- /*
- * Restart this instruction with the original opcode. We do
- * this by simply jumping to the handler.
- *
- * It's probably not necessary to update "inst", but we do it
- * for the sake of anything that needs to do disambiguation in a
- * common handler with INST_INST.
- *
- * The breakpoint itself is handled over in updateDebugger(),
- * because we need to detect other events (method entry, single
- * step) and report them in the same event packet, and we're not
- * yet handling those through breakpoint instructions. By the
- * time we get here, the breakpoint has already been handled and
- * the thread resumed.
- */
- u1 originalOpCode = dvmGetOriginalOpCode(pc);
- LOGV("+++ break 0x%02x (0x%04x -> 0x%04x)\n", originalOpCode, inst,
- INST_REPLACE_OP(inst, originalOpCode));
- inst = INST_REPLACE_OP(inst, originalOpCode);
- FINISH_BKPT(originalOpCode);
- }
-#else
- LOGE("Breakpoint hit in non-debug interpreter\n");
- dvmAbort();
-#endif
-OP_END
-
-/* File: c/OP_EXECUTE_INLINE_RANGE.c */
-HANDLE_OPCODE(OP_EXECUTE_INLINE_RANGE /*{vCCCC..v(CCCC+AA-1)}, inline@BBBB*/)
- {
- u4 arg0, arg1, arg2, arg3;
- arg0 = arg1 = arg2 = arg3 = 0; /* placate gcc */
-
- EXPORT_PC();
-
- vsrc1 = INST_AA(inst); /* #of args */
- ref = FETCH(1); /* inline call "ref" */
- vdst = FETCH(2); /* range base */
- ILOGV("|execute-inline-range args=%d @%d {regs=v%d-v%d}",
- vsrc1, ref, vdst, vdst+vsrc1-1);
-
- assert((vdst >> 16) == 0); // 16-bit type -or- high 16 bits clear
- assert(vsrc1 <= 4);
-
- switch (vsrc1) {
- case 4:
- arg3 = GET_REGISTER(vdst+3);
- /* fall through */
- case 3:
- arg2 = GET_REGISTER(vdst+2);
- /* fall through */
- case 2:
- arg1 = GET_REGISTER(vdst+1);
- /* fall through */
- case 1:
- arg0 = GET_REGISTER(vdst+0);
- /* fall through */
- default: // case 0
- ;
- }
-
-#if INTERP_TYPE == INTERP_DBG
- if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
- GOTO_exceptionThrown();
-#else
- if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref))
- GOTO_exceptionThrown();
-#endif
- }
- FINISH(3);
-OP_END
-
/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
--- /dev/null
+%include "x86/unused.S"
*
* Format:
*
- * Syntax: vAA, {vC, vD, vE, vF}, inline@BBBB
+ * Syntax: A, {vC, vD, vE, vF}, inline@BBBB
*/
FETCH 1, %ecx # %ecx<- BBBB
movl rGLUE, %eax # %eax<- MterpGlue pointer
addl $$offGlue_retval, %eax # %eax<- &glue->retval
EXPORT_PC
- shr $$4, rINST # rINST<- B
+ shr $$4, rINST # rINST<- A
movl %eax, -8(%esp) # push parameter glue->retval
lea -24(%esp), %esp
jmp .L${opcode}_continue
--- /dev/null
+ /* Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /*
+ * File: OP_EXECUTE_INLINE_RANGE.S
+ *
+ * Code: Executes a "native inline" instruction. Uses no substitutions.
+ *
+ * For: execute-inline
+ *
+ * Description: Executes a "native inline" instruction. This instruction
+ * is generated by the optimizer.
+ *
+ * Format:
+ *
+ * Syntax: AA, {vCCCC..v(CCCC+AA-1)}, inline@BBBB
+ */
+
+ FETCH 1, %ecx # %ecx<- BBBB
+ movl rGLUE, %eax # %eax<- MterpGlue pointer
+ addl $$offGlue_retval, %eax # %eax<- &glue->retval
+ EXPORT_PC
+ movl %eax, -8(%esp) # push parameter glue->retval
+ lea -24(%esp), %esp
+ jmp .L${opcode}_continue
+%break
+
+ /*
+ * Extract args, call function.
+ * rINST = #of args (0-4)
+ * %ecx = call index
+ */
+
+.L${opcode}_continue:
+ FETCH 2, %edx # %edx<- FEDC
+ cmp $$1, rINST # determine number of arguments
+ jl 0f # handle zero args
+ je 1f # handle one arg
+ cmp $$3, rINST
+ jl 2f # handle two args
+ je 3f # handle three args
+4:
+ movl 12(rFP, %edx, 4), rINST # rINST<- vF
+ movl rINST, 12(%esp) # push parameter vF
+3:
+ movl 8(rFP, %edx, 4), rINST # rINST<- vE
+ movl rINST, 8(%esp) # push parameter E
+2:
+ movl 4(rFP, %edx, 4), rINST # rINST<- vD
+ movl rINST, 4(%esp) # push parameter D
+1:
+ movl (rFP, %edx, 4), %edx # rINST<- vC
+ movl %edx, (%esp) # push parameter C
+0:
+ shl $$4, %ecx
+ movl $$gDvmInlineOpsTable, %eax # %eax<- address for table of inline operations
+ call *(%eax, %ecx) # call function
+
+ cmp $$0, %eax # check boolean result of inline
+ FFETCH_ADV 3, %eax # %eax<- next instruction hi; fetch, advance
+ lea 24(%esp), %esp # update stack pointer
+ je common_exceptionThrown # handle exception
+ FGETOP_JMP 3, %eax # jump to next instruction; getop, jmp
shl $$16, %ecx # prepare to create +AAAAAAAA
or %ecx, %edx # %edx<- +AAAAAAAA
shl $$1, %edx # %edx is doubled to get the byte offset
- jc common_periodicChecks2 # do check on backwards branch
+ jle common_periodicChecks2 # do check on backwards branch
FINISH_RB %edx, %ecx # jump to next instruction
* For: monitor-exit
*
* Description: Release a monitor for the indicated object. If this instruction needs
- * to throw an execption, it must do so as if teh pc has already
+ * to throw an execption, it must do so as if the pc has already
* advanced pased the instruction.
*
* Format: AA|op (11x)
jne common_exceptionThrown # handle exception
FGETOP_JMP 3, %edx # jump to next instruction; getop, jmp
-.LstackOverflow:
+.LstackOverflow: # %ecx=methodToCall
+ movl %ecx, -4(%esp) # push parameter method to call
movl rGLUE, %ecx # %ecx<- pMterpGlue
movl offGlue_self(%ecx), %ecx # %ecx<- glue->self
- movl %ecx, -4(%esp) # push parameter self
- lea -4(%esp), %esp
- call dvmHandleStackOverflow # call: (Thread* self)
+ movl %ecx, -8(%esp) # push parameter self
+ lea -8(%esp), %esp
+ call dvmHandleStackOverflow # call: (Thread* self, Method* method)
# return: void
- lea 4(%esp), %esp
+ lea 8(%esp), %esp
jmp common_exceptionThrown # handle exception
#ifdef ASSIST_DEBUGGER
#endif
movl %eax, -4(%esp) # save %eax for later
movl %ecx, -12(%esp) # push parameter 2 glue->self
lea -12(%esp), %esp
- call dvmCleanupStackOverflow # call: (Thread* self)
+ call dvmCleanupStackOverflow # call: (Thread* self, Object* exception)
# return: void
lea 12(%esp), %esp
movl -4(%esp), %eax # %eax<- restore %eax
je 1f #
movl %edx, -12(%esp) # push parameter 1 glue->self
lea -12(%esp), %esp
- call dvmCleanupStackOverflow # call: (Thread* self)
+ call dvmCleanupStackOverflow # call: (Thread* self, Object* exception)
# return: void
lea 12(%esp), %esp