| Index: src/mips/code-stubs-mips.cc
|
| diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
|
| index dd4e7c12fa3beb690199437613d73f790753072b..bb009218db07bc33f3bbc94fb9eeeea56bb19b26 100644
|
| --- a/src/mips/code-stubs-mips.cc
|
| +++ b/src/mips/code-stubs-mips.cc
|
| @@ -1472,7 +1472,7 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
|
| scratch1,
|
| Heap::kHeapNumberMapRootIndex,
|
| not_found,
|
| - true);
|
| + DONT_DO_SMI_CHECK);
|
|
|
| STATIC_ASSERT(8 == kDoubleSize);
|
| __ Addu(scratch1,
|
| @@ -1736,12 +1736,33 @@ void CompareStub::Generate(MacroAssembler* masm) {
|
| // The stub returns zero for false, and a non-zero value for true.
|
| void ToBooleanStub::Generate(MacroAssembler* masm) {
|
| // This stub uses FPU instructions.
|
| - ASSERT(CpuFeatures::IsEnabled(FPU));
|
| + CpuFeatures::Scope scope(FPU);
|
|
|
| Label false_result;
|
| Label not_heap_number;
|
| Register scratch0 = t5.is(tos_) ? t3 : t5;
|
|
|
| + // undefined -> false
|
| + __ LoadRoot(scratch0, Heap::kUndefinedValueRootIndex);
|
| + __ Branch(&false_result, eq, tos_, Operand(scratch0));
|
| +
|
| + // Boolean -> its value
|
| + __ LoadRoot(scratch0, Heap::kFalseValueRootIndex);
|
| + __ Branch(&false_result, eq, tos_, Operand(scratch0));
|
| + __ LoadRoot(scratch0, Heap::kTrueValueRootIndex);
|
| + // "tos_" is a register and contains a non-zero value. Hence we implicitly
|
| + // return true if the equal condition is satisfied.
|
| + __ Ret(eq, tos_, Operand(scratch0));
|
| +
|
| + // Smis: 0 -> false, all other -> true
|
| + __ And(scratch0, tos_, tos_);
|
| + __ Branch(&false_result, eq, scratch0, Operand(zero_reg));
|
| + __ And(scratch0, tos_, Operand(kSmiTagMask));
|
| + // "tos_" is a register and contains a non-zero value. Hence we implicitly
|
| + // return true if the not equal condition is satisfied.
|
| + __ Ret(eq, scratch0, Operand(zero_reg));
|
| +
|
| + // 'null' -> false
|
| __ LoadRoot(scratch0, Heap::kNullValueRootIndex);
|
| __ Branch(&false_result, eq, tos_, Operand(scratch0));
|
|
|
| @@ -1750,8 +1771,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
|
| __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
|
| __ Branch(¬_heap_number, ne, scratch0, Operand(at));
|
|
|
| - __ Subu(at, tos_, Operand(kHeapObjectTag));
|
| - __ ldc1(f12, MemOperand(at, HeapNumber::kValueOffset));
|
| + __ ldc1(f12, FieldMemOperand(tos_, HeapNumber::kValueOffset));
|
| __ fcmp(f12, 0.0, UEQ);
|
|
|
| // "tos_" is a register, and contains a non zero value by default.
|
| @@ -1762,11 +1782,6 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
|
|
|
| __ bind(¬_heap_number);
|
|
|
| - // Check if the value is 'null'.
|
| - // 'null' => false.
|
| - __ LoadRoot(at, Heap::kNullValueRootIndex);
|
| - __ Branch(&false_result, eq, tos_, Operand(at));
|
| -
|
| // It can be an undetectable object.
|
| // Undetectable => false.
|
| __ lw(at, FieldMemOperand(tos_, HeapObject::kMapOffset));
|
| @@ -1944,12 +1959,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
|
|
|
|
|
| void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
|
| - Label non_smi, slow;
|
| - GenerateSmiCodeSub(masm, &non_smi, &slow);
|
| + Label non_smi, slow, call_builtin;
|
| + GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
|
| __ bind(&non_smi);
|
| GenerateHeapNumberCodeSub(masm, &slow);
|
| __ bind(&slow);
|
| GenerateTypeTransition(masm);
|
| + __ bind(&call_builtin);
|
| + GenerateGenericCodeFallback(masm);
|
| }
|
|
|
|
|
| @@ -3185,7 +3202,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
|
| a1,
|
| Heap::kHeapNumberMapRootIndex,
|
| &calculate,
|
| - true);
|
| + DONT_DO_SMI_CHECK);
|
| // Input is a HeapNumber. Store the
|
| // low and high words into a2, a3.
|
| __ lw(a2, FieldMemOperand(a0, HeapNumber::kValueOffset));
|
| @@ -3764,16 +3781,21 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| // If this is the outermost JS call, set js_entry_sp value.
|
| + Label non_outermost_js;
|
| ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
|
| masm->isolate());
|
| __ li(t1, Operand(ExternalReference(js_entry_sp)));
|
| __ lw(t2, MemOperand(t1));
|
| - {
|
| - Label skip;
|
| - __ Branch(&skip, ne, t2, Operand(zero_reg));
|
| - __ sw(fp, MemOperand(t1));
|
| - __ bind(&skip);
|
| - }
|
| + __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
|
| + __ sw(fp, MemOperand(t1));
|
| + __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
|
| + Label cont;
|
| + __ b(&cont);
|
| + __ nop(); // Branch delay slot nop.
|
| + __ bind(&non_outermost_js);
|
| + __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
|
| + __ bind(&cont);
|
| + __ push(t0);
|
| #endif
|
|
|
| // Call a faked try-block that does the invoke.
|
| @@ -3839,32 +3861,21 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
| __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
|
| __ Call(t9);
|
|
|
| - // Unlink this frame from the handler chain. When reading the
|
| - // address of the next handler, there is no need to use the address
|
| - // displacement since the current stack pointer (sp) points directly
|
| - // to the stack handler.
|
| - __ lw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
|
| - __ li(t0, Operand(ExternalReference(Isolate::k_handler_address,
|
| - masm->isolate())));
|
| - __ sw(t1, MemOperand(t0));
|
| + // Unlink this frame from the handler chain.
|
| + __ PopTryHandler();
|
|
|
| - // This restores sp to its position before PushTryHandler.
|
| - __ addiu(sp, sp, StackHandlerConstants::kSize);
|
| -
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| - // If current FP value is the same as js_entry_sp value, it means that
|
| - // the current function is the outermost.
|
| - __ li(t1, Operand(ExternalReference(js_entry_sp)));
|
| - __ lw(t2, MemOperand(t1));
|
| - {
|
| - Label skip;
|
| - __ Branch(&skip, ne, fp, Operand(t2));
|
| + __ bind(&exit); // v0 holds result
|
| + #ifdef ENABLE_LOGGING_AND_PROFILING
|
| + // Check if the current stack frame is marked as the outermost JS frame.
|
| + Label non_outermost_js_2;
|
| + __ pop(t1);
|
| + __ Branch(&non_outermost_js_2, ne, t1,
|
| + Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
|
| + __ li(t1, Operand(ExternalReference(js_entry_sp)));
|
| __ sw(zero_reg, MemOperand(t1));
|
| - __ bind(&skip);
|
| - }
|
| -#endif
|
| + __ bind(&non_outermost_js_2);
|
| + #endif
|
|
|
| - __ bind(&exit); // v0 holds result.
|
| // Restore the top frame descriptors from the stack.
|
| __ pop(t1);
|
| __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address,
|
| @@ -4846,7 +4857,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
|
| scratch_,
|
| Heap::kHeapNumberMapRootIndex,
|
| index_not_number_,
|
| - true);
|
| + DONT_DO_SMI_CHECK);
|
| call_helper.BeforeCall(masm);
|
| // Consumed by runtime conversion function:
|
| __ Push(object_, index_, index_);
|
|
|