Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index 598bf1731ea3ebfdafa0fcd1d4bd2f0550295fd7..4a2f3303f652e67bb4ef60e0c26d288a62e4dff0 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -180,6 +180,18 @@ void CompareNilICStub::InitializeInterfaceDescriptor( |
ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate)); |
} |
+void ToBooleanStub::InitializeInterfaceDescriptor( |
+ Isolate* isolate, |
+ CodeStubInterfaceDescriptor* descriptor) { |
+ static Register registers[] = { eax }; |
+ descriptor->register_param_count_ = 1; |
+ descriptor->register_params_ = registers; |
+ descriptor->deoptimization_handler_ = |
+ FUNCTION_ADDR(ToBooleanIC_Miss); |
+ descriptor->SetMissHandler( |
+ ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate)); |
+} |
+ |
#define __ ACCESS_MASM(masm) |
@@ -469,116 +481,6 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) { |
} |
-// The stub expects its argument on the stack and returns its result in tos_: |
-// zero for false, and a non-zero value for true. |
-void ToBooleanStub::Generate(MacroAssembler* masm) { |
- // This stub overrides SometimesSetsUpAFrame() to return false. That means |
- // we cannot call anything that could cause a GC from this stub. |
- Label patch; |
- Factory* factory = masm->isolate()->factory(); |
- const Register argument = eax; |
- const Register map = edx; |
- |
- if (!types_.IsEmpty()) { |
- __ mov(argument, Operand(esp, 1 * kPointerSize)); |
- } |
- |
- // undefined -> false |
- CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false); |
- |
- // Boolean -> its value |
- CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false); |
- CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true); |
- |
- // 'null' -> false. |
- CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false); |
- |
- if (types_.Contains(SMI)) { |
- // Smis: 0 -> false, all other -> true |
- Label not_smi; |
- __ JumpIfNotSmi(argument, ¬_smi, Label::kNear); |
- // argument contains the correct return value already. |
- if (!tos_.is(argument)) { |
- __ mov(tos_, argument); |
- } |
- __ ret(1 * kPointerSize); |
- __ bind(¬_smi); |
- } else if (types_.NeedsMap()) { |
- // If we need a map later and have a Smi -> patch. |
- __ JumpIfSmi(argument, &patch, Label::kNear); |
- } |
- |
- if (types_.NeedsMap()) { |
- __ mov(map, FieldOperand(argument, HeapObject::kMapOffset)); |
- |
- if (types_.CanBeUndetectable()) { |
- __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
- 1 << Map::kIsUndetectable); |
- // Undetectable -> false. |
- Label not_undetectable; |
- __ j(zero, ¬_undetectable, Label::kNear); |
- __ Set(tos_, Immediate(0)); |
- __ ret(1 * kPointerSize); |
- __ bind(¬_undetectable); |
- } |
- } |
- |
- if (types_.Contains(SPEC_OBJECT)) { |
- // spec object -> true. |
- Label not_js_object; |
- __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); |
- __ j(below, ¬_js_object, Label::kNear); |
- // argument contains the correct return value already. |
- if (!tos_.is(argument)) { |
- __ Set(tos_, Immediate(1)); |
- } |
- __ ret(1 * kPointerSize); |
- __ bind(¬_js_object); |
- } |
- |
- if (types_.Contains(STRING)) { |
- // String value -> false iff empty. |
- Label not_string; |
- __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); |
- __ j(above_equal, ¬_string, Label::kNear); |
- __ mov(tos_, FieldOperand(argument, String::kLengthOffset)); |
- __ ret(1 * kPointerSize); // the string length is OK as the return value |
- __ bind(¬_string); |
- } |
- |
- if (types_.Contains(SYMBOL)) { |
- // Symbol value -> true. |
- Label not_symbol; |
- __ CmpInstanceType(map, SYMBOL_TYPE); |
- __ j(not_equal, ¬_symbol, Label::kNear); |
- __ bind(¬_symbol); |
- } |
- |
- if (types_.Contains(HEAP_NUMBER)) { |
- // heap number -> false iff +0, -0, or NaN. |
- Label not_heap_number, false_result; |
- __ cmp(map, factory->heap_number_map()); |
- __ j(not_equal, ¬_heap_number, Label::kNear); |
- __ fldz(); |
- __ fld_d(FieldOperand(argument, HeapNumber::kValueOffset)); |
- __ FCmp(); |
- __ j(zero, &false_result, Label::kNear); |
- // argument contains the correct return value already. |
- if (!tos_.is(argument)) { |
- __ Set(tos_, Immediate(1)); |
- } |
- __ ret(1 * kPointerSize); |
- __ bind(&false_result); |
- __ Set(tos_, Immediate(0)); |
- __ ret(1 * kPointerSize); |
- __ bind(¬_heap_number); |
- } |
- |
- __ bind(&patch); |
- GenerateTypeTransition(masm); |
-} |
- |
- |
void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
// We don't allow a GC during a store buffer overflow so there is no need to |
// store the registers in any particular way, but we do have to store and |
@@ -614,44 +516,6 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
} |
-void ToBooleanStub::CheckOddball(MacroAssembler* masm, |
- Type type, |
- Heap::RootListIndex value, |
- bool result) { |
- const Register argument = eax; |
- if (types_.Contains(type)) { |
- // If we see an expected oddball, return its ToBoolean value tos_. |
- Label different_value; |
- __ CompareRoot(argument, value); |
- __ j(not_equal, &different_value, Label::kNear); |
- if (!result) { |
- // If we have to return zero, there is no way around clearing tos_. |
- __ Set(tos_, Immediate(0)); |
- } else if (!tos_.is(argument)) { |
- // If we have to return non-zero, we can re-use the argument if it is the |
- // same register as the result, because we never see Smi-zero here. |
- __ Set(tos_, Immediate(1)); |
- } |
- __ ret(1 * kPointerSize); |
- __ bind(&different_value); |
- } |
-} |
- |
- |
-void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) { |
- __ pop(ecx); // Get return address, operand is now on top of stack. |
- __ push(Immediate(Smi::FromInt(tos_.code()))); |
- __ push(Immediate(Smi::FromInt(types_.ToByte()))); |
- __ push(ecx); // Push return address. |
- // Patch the caller to an appropriate specialized stub and return the |
- // operation result to the caller of the stub. |
- __ TailCallExternalReference( |
- ExternalReference(IC_Utility(IC::kToBoolean_Patch), masm->isolate()), |
- 3, |
- 1); |
-} |
- |
- |
class FloatingPointHelper : public AllStatic { |
public: |
enum ArgLocation { |