summaryrefslogtreecommitdiff
path: root/runtime/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter')
-rw-r--r--runtime/interpreter/interpreter.cc13
-rw-r--r--runtime/interpreter/interpreter_common.cc42
-rw-r--r--runtime/interpreter/interpreter_common.h3
-rw-r--r--runtime/interpreter/interpreter_intrinsics.cc1
-rw-r--r--runtime/interpreter/mterp/mips/op_double_to_int.S20
-rw-r--r--runtime/interpreter/mterp/mips/op_double_to_long.S15
-rw-r--r--runtime/interpreter/mterp/mips/op_float_to_int.S19
-rw-r--r--runtime/interpreter/mterp/mips/op_float_to_long.S14
-rw-r--r--runtime/interpreter/mterp/mips64/op_double_to_int.S22
-rw-r--r--runtime/interpreter/mterp/mips64/op_double_to_long.S22
-rw-r--r--runtime/interpreter/mterp/mips64/op_float_to_int.S22
-rw-r--r--runtime/interpreter/mterp/mips64/op_float_to_long.S22
-rw-r--r--runtime/interpreter/mterp/out/mterp_mips.S68
-rw-r--r--runtime/interpreter/mterp/out/mterp_mips64.S161
-rw-r--r--runtime/interpreter/unstarted_runtime.cc4
15 files changed, 161 insertions, 287 deletions
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index bf49e84760..4bc0f2fa12 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -22,15 +22,16 @@
#include "interpreter_common.h"
#include "interpreter_mterp_impl.h"
#include "interpreter_switch_impl.h"
+#include "jit/jit.h"
+#include "jit/jit_code_cache.h"
#include "jvalue-inl.h"
#include "mirror/string-inl.h"
+#include "mterp/mterp.h"
#include "scoped_thread_state_change-inl.h"
#include "ScopedLocalRef.h"
#include "stack.h"
+#include "thread-inl.h"
#include "unstarted_runtime.h"
-#include "mterp/mterp.h"
-#include "jit/jit.h"
-#include "jit/jit_code_cache.h"
namespace art {
namespace interpreter {
@@ -264,7 +265,11 @@ static inline JValue Execute(
// Pop the shadow frame before calling into compiled code.
self->PopShadowFrame();
- ArtInterpreterToCompiledCodeBridge(self, nullptr, code_item, &shadow_frame, &result);
+ // Calculate the offset of the first input reg. The input registers are in the high regs.
+ // It's ok to access the code item here since JIT code will have been touched by the
+ // interpreter and compiler already.
+ uint16_t arg_offset = code_item->registers_size_ - code_item->ins_size_;
+ ArtInterpreterToCompiledCodeBridge(self, nullptr, &shadow_frame, arg_offset, &result);
// Push the shadow frame back as the caller will expect it.
self->PushShadowFrame(&shadow_frame);
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index ef0ddb30db..d06ac23d3c 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -32,6 +32,7 @@
#include "reflection.h"
#include "reflection-inl.h"
#include "stack.h"
+#include "thread-inl.h"
#include "well_known_classes.h"
namespace art {
@@ -458,8 +459,8 @@ ALWAYS_INLINE void CopyRegisters(ShadowFrame& caller_frame,
void ArtInterpreterToCompiledCodeBridge(Thread* self,
ArtMethod* caller,
- const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame,
+ uint16_t arg_offset,
JValue* result)
REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* method = shadow_frame->GetMethod();
@@ -482,9 +483,17 @@ void ArtInterpreterToCompiledCodeBridge(Thread* self,
method = shadow_frame->GetMethod();
}
}
- uint16_t arg_offset = (code_item == nullptr)
- ? 0
- : code_item->registers_size_ - code_item->ins_size_;
+ // Basic checks for the arg_offset. If there's no code item, the arg_offset must be 0. Otherwise,
+ // check that the arg_offset isn't greater than the number of registers. A stronger check is
+ // difficult since the frame may contain space for all the registers in the method, or only enough
+ // space for the arguments.
+ if (kIsDebugBuild) {
+ if (method->GetCodeItem() == nullptr) {
+ DCHECK_EQ(0u, arg_offset) << method->PrettyMethod();
+ } else {
+ DCHECK_LE(arg_offset, shadow_frame->NumberOfVRegs());
+ }
+ }
jit::Jit* jit = Runtime::Current()->GetJit();
if (jit != nullptr && caller != nullptr) {
jit->NotifyInterpreterToCompiledCodeTransition(self, caller);
@@ -918,12 +927,23 @@ static inline bool DoCallCommon(ArtMethod* called_method,
// Compute method information.
const DexFile::CodeItem* code_item = called_method->GetCodeItem();
-
// Number of registers for the callee's call frame.
uint16_t num_regs;
+ // Test whether to use the interpreter or compiler entrypoint, and save that result to pass to
+ // PerformCall. A deoptimization could occur at any time, and we shouldn't change which
+ // entrypoint to use once we start building the shadow frame.
+ bool use_interpreter_entrypoint = ClassLinker::ShouldUseInterpreterEntrypoint(
+ called_method, called_method->GetEntryPointFromQuickCompiledCode());
if (LIKELY(code_item != nullptr)) {
- num_regs = code_item->registers_size_;
- DCHECK_EQ(string_init ? number_of_inputs - 1 : number_of_inputs, code_item->ins_size_);
+ // When transitioning to compiled code, space only needs to be reserved for the input registers.
+ // The rest of the frame gets discarded. This also prevents accessing the called method's code
+ // item, saving memory by keeping code items of compiled code untouched.
+ if (Runtime::Current()->IsStarted() && !use_interpreter_entrypoint) {
+ num_regs = number_of_inputs;
+ } else {
+ num_regs = code_item->registers_size_;
+ DCHECK_EQ(string_init ? number_of_inputs - 1 : number_of_inputs, code_item->ins_size_);
+ }
} else {
DCHECK(called_method->IsNative() || called_method->IsProxyMethod());
num_regs = number_of_inputs;
@@ -1077,7 +1097,13 @@ static inline bool DoCallCommon(ArtMethod* called_method,
self->EndAssertNoThreadSuspension(old_cause);
}
- PerformCall(self, code_item, shadow_frame.GetMethod(), first_dest_reg, new_shadow_frame, result);
+ PerformCall(self,
+ code_item,
+ shadow_frame.GetMethod(),
+ first_dest_reg,
+ new_shadow_frame,
+ result,
+ use_interpreter_entrypoint);
if (string_init && !self->IsExceptionPending()) {
SetStringInitValueToAllAliases(&shadow_frame, string_init_vreg_this, *result);
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index fdc0505e7f..38edc7a9e7 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -527,10 +527,11 @@ static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFra
}
}
+// The arg_offset is the offset to the first input register in the frame.
void ArtInterpreterToCompiledCodeBridge(Thread* self,
ArtMethod* caller,
- const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame,
+ uint16_t arg_offset,
JValue* result);
// Set string value created from StringFactory.newStringFromXXX() into all aliases of
diff --git a/runtime/interpreter/interpreter_intrinsics.cc b/runtime/interpreter/interpreter_intrinsics.cc
index 869d43061b..74e6cd297d 100644
--- a/runtime/interpreter/interpreter_intrinsics.cc
+++ b/runtime/interpreter/interpreter_intrinsics.cc
@@ -469,6 +469,7 @@ bool MterpHandleIntrinsic(ShadowFrame* shadow_frame,
UNIMPLEMENTED_CASE(UnsafeFullFence /* ()V */)
UNIMPLEMENTED_CASE(ReferenceGetReferent /* ()Ljava/lang/Object; */)
UNIMPLEMENTED_CASE(IntegerValueOf /* (I)Ljava/lang/Integer; */)
+ UNIMPLEMENTED_CASE(ThreadInterrupted /* ()Z */)
case Intrinsics::kNone:
res = false;
break;
diff --git a/runtime/interpreter/mterp/mips/op_double_to_int.S b/runtime/interpreter/mterp/mips/op_double_to_int.S
index 3b44964333..6d7c6cae61 100644
--- a/runtime/interpreter/mterp/mips/op_double_to_int.S
+++ b/runtime/interpreter/mterp/mips/op_double_to_int.S
@@ -3,7 +3,8 @@
*
* We have to clip values to int min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPB(a3) # a3 <- B
@@ -11,29 +12,20 @@
EAS2(a3, rFP, a3) # a3 <- &fp[B]
LOAD64_F(fa0, fa0f, a3)
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
+#ifndef MIPS32REVGE6
li t0, INT_MIN_AS_DOUBLE_HIGH
mtc1 zero, fa1
MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
-#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- cmp.le.d ft0, fa1, fa0
- GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if INT_MIN <= vB, proceed to truncation
- cmp.eq.d ft0, fa0, fa0
- selnez.d fa0, fa1, ft0 # fa0 = ordered(vB) ? INT_MIN_AS_DOUBLE : 0
-#else
c.ole.d fcc0, fa1, fa0
+#endif
GET_INST_OPCODE(t1) # extract opcode from rINST
+#ifndef MIPS32REVGE6
bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
c.eq.d fcc0, fa0, fa0
mtc1 zero, fa0
MOVE_TO_FPU_HIGH(zero, fa0, fa0f)
movt.d fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_DOUBLE : 0
-#endif
1:
+#endif
trunc.w.d fa0, fa0
SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
diff --git a/runtime/interpreter/mterp/mips/op_double_to_long.S b/runtime/interpreter/mterp/mips/op_double_to_long.S
index 78d4a8f5c7..459ab7eed0 100644
--- a/runtime/interpreter/mterp/mips/op_double_to_long.S
+++ b/runtime/interpreter/mterp/mips/op_double_to_long.S
@@ -3,7 +3,8 @@
*
* We have to clip values to long min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPA4(rOBJ) # rOBJ <- A+
@@ -13,19 +14,7 @@
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- li t0, LONG_MIN_AS_DOUBLE_HIGH
- mtc1 zero, fa1
- mthc1 t0, fa1
- cmp.le.d ft0, fa1, fa0
GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if LONG_MIN <= vB, proceed to truncation
- cmp.eq.d ft0, fa0, fa0
- selnez.d fa0, fa1, ft0 # fa0 = ordered(vB) ? LONG_MIN_AS_DOUBLE : 0
-1:
trunc.l.d fa0, fa0
SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
#else
diff --git a/runtime/interpreter/mterp/mips/op_float_to_int.S b/runtime/interpreter/mterp/mips/op_float_to_int.S
index 087e50fe80..26a0988082 100644
--- a/runtime/interpreter/mterp/mips/op_float_to_int.S
+++ b/runtime/interpreter/mterp/mips/op_float_to_int.S
@@ -3,7 +3,8 @@
*
* We have to clip values to int min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPB(a3) # a3 <- B
@@ -11,26 +12,18 @@
GET_VREG_F(fa0, a3)
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+#ifndef MIPS32REVGE6
li t0, INT_MIN_AS_FLOAT
mtc1 t0, fa1
-#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- cmp.le.s ft0, fa1, fa0
- GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if INT_MIN <= vB, proceed to truncation
- cmp.eq.s ft0, fa0, fa0
- selnez.s fa0, fa1, ft0 # fa0 = ordered(vB) ? INT_MIN_AS_FLOAT : 0
-#else
c.ole.s fcc0, fa1, fa0
+#endif
GET_INST_OPCODE(t1) # extract opcode from rINST
+#ifndef MIPS32REVGE6
bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
c.eq.s fcc0, fa0, fa0
mtc1 zero, fa0
movt.s fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_FLOAT : 0
-#endif
1:
+#endif
trunc.w.s fa0, fa0
SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
diff --git a/runtime/interpreter/mterp/mips/op_float_to_long.S b/runtime/interpreter/mterp/mips/op_float_to_long.S
index dc88a78e7a..b8f8efbdcb 100644
--- a/runtime/interpreter/mterp/mips/op_float_to_long.S
+++ b/runtime/interpreter/mterp/mips/op_float_to_long.S
@@ -3,7 +3,8 @@
*
* We have to clip values to long min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPA4(rOBJ) # rOBJ <- A+
@@ -12,18 +13,7 @@
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- li t0, LONG_MIN_AS_FLOAT
- mtc1 t0, fa1
- cmp.le.s ft0, fa1, fa0
GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if LONG_MIN <= vB, proceed to truncation
- cmp.eq.s ft0, fa0, fa0
- selnez.s fa0, fa1, ft0 # fa0 = ordered(vB) ? LONG_MIN_AS_FLOAT : 0
-1:
trunc.l.s fa0, fa0
SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
#else
diff --git a/runtime/interpreter/mterp/mips64/op_double_to_int.S b/runtime/interpreter/mterp/mips64/op_double_to_int.S
index aa2cbcad38..d09952233c 100644
--- a/runtime/interpreter/mterp/mips64/op_double_to_int.S
+++ b/runtime/interpreter/mterp/mips64/op_double_to_int.S
@@ -1,23 +1,3 @@
%include "mips64/fcvtHeader.S" { "suffix":"_DOUBLE", "valreg":"f0" }
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- dli t0, INT_MIN_AS_DOUBLE
- dmtc1 t0, f1
- cmp.le.d f1, f1, f0
- bc1nez f1, .L${opcode}_trunc
- cmp.eq.d f1, f0, f0
- li t0, INT_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .L${opcode}_done
-%break
-.L${opcode}_trunc:
trunc.w.d f0, f0
- mfc1 t0, f0
-.L${opcode}_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG t0, a1
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/fcvtFooter.S" { "suffix":"_FLOAT", "valreg":"f0" }
diff --git a/runtime/interpreter/mterp/mips64/op_double_to_long.S b/runtime/interpreter/mterp/mips64/op_double_to_long.S
index 777cfeb6c8..9b65da5602 100644
--- a/runtime/interpreter/mterp/mips64/op_double_to_long.S
+++ b/runtime/interpreter/mterp/mips64/op_double_to_long.S
@@ -1,23 +1,3 @@
%include "mips64/fcvtHeader.S" { "suffix":"_DOUBLE", "valreg":"f0" }
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- dli t0, LONG_MIN_AS_DOUBLE
- dmtc1 t0, f1
- cmp.le.d f1, f1, f0
- bc1nez f1, .L${opcode}_trunc
- cmp.eq.d f1, f0, f0
- dli t0, LONG_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .L${opcode}_done
-%break
-.L${opcode}_trunc:
trunc.l.d f0, f0
- dmfc1 t0, f0
-.L${opcode}_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE t0, a1
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/fcvtFooter.S" { "suffix":"_DOUBLE", "valreg":"f0" }
diff --git a/runtime/interpreter/mterp/mips64/op_float_to_int.S b/runtime/interpreter/mterp/mips64/op_float_to_int.S
index d957540a7b..2806973935 100644
--- a/runtime/interpreter/mterp/mips64/op_float_to_int.S
+++ b/runtime/interpreter/mterp/mips64/op_float_to_int.S
@@ -1,23 +1,3 @@
%include "mips64/fcvtHeader.S" { "suffix":"_FLOAT", "valreg":"f0" }
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- li t0, INT_MIN_AS_FLOAT
- mtc1 t0, f1
- cmp.le.s f1, f1, f0
- bc1nez f1, .L${opcode}_trunc
- cmp.eq.s f1, f0, f0
- li t0, INT_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .L${opcode}_done
-%break
-.L${opcode}_trunc:
trunc.w.s f0, f0
- mfc1 t0, f0
-.L${opcode}_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG t0, a1
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/fcvtFooter.S" { "suffix":"_FLOAT", "valreg":"f0" }
diff --git a/runtime/interpreter/mterp/mips64/op_float_to_long.S b/runtime/interpreter/mterp/mips64/op_float_to_long.S
index 5d036c8455..c40c8a6680 100644
--- a/runtime/interpreter/mterp/mips64/op_float_to_long.S
+++ b/runtime/interpreter/mterp/mips64/op_float_to_long.S
@@ -1,23 +1,3 @@
%include "mips64/fcvtHeader.S" { "suffix":"_FLOAT", "valreg":"f0" }
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- li t0, LONG_MIN_AS_FLOAT
- mtc1 t0, f1
- cmp.le.s f1, f1, f0
- bc1nez f1, .L${opcode}_trunc
- cmp.eq.s f1, f0, f0
- dli t0, LONG_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .L${opcode}_done
-%break
-.L${opcode}_trunc:
trunc.l.s f0, f0
- dmfc1 t0, f0
-.L${opcode}_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE t0, a1
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/fcvtFooter.S" { "suffix":"_DOUBLE", "valreg":"f0" }
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index 579afc2387..636289798c 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -3967,7 +3967,8 @@ artMterpAsmInstructionStart = .L_op_nop
*
* We have to clip values to int min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPB(a3) # a3 <- B
@@ -3975,27 +3976,19 @@ artMterpAsmInstructionStart = .L_op_nop
GET_VREG_F(fa0, a3)
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
+#ifndef MIPS32REVGE6
li t0, INT_MIN_AS_FLOAT
mtc1 t0, fa1
-#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- cmp.le.s ft0, fa1, fa0
- GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if INT_MIN <= vB, proceed to truncation
- cmp.eq.s ft0, fa0, fa0
- selnez.s fa0, fa1, ft0 # fa0 = ordered(vB) ? INT_MIN_AS_FLOAT : 0
-#else
c.ole.s fcc0, fa1, fa0
+#endif
GET_INST_OPCODE(t1) # extract opcode from rINST
+#ifndef MIPS32REVGE6
bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
c.eq.s fcc0, fa0, fa0
mtc1 zero, fa0
movt.s fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_FLOAT : 0
-#endif
1:
+#endif
trunc.w.s fa0, fa0
SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
@@ -4008,7 +4001,8 @@ artMterpAsmInstructionStart = .L_op_nop
*
* We have to clip values to long min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPA4(rOBJ) # rOBJ <- A+
@@ -4017,18 +4011,7 @@ artMterpAsmInstructionStart = .L_op_nop
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- li t0, LONG_MIN_AS_FLOAT
- mtc1 t0, fa1
- cmp.le.s ft0, fa1, fa0
GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if LONG_MIN <= vB, proceed to truncation
- cmp.eq.s ft0, fa0, fa0
- selnez.s fa0, fa1, ft0 # fa0 = ordered(vB) ? LONG_MIN_AS_FLOAT : 0
-1:
trunc.l.s fa0, fa0
SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
#else
@@ -4084,7 +4067,8 @@ artMterpAsmInstructionStart = .L_op_nop
*
* We have to clip values to int min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPB(a3) # a3 <- B
@@ -4092,30 +4076,21 @@ artMterpAsmInstructionStart = .L_op_nop
EAS2(a3, rFP, a3) # a3 <- &fp[B]
LOAD64_F(fa0, fa0f, a3)
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
-
+#ifndef MIPS32REVGE6
li t0, INT_MIN_AS_DOUBLE_HIGH
mtc1 zero, fa1
MOVE_TO_FPU_HIGH(t0, fa1, fa1f)
-#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- cmp.le.d ft0, fa1, fa0
- GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if INT_MIN <= vB, proceed to truncation
- cmp.eq.d ft0, fa0, fa0
- selnez.d fa0, fa1, ft0 # fa0 = ordered(vB) ? INT_MIN_AS_DOUBLE : 0
-#else
c.ole.d fcc0, fa1, fa0
+#endif
GET_INST_OPCODE(t1) # extract opcode from rINST
+#ifndef MIPS32REVGE6
bc1t fcc0, 1f # if INT_MIN <= vB, proceed to truncation
c.eq.d fcc0, fa0, fa0
mtc1 zero, fa0
MOVE_TO_FPU_HIGH(zero, fa0, fa0f)
movt.d fa0, fa1, fcc0 # fa0 = ordered(vB) ? INT_MIN_AS_DOUBLE : 0
-#endif
1:
+#endif
trunc.w.d fa0, fa0
SET_VREG_F_GOTO(fa0, rOBJ, t1) # vA <- result
@@ -4128,7 +4103,8 @@ artMterpAsmInstructionStart = .L_op_nop
*
* We have to clip values to long min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
- * to modest integer. The EABI convert function isn't doing this for us.
+ * to modest integer. The EABI convert function isn't doing this for us
+ * for pre-R6.
*/
/* unop vA, vB */
GET_OPA4(rOBJ) # rOBJ <- A+
@@ -4138,19 +4114,7 @@ artMterpAsmInstructionStart = .L_op_nop
FETCH_ADVANCE_INST(1) # advance rPC, load rINST
#ifdef MIPS32REVGE6
- /*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
- */
- li t0, LONG_MIN_AS_DOUBLE_HIGH
- mtc1 zero, fa1
- mthc1 t0, fa1
- cmp.le.d ft0, fa1, fa0
GET_INST_OPCODE(t1) # extract opcode from rINST
- bc1nez ft0, 1f # if LONG_MIN <= vB, proceed to truncation
- cmp.eq.d ft0, fa0, fa0
- selnez.d fa0, fa1, ft0 # fa0 = ordered(vB) ? LONG_MIN_AS_DOUBLE : 0
-1:
trunc.l.d fa0, fa0
SET_VREG64_F_GOTO(fa0, fa0f, rOBJ, t1) # vA <- result
#else
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index 3656df9a8e..bc0d90c7cb 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -3699,19 +3699,27 @@ artMterpAsmInstructionStart = .L_op_nop
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ trunc.w.s f0, f0
+/* File: mips64/fcvtFooter.S */
/*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
+ * Stores a specified register containing the result of conversion
+ * from or to a floating-point type and jumps to the next instruction.
+ *
+ * Expects a1 to contain the destination Dalvik register number.
+ * a1 is set up by fcvtHeader.S.
+ *
+ * For: int-to-float, int-to-double, long-to-float, long-to-double,
+ * float-to-int, float-to-long, float-to-double, double-to-int,
+ * double-to-long, double-to-float, neg-float, neg-double.
+ *
+ * Note that this file can't be included after a break in other files
+ * and in those files its contents appear as a copy.
+ * See: float-to-int, float-to-long, double-to-int, double-to-long.
*/
- li t0, INT_MIN_AS_FLOAT
- mtc1 t0, f1
- cmp.le.s f1, f1, f0
- bc1nez f1, .Lop_float_to_int_trunc
- cmp.eq.s f1, f0, f0
- li t0, INT_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .Lop_float_to_int_done
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_FLOAT f0, a1
+ GOTO_OPCODE v0 # jump to next instruction
+
/* ------------------------------ */
.balign 128
@@ -3734,19 +3742,28 @@ artMterpAsmInstructionStart = .L_op_nop
GET_VREG_FLOAT f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ trunc.l.s f0, f0
+/* File: mips64/fcvtFooter.S */
/*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
+ * Stores a specified register containing the result of conversion
+ * from or to a floating-point type and jumps to the next instruction.
+ *
+ * Expects a1 to contain the destination Dalvik register number.
+ * a1 is set up by fcvtHeader.S.
+ *
+ * For: int-to-float, int-to-double, long-to-float, long-to-double,
+ * float-to-int, float-to-long, float-to-double, double-to-int,
+ * double-to-long, double-to-float, neg-float, neg-double.
+ *
+ * Note that this file can't be included after a break in other files
+ * and in those files its contents appear as a copy.
+ * See: float-to-int, float-to-long, double-to-int, double-to-long.
*/
- li t0, LONG_MIN_AS_FLOAT
- mtc1 t0, f1
- cmp.le.s f1, f1, f0
- bc1nez f1, .Lop_float_to_long_trunc
- cmp.eq.s f1, f0, f0
- dli t0, LONG_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .Lop_float_to_long_done
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_DOUBLE f0, a1
+ GOTO_OPCODE v0 # jump to next instruction
+
+
/* ------------------------------ */
.balign 128
@@ -3817,19 +3834,27 @@ artMterpAsmInstructionStart = .L_op_nop
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ trunc.w.d f0, f0
+/* File: mips64/fcvtFooter.S */
/*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
+ * Stores a specified register containing the result of conversion
+ * from or to a floating-point type and jumps to the next instruction.
+ *
+ * Expects a1 to contain the destination Dalvik register number.
+ * a1 is set up by fcvtHeader.S.
+ *
+ * For: int-to-float, int-to-double, long-to-float, long-to-double,
+ * float-to-int, float-to-long, float-to-double, double-to-int,
+ * double-to-long, double-to-float, neg-float, neg-double.
+ *
+ * Note that this file can't be included after a break in other files
+ * and in those files its contents appear as a copy.
+ * See: float-to-int, float-to-long, double-to-int, double-to-long.
*/
- dli t0, INT_MIN_AS_DOUBLE
- dmtc1 t0, f1
- cmp.le.d f1, f1, f0
- bc1nez f1, .Lop_double_to_int_trunc
- cmp.eq.d f1, f0, f0
- li t0, INT_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .Lop_double_to_int_done
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_FLOAT f0, a1
+ GOTO_OPCODE v0 # jump to next instruction
+
/* ------------------------------ */
.balign 128
@@ -3852,19 +3877,27 @@ artMterpAsmInstructionStart = .L_op_nop
GET_VREG_DOUBLE f0, a2
FETCH_ADVANCE_INST 1 # advance rPC, load rINST
+ trunc.l.d f0, f0
+/* File: mips64/fcvtFooter.S */
/*
- * TODO: simplify this when the MIPS64R6 emulator
- * supports NAN2008=1.
+ * Stores a specified register containing the result of conversion
+ * from or to a floating-point type and jumps to the next instruction.
+ *
+ * Expects a1 to contain the destination Dalvik register number.
+ * a1 is set up by fcvtHeader.S.
+ *
+ * For: int-to-float, int-to-double, long-to-float, long-to-double,
+ * float-to-int, float-to-long, float-to-double, double-to-int,
+ * double-to-long, double-to-float, neg-float, neg-double.
+ *
+ * Note that this file can't be included after a break in other files
+ * and in those files its contents appear as a copy.
+ * See: float-to-int, float-to-long, double-to-int, double-to-long.
*/
- dli t0, LONG_MIN_AS_DOUBLE
- dmtc1 t0, f1
- cmp.le.d f1, f1, f0
- bc1nez f1, .Lop_double_to_long_trunc
- cmp.eq.d f1, f0, f0
- dli t0, LONG_MIN
- mfc1 t1, f1
- and t0, t0, t1
- b .Lop_double_to_long_done
+ GET_INST_OPCODE v0 # extract opcode from rINST
+ SET_VREG_DOUBLE f0, a1
+ GOTO_OPCODE v0 # jump to next instruction
+
/* ------------------------------ */
.balign 128
@@ -7132,46 +7165,6 @@ artMterpAsmInstructionEnd:
.balign 4
artMterpAsmSisterStart:
-/* continuation for op_float_to_int */
-.Lop_float_to_int_trunc:
- trunc.w.s f0, f0
- mfc1 t0, f0
-.Lop_float_to_int_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG t0, a1
- GOTO_OPCODE v0 # jump to next instruction
-
-/* continuation for op_float_to_long */
-.Lop_float_to_long_trunc:
- trunc.l.s f0, f0
- dmfc1 t0, f0
-.Lop_float_to_long_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE t0, a1
- GOTO_OPCODE v0 # jump to next instruction
-
-/* continuation for op_double_to_int */
-.Lop_double_to_int_trunc:
- trunc.w.d f0, f0
- mfc1 t0, f0
-.Lop_double_to_int_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG t0, a1
- GOTO_OPCODE v0 # jump to next instruction
-
-/* continuation for op_double_to_long */
-.Lop_double_to_long_trunc:
- trunc.l.d f0, f0
- dmfc1 t0, f0
-.Lop_double_to_long_done:
- /* Can't include fcvtFooter.S after break */
- GET_INST_OPCODE v0 # extract opcode from rINST
- SET_VREG_WIDE t0, a1
- GOTO_OPCODE v0 # jump to next instruction
-
.size artMterpAsmSisterStart, .-artMterpAsmSisterStart
.global artMterpAsmSisterEnd
artMterpAsmSisterEnd:
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 70be30c22c..152cce4c60 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -50,7 +50,7 @@
#include "mirror/string-inl.h"
#include "nth_caller_visitor.h"
#include "reflection.h"
-#include "thread.h"
+#include "thread-inl.h"
#include "transaction.h"
#include "well_known_classes.h"
#include "zip_archive.h"
@@ -568,7 +568,7 @@ static void GetResourceAsStream(Thread* self,
// Copy in content.
memcpy(h_array->GetData(), mem_map->Begin(), map_size);
// Be proactive releasing memory.
- mem_map.release();
+ mem_map.reset();
// Create a ByteArrayInputStream.
Handle<mirror::Class> h_class(hs.NewHandle(