Merge "Use the generated opcode info tables." into dalvik-dev
diff --git a/vm/Exception.c b/vm/Exception.c
index 7b0a835..13c655f 100644
--- a/vm/Exception.c
+++ b/vm/Exception.c
@@ -1359,3 +1359,13 @@
dvmThrowExceptionFmt("Ljava/lang/ArrayIndexOutOfBoundsException;",
"index=%d length=%d", index, length);
}
+
+void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired)
+{
+ char* actualClassName = dvmDescriptorToDot(actual->descriptor);
+ char* desiredClassName = dvmDescriptorToDot(desired->descriptor);
+ dvmThrowExceptionFmt("Ljava/lang/ClassCastException;", "%s cannot be cast to %s",
+ actualClassName, desiredClassName);
+ free(desiredClassName);
+ free(actualClassName);
+}
diff --git a/vm/Exception.h b/vm/Exception.h
index 559e47f..41ee189 100644
--- a/vm/Exception.h
+++ b/vm/Exception.h
@@ -41,6 +41,12 @@
*/
void dvmThrowAIOOBE(int index, int length);
+/**
+ * Throw a ClassCastException in the current thread, using the given classes'
+ * names in the detail message.
+ */
+void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired);
+
/*
* Like dvmThrowChainedException, but takes printf-style args for the message.
*/
diff --git a/vm/mterp/armv5te/OP_CHECK_CAST.S b/vm/mterp/armv5te/OP_CHECK_CAST.S
index c711276..3a07ea3 100644
--- a/vm/mterp/armv5te/OP_CHECK_CAST.S
+++ b/vm/mterp/armv5te/OP_CHECK_CAST.S
@@ -32,21 +32,20 @@
/*
* Trivial test failed, need to perform full check. This is common.
* r0 holds obj->clazz
- * r1 holds class resolved from BBBB
+ * r1 holds desired class resolved from BBBB
* r9 holds object
*/
.L${opcode}_fullcheck:
+ mov r10, r1 @ avoid ClassObject getting clobbered
bl dvmInstanceofNonTrivial @ r0<- boolean result
cmp r0, #0 @ failed?
bne .L${opcode}_okay @ no, success
- @ A cast has failed. We need to throw a ClassCastException with the
- @ class of the object that failed to be cast.
+ @ A cast has failed. We need to throw a ClassCastException.
EXPORT_PC() @ about to throw
- ldr r3, [r9, #offObject_clazz] @ r3<- obj->clazz
- ldr r0, .LstrClassCastExceptionPtr
- ldr r1, [r3, #offClassObject_descriptor] @ r1<- obj->clazz->descriptor
- bl dvmThrowExceptionWithClassMessage
+ ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class)
+ mov r1, r10 @ r1<- desired class
+ bl dvmThrowClassCastException
b common_exceptionThrown
/*
@@ -67,6 +66,3 @@
mov r1, r0 @ r1<- class resolved from BBB
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
b .L${opcode}_resolved @ pick up where we left off
-
-.LstrClassCastExceptionPtr:
- .word .LstrClassCastException
diff --git a/vm/mterp/armv5te/footer.S b/vm/mterp/armv5te/footer.S
index ad4994d..8f15c59 100644
--- a/vm/mterp/armv5te/footer.S
+++ b/vm/mterp/armv5te/footer.S
@@ -1257,8 +1257,6 @@
.asciz "Ljava/lang/ArithmeticException;"
.LstrArrayStoreException:
.asciz "Ljava/lang/ArrayStoreException;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
diff --git a/vm/mterp/c/OP_CHECK_CAST.c b/vm/mterp/c/OP_CHECK_CAST.c
index 9a7ecfb..2c4a304 100644
--- a/vm/mterp/c/OP_CHECK_CAST.c
+++ b/vm/mterp/c/OP_CHECK_CAST.c
@@ -22,8 +22,7 @@
GOTO_exceptionThrown();
}
if (!dvmInstanceof(obj->clazz, clazz)) {
- dvmThrowExceptionWithClassMessage(
- "Ljava/lang/ClassCastException;", obj->clazz->descriptor);
+ dvmThrowClassCastException(obj->clazz, clazz);
GOTO_exceptionThrown();
}
}
diff --git a/vm/mterp/out/InterpAsm-armv5te-vfp.S b/vm/mterp/out/InterpAsm-armv5te-vfp.S
index fe923dc..bcb357a 100644
--- a/vm/mterp/out/InterpAsm-armv5te-vfp.S
+++ b/vm/mterp/out/InterpAsm-armv5te-vfp.S
@@ -7827,21 +7827,20 @@
/*
* Trivial test failed, need to perform full check. This is common.
* r0 holds obj->clazz
- * r1 holds class resolved from BBBB
+ * r1 holds desired class resolved from BBBB
* r9 holds object
*/
.LOP_CHECK_CAST_fullcheck:
+ mov r10, r1 @ avoid ClassObject getting clobbered
bl dvmInstanceofNonTrivial @ r0<- boolean result
cmp r0, #0 @ failed?
bne .LOP_CHECK_CAST_okay @ no, success
- @ A cast has failed. We need to throw a ClassCastException with the
- @ class of the object that failed to be cast.
+ @ A cast has failed. We need to throw a ClassCastException.
EXPORT_PC() @ about to throw
- ldr r3, [r9, #offObject_clazz] @ r3<- obj->clazz
- ldr r0, .LstrClassCastExceptionPtr
- ldr r1, [r3, #offClassObject_descriptor] @ r1<- obj->clazz->descriptor
- bl dvmThrowExceptionWithClassMessage
+ ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class)
+ mov r1, r10 @ r1<- desired class
+ bl dvmThrowClassCastException
b common_exceptionThrown
/*
@@ -7863,9 +7862,6 @@
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
b .LOP_CHECK_CAST_resolved @ pick up where we left off
-.LstrClassCastExceptionPtr:
- .word .LstrClassCastException
-
/* continuation for OP_INSTANCE_OF */
/*
@@ -10614,8 +10610,6 @@
.asciz "Ljava/lang/ArithmeticException;"
.LstrArrayStoreException:
.asciz "Ljava/lang/ArrayStoreException;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index b30260c..05898d3 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -8149,21 +8149,20 @@
/*
* Trivial test failed, need to perform full check. This is common.
* r0 holds obj->clazz
- * r1 holds class resolved from BBBB
+ * r1 holds desired class resolved from BBBB
* r9 holds object
*/
.LOP_CHECK_CAST_fullcheck:
+ mov r10, r1 @ avoid ClassObject getting clobbered
bl dvmInstanceofNonTrivial @ r0<- boolean result
cmp r0, #0 @ failed?
bne .LOP_CHECK_CAST_okay @ no, success
- @ A cast has failed. We need to throw a ClassCastException with the
- @ class of the object that failed to be cast.
+ @ A cast has failed. We need to throw a ClassCastException.
EXPORT_PC() @ about to throw
- ldr r3, [r9, #offObject_clazz] @ r3<- obj->clazz
- ldr r0, .LstrClassCastExceptionPtr
- ldr r1, [r3, #offClassObject_descriptor] @ r1<- obj->clazz->descriptor
- bl dvmThrowExceptionWithClassMessage
+ ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class)
+ mov r1, r10 @ r1<- desired class
+ bl dvmThrowClassCastException
b common_exceptionThrown
/*
@@ -8185,9 +8184,6 @@
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
b .LOP_CHECK_CAST_resolved @ pick up where we left off
-.LstrClassCastExceptionPtr:
- .word .LstrClassCastException
-
/* continuation for OP_INSTANCE_OF */
/*
@@ -11072,8 +11068,6 @@
.asciz "Ljava/lang/ArithmeticException;"
.LstrArrayStoreException:
.asciz "Ljava/lang/ArrayStoreException;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
diff --git a/vm/mterp/out/InterpAsm-armv7-a-neon.S b/vm/mterp/out/InterpAsm-armv7-a-neon.S
index 65514b3..4c2da43 100644
--- a/vm/mterp/out/InterpAsm-armv7-a-neon.S
+++ b/vm/mterp/out/InterpAsm-armv7-a-neon.S
@@ -7781,21 +7781,20 @@
/*
* Trivial test failed, need to perform full check. This is common.
* r0 holds obj->clazz
- * r1 holds class resolved from BBBB
+ * r1 holds desired class resolved from BBBB
* r9 holds object
*/
.LOP_CHECK_CAST_fullcheck:
+ mov r10, r1 @ avoid ClassObject getting clobbered
bl dvmInstanceofNonTrivial @ r0<- boolean result
cmp r0, #0 @ failed?
bne .LOP_CHECK_CAST_okay @ no, success
- @ A cast has failed. We need to throw a ClassCastException with the
- @ class of the object that failed to be cast.
+ @ A cast has failed. We need to throw a ClassCastException.
EXPORT_PC() @ about to throw
- ldr r3, [r9, #offObject_clazz] @ r3<- obj->clazz
- ldr r0, .LstrClassCastExceptionPtr
- ldr r1, [r3, #offClassObject_descriptor] @ r1<- obj->clazz->descriptor
- bl dvmThrowExceptionWithClassMessage
+ ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class)
+ mov r1, r10 @ r1<- desired class
+ bl dvmThrowClassCastException
b common_exceptionThrown
/*
@@ -7817,9 +7816,6 @@
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
b .LOP_CHECK_CAST_resolved @ pick up where we left off
-.LstrClassCastExceptionPtr:
- .word .LstrClassCastException
-
/* continuation for OP_INSTANCE_OF */
/*
@@ -10552,8 +10548,6 @@
.asciz "Ljava/lang/ArithmeticException;"
.LstrArrayStoreException:
.asciz "Ljava/lang/ArrayStoreException;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
diff --git a/vm/mterp/out/InterpAsm-armv7-a.S b/vm/mterp/out/InterpAsm-armv7-a.S
index dff7ef5..c17fe9d 100644
--- a/vm/mterp/out/InterpAsm-armv7-a.S
+++ b/vm/mterp/out/InterpAsm-armv7-a.S
@@ -7781,21 +7781,20 @@
/*
* Trivial test failed, need to perform full check. This is common.
* r0 holds obj->clazz
- * r1 holds class resolved from BBBB
+ * r1 holds desired class resolved from BBBB
* r9 holds object
*/
.LOP_CHECK_CAST_fullcheck:
+ mov r10, r1 @ avoid ClassObject getting clobbered
bl dvmInstanceofNonTrivial @ r0<- boolean result
cmp r0, #0 @ failed?
bne .LOP_CHECK_CAST_okay @ no, success
- @ A cast has failed. We need to throw a ClassCastException with the
- @ class of the object that failed to be cast.
+ @ A cast has failed. We need to throw a ClassCastException.
EXPORT_PC() @ about to throw
- ldr r3, [r9, #offObject_clazz] @ r3<- obj->clazz
- ldr r0, .LstrClassCastExceptionPtr
- ldr r1, [r3, #offClassObject_descriptor] @ r1<- obj->clazz->descriptor
- bl dvmThrowExceptionWithClassMessage
+ ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class)
+ mov r1, r10 @ r1<- desired class
+ bl dvmThrowClassCastException
b common_exceptionThrown
/*
@@ -7817,9 +7816,6 @@
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
b .LOP_CHECK_CAST_resolved @ pick up where we left off
-.LstrClassCastExceptionPtr:
- .word .LstrClassCastException
-
/* continuation for OP_INSTANCE_OF */
/*
@@ -10552,8 +10548,6 @@
.asciz "Ljava/lang/ArithmeticException;"
.LstrArrayStoreException:
.asciz "Ljava/lang/ArrayStoreException;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index c2ce035..6ddf10f 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -6556,21 +6556,20 @@
* rINST holds object
*/
.LOP_CHECK_CAST_fullcheck:
+ movl %eax,sReg0 # we'll need the desired class on failure
movl %eax,OUT_ARG1(%esp)
movl %ecx,OUT_ARG0(%esp)
- call dvmInstanceofNonTrivial # eax<- boolean result
- testl %eax,%eax # failed?
- jne .LOP_CHECK_CAST_okay # no, success
+ call dvmInstanceofNonTrivial # eax<- boolean result
+ testl %eax,%eax # failed?
+ jne .LOP_CHECK_CAST_okay # no, success
- # A cast has failed. We need to throw a ClassCastException with the
- # class of the object that failed to be cast.
+ # A cast has failed. We need to throw a ClassCastException.
EXPORT_PC
- movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz
- movl $.LstrClassCastException,%eax
- movl offClassObject_descriptor(%ecx),%ecx
- movl %eax,OUT_ARG0(%esp) # arg0<- message
- movl %ecx,OUT_ARG1(%esp) # arg1<- obj->clazz->descriptor
- call dvmThrowExceptionWithClassMessage
+ movl offObject_clazz(rINST),%eax
+ movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz
+ movl sReg0,%ecx
+ movl %ecx,OUT_ARG1(%esp) # arg1<- desired class
+ call dvmThrowClassCastException
jmp common_exceptionThrown
/*
@@ -9598,8 +9597,6 @@
.asciz "Ljava/lang/NegativeArraySizeException;"
.LstrInstantiationError:
.asciz "Ljava/lang/InstantiationError;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrNoSuchMethodError:
.asciz "Ljava/lang/NoSuchMethodError;"
.LstrInternalErrorA:
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 198d623..0379d7a 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -1616,8 +1616,7 @@
GOTO_exceptionThrown();
}
if (!dvmInstanceof(obj->clazz, clazz)) {
- dvmThrowExceptionWithClassMessage(
- "Ljava/lang/ClassCastException;", obj->clazz->descriptor);
+ dvmThrowClassCastException(obj->clazz, clazz);
GOTO_exceptionThrown();
}
}
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index e32a9ce..03b69df 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -1972,8 +1972,7 @@
GOTO_exceptionThrown();
}
if (!dvmInstanceof(obj->clazz, clazz)) {
- dvmThrowExceptionWithClassMessage(
- "Ljava/lang/ClassCastException;", obj->clazz->descriptor);
+ dvmThrowClassCastException(obj->clazz, clazz);
GOTO_exceptionThrown();
}
}
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index 6070ec3..b0adbc8 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1722,8 +1722,7 @@
GOTO_exceptionThrown();
}
if (!dvmInstanceof(obj->clazz, clazz)) {
- dvmThrowExceptionWithClassMessage(
- "Ljava/lang/ClassCastException;", obj->clazz->descriptor);
+ dvmThrowClassCastException(obj->clazz, clazz);
GOTO_exceptionThrown();
}
}
diff --git a/vm/mterp/x86-atom/TODO.txt b/vm/mterp/x86-atom/TODO.txt
index 0d50d2e..462728d 100644
--- a/vm/mterp/x86-atom/TODO.txt
+++ b/vm/mterp/x86-atom/TODO.txt
@@ -11,7 +11,8 @@
(md) Correct OP_MONITOR_EXIT (need to adjust PC before throw)
(md) OP_THROW needs to export the PC
-(md) Use dvmThrowAIOOBE(index, lentgh) for array bounds error.
+(md) Use dvmThrowAIOOBE(index, length) for array bounds errors.
+(md) Use dvmThrowClassCastException(actual, desired) for class cast errors.
(lo) Implement OP_BREAKPOINT
(lo) Implement OP_EXECUTE_INLINE_RANGE
diff --git a/vm/mterp/x86/OP_CHECK_CAST.S b/vm/mterp/x86/OP_CHECK_CAST.S
index 176dc57..6fb8415 100644
--- a/vm/mterp/x86/OP_CHECK_CAST.S
+++ b/vm/mterp/x86/OP_CHECK_CAST.S
@@ -36,21 +36,20 @@
* rINST holds object
*/
.L${opcode}_fullcheck:
+ movl %eax,sReg0 # we'll need the desired class on failure
movl %eax,OUT_ARG1(%esp)
movl %ecx,OUT_ARG0(%esp)
- call dvmInstanceofNonTrivial # eax<- boolean result
- testl %eax,%eax # failed?
- jne .L${opcode}_okay # no, success
+ call dvmInstanceofNonTrivial # eax<- boolean result
+ testl %eax,%eax # failed?
+ jne .L${opcode}_okay # no, success
- # A cast has failed. We need to throw a ClassCastException with the
- # class of the object that failed to be cast.
+ # A cast has failed. We need to throw a ClassCastException.
EXPORT_PC
- movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz
- movl $$.LstrClassCastException,%eax
- movl offClassObject_descriptor(%ecx),%ecx
- movl %eax,OUT_ARG0(%esp) # arg0<- message
- movl %ecx,OUT_ARG1(%esp) # arg1<- obj->clazz->descriptor
- call dvmThrowExceptionWithClassMessage
+ movl offObject_clazz(rINST),%eax
+ movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz
+ movl sReg0,%ecx
+ movl %ecx,OUT_ARG1(%esp) # arg1<- desired class
+ call dvmThrowClassCastException
jmp common_exceptionThrown
/*
diff --git a/vm/mterp/x86/footer.S b/vm/mterp/x86/footer.S
index fb6df27..1d63a52 100644
--- a/vm/mterp/x86/footer.S
+++ b/vm/mterp/x86/footer.S
@@ -502,8 +502,6 @@
.asciz "Ljava/lang/NegativeArraySizeException;"
.LstrInstantiationError:
.asciz "Ljava/lang/InstantiationError;"
-.LstrClassCastException:
- .asciz "Ljava/lang/ClassCastException;"
.LstrNoSuchMethodError:
.asciz "Ljava/lang/NoSuchMethodError;"
.LstrInternalErrorA: