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_); |