diff options
Diffstat (limited to 'runtime/interpreter')
| -rw-r--r-- | runtime/interpreter/interpreter.cc | 13 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter_common.cc | 42 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter_common.h | 3 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter_intrinsics.cc | 1 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips/op_double_to_int.S | 20 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips/op_double_to_long.S | 15 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips/op_float_to_int.S | 19 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips/op_float_to_long.S | 14 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips64/op_double_to_int.S | 22 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips64/op_double_to_long.S | 22 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips64/op_float_to_int.S | 22 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/mips64/op_float_to_long.S | 22 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/out/mterp_mips.S | 68 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/out/mterp_mips64.S | 161 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 4 |
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( |