| 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 {
|
|
|