Author: erik.co...@gmail.com Date: Wed Jun 10 04:42:13 2009 New Revision: 2132
Modified: branches/bleeding_edge/src/arm/builtins-arm.cc branches/bleeding_edge/src/arm/codegen-arm.cc branches/bleeding_edge/src/arm/ic-arm.cc branches/bleeding_edge/src/arm/macro-assembler-arm.cc branches/bleeding_edge/src/arm/macro-assembler-arm.h branches/bleeding_edge/src/arm/stub-cache-arm.cc branches/bleeding_edge/src/arm/virtual-frame-arm.cc branches/bleeding_edge/src/codegen.h branches/bleeding_edge/src/ia32/codegen-ia32.cc Log: Add instanceof stub for ARM. Review URL: http://codereview.chromium.org/119353 Modified: branches/bleeding_edge/src/arm/builtins-arm.cc ============================================================================== --- branches/bleeding_edge/src/arm/builtins-arm.cc (original) +++ branches/bleeding_edge/src/arm/builtins-arm.cc Wed Jun 10 04:42:13 2009 @@ -64,9 +64,7 @@ __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &non_function_call); // Check that the function is a JSFunction. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(ne, &non_function_call); // Enter a construct frame. @@ -159,9 +157,7 @@ // If the type of the result (stored in its map) is less than // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense. - __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); - __ cmp(r3, Operand(FIRST_JS_OBJECT_TYPE)); + __ CompareObjectType(r0, r3, r3, FIRST_JS_OBJECT_TYPE); __ b(ge, &exit); // Throw away the result of the constructor invocation and use the @@ -290,9 +286,7 @@ __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &non_function); - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(eq, &function); // Non-function called: Clear the function to force exception. @@ -328,9 +322,7 @@ __ cmp(r2, r3); __ b(eq, &use_global_receiver); - __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); - __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); - __ cmp(r3, Operand(FIRST_JS_OBJECT_TYPE)); + __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE); __ b(lt, &call_to_object); __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE)); __ b(le, &done); @@ -501,9 +493,7 @@ // Check if the receiver is already a JavaScript object. // r0: receiver - __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); + __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); __ b(lt, &call_to_object); __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); __ b(le, &push_receiver); Modified: branches/bleeding_edge/src/arm/codegen-arm.cc ============================================================================== --- branches/bleeding_edge/src/arm/codegen-arm.cc (original) +++ branches/bleeding_edge/src/arm/codegen-arm.cc Wed Jun 10 04:42:13 2009 @@ -1504,9 +1504,7 @@ // Test for a Smi value in a HeapNumber. __ tst(r0, Operand(kSmiTagMask)); is_smi.Branch(eq); - __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - __ cmp(r1, Operand(HEAP_NUMBER_TYPE)); + __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE); default_target->Branch(ne); frame_->EmitPush(r0); frame_->CallRuntime(Runtime::kNumberToSmi, 1); @@ -1873,9 +1871,7 @@ // Check if enumerable is already a JSObject __ tst(r0, Operand(kSmiTagMask)); primitive.Branch(eq); - __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); + __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); jsobject.Branch(hs); primitive.Bind(); @@ -3277,11 +3273,8 @@ // if (object->IsSmi()) return the object. __ tst(r0, Operand(kSmiTagMask)); leave.Branch(eq); - // It is a heap object - get map. - __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - // if (!object->IsJSValue()) return the object. - __ cmp(r1, Operand(JS_VALUE_TYPE)); + // It is a heap object - get map. If (!object->IsJSValue()) return the object. + __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); leave.Branch(ne); // Load the value. __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); @@ -3301,11 +3294,8 @@ // if (object->IsSmi()) return object. __ tst(r1, Operand(kSmiTagMask)); leave.Branch(eq); - // It is a heap object - get map. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - // if (!object->IsJSValue()) return object. - __ cmp(r2, Operand(JS_VALUE_TYPE)); + // It is a heap object - get map. If (!object->IsJSValue()) return the object. + __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); leave.Branch(ne); // Store the value. __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); @@ -3377,11 +3367,8 @@ __ and_(r1, r0, Operand(kSmiTagMask)); __ eor(r1, r1, Operand(kSmiTagMask), SetCC); answer.Branch(ne); - // It is a heap object - get the map. - __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - // Check if the object is a JS array or not. - __ cmp(r1, Operand(JS_ARRAY_TYPE)); + // It is a heap object - get the map. Check if the object is a JS array. + __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); answer.Bind(); cc_reg_ = eq; } @@ -4000,9 +3987,7 @@ } else if (check->Equals(Heap::function_symbol())) { __ tst(r1, Operand(kSmiTagMask)); false_target()->Branch(eq); - __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - __ cmp(r1, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r1, r1, JS_FUNCTION_TYPE); cc_reg_ = eq; } else if (check->Equals(Heap::object_symbol())) { @@ -4075,13 +4060,9 @@ } case Token::INSTANCEOF: { - Result arg_count = allocator_->Allocate(r0); - ASSERT(arg_count.is_valid()); - __ mov(arg_count.reg(), Operand(1)); // not counting receiver - Result result = frame_->InvokeBuiltin(Builtins::INSTANCE_OF, - CALL_JS, - &arg_count, - 2); + InstanceofStub stub; + Result result = frame_->CallStub(&stub, 2); + // At this point if instanceof succeeded then r0 == 0. __ tst(result.reg(), Operand(result.reg())); cc_reg_ = eq; break; @@ -4593,21 +4574,6 @@ } -// Checks that the object register (which is assumed not to be a Smi) points to -// a heap number. Jumps to the label if it is not. -void CheckForHeapNumber(MacroAssembler* masm, - Register object, - Register scratch, - Label* slow) { - // Get map of object into scratch. - __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); - // Get type of object into scratch. - __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); - __ cmp(scratch, Operand(HEAP_NUMBER_TYPE)); - __ b(ne, slow); -} - - // We fall into this code if the operands were Smis, but the result was // not (eg. overflow). We branch into this code (to the not_smi label) if // the operands were not both Smi. The operands are in r0 and r1. In order @@ -4655,7 +4621,8 @@ // Move r0 to a double in r2-r3. __ tst(r0, Operand(kSmiTagMask)); __ b(eq, &r0_is_smi); // It's a Smi so don't check it's a heap number. - CheckForHeapNumber(masm, r0, r4, &slow); + __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); + __ b(ne, &slow); if (mode == OVERWRITE_RIGHT) { __ mov(r5, Operand(r0)); // Overwrite this heap number. } @@ -4679,7 +4646,8 @@ // Move r1 to a double in r0-r1. __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &r1_is_smi); // It's a Smi so don't check it's a heap number. - CheckForHeapNumber(masm, r1, r4, &slow); + __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE); + __ b(ne, &slow); if (mode == OVERWRITE_LEFT) { __ mov(r5, Operand(r1)); // Overwrite this heap number. } @@ -4786,7 +4754,8 @@ __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &r1_is_smi); // It's a Smi so don't check it's a heap number. - CheckForHeapNumber(masm, r1, r4, &slow); + __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE); + __ b(ne, &slow); GetInt32(masm, r1, r3, r4, &slow); __ jmp(&done_checking_r1); __ bind(&r1_is_smi); @@ -4795,7 +4764,8 @@ __ tst(r0, Operand(kSmiTagMask)); __ b(eq, &r0_is_smi); // It's a Smi so don't check it's a heap number. - CheckForHeapNumber(masm, r0, r4, &slow); + __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); + __ b(ne, &slow); GetInt32(masm, r0, r2, r4, &slow); __ jmp(&done_checking_r0); __ bind(&r0_is_smi); @@ -5098,7 +5068,8 @@ __ StubReturn(1); __ bind(¬_smi); - CheckForHeapNumber(masm, r0, r1, &slow); + __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE); + __ b(ne, &slow); // r0 is a heap number. Get a new heap number in r1. if (overwrite_) { __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); @@ -5503,6 +5474,66 @@ } +// This stub performs an instanceof, calling the builtin function if +// necessary. Uses r1 for the object, r0 for the function that it may +// be an instance of (these are fetched from the stack). +void InstanceofStub::Generate(MacroAssembler* masm) { + // Get the object - slow case for smis (we may need to throw an exception + // depending on the rhs). + Label slow, loop, is_instance, is_not_instance; + __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); + __ BranchOnSmi(r0, &slow); + + // Check that the left hand is a JS object and put map in r3. + __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE); + __ b(lt, &slow); + __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); + __ b(gt, &slow); + + // Get the prototype of the function (r4 is result, r2 is scratch). + __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); + __ TryGetFunctionPrototype(r1, r4, r2, &slow); + + // Check that the function prototype is a JS object. + __ BranchOnSmi(r4, &slow); + __ CompareObjectType(r4, r5, r5, FIRST_JS_OBJECT_TYPE); + __ b(lt, &slow); + __ cmp(r5, Operand(LAST_JS_OBJECT_TYPE)); + __ b(gt, &slow); + + // Register mapping: r3 is object map and r4 is function prototype. + // Get prototype of object into r2. + __ ldr(r2, FieldMemOperand(r3, Map::kPrototypeOffset)); + + // Loop through the prototype chain looking for the function prototype. + __ bind(&loop); + __ cmp(r2, Operand(r4)); + __ b(eq, &is_instance); + __ cmp(r2, Operand(Factory::null_value())); + __ b(eq, &is_not_instance); + __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); + __ ldr(r2, FieldMemOperand(r2, Map::kPrototypeOffset)); + __ jmp(&loop); + + __ bind(&is_instance); + __ mov(r0, Operand(Smi::FromInt(0))); + __ pop(); + __ pop(); + __ mov(pc, Operand(lr)); // Return. + + __ bind(&is_not_instance); + __ mov(r0, Operand(Smi::FromInt(1))); + __ pop(); + __ pop(); + __ mov(pc, Operand(lr)); // Return. + + // Slow-case. Tail call builtin. + __ bind(&slow); + __ mov(r0, Operand(1)); // Arg count without receiver. + __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_JS); +} + + void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { // Check if the calling frame is an arguments adaptor frame. Label adaptor; @@ -5531,8 +5562,7 @@ // Check that the key is a smi. Label slow; - __ tst(r1, Operand(kSmiTagMask)); - __ b(ne, &slow); + __ BranchOnNotSmi(r1, &slow); // Check if the calling frame is an arguments adaptor frame. Label adaptor; @@ -5604,12 +5634,9 @@ // Check that the function is really a JavaScript function. // r1: pushed function (to be verified) - __ tst(r1, Operand(kSmiTagMask)); - __ b(eq, &slow); + __ BranchOnSmi(r1, &slow); // Get the map of the function object. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(ne, &slow); // Fast-case: Invoke the function now. Modified: branches/bleeding_edge/src/arm/ic-arm.cc ============================================================================== --- branches/bleeding_edge/src/arm/ic-arm.cc (original) +++ branches/bleeding_edge/src/arm/ic-arm.cc Wed Jun 10 04:42:13 2009 @@ -223,9 +223,7 @@ // Check for number. __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &number); - __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); - __ cmp(r3, Operand(HEAP_NUMBER_TYPE)); + __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE); __ b(ne, &non_number); __ bind(&number); StubCompiler::GenerateLoadGlobalFunctionPrototype( @@ -272,9 +270,7 @@ __ b(eq, miss); // Check that the value is a JSFunction. - __ ldr(r0, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); - __ cmp(r0, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r0, r0, JS_FUNCTION_TYPE); __ b(ne, miss); // Check that the function has been loaded. @@ -312,10 +308,8 @@ __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &miss); - // Check that the receiver is a valid JS object. - __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r0, FieldMemOperand(r3, Map::kInstanceTypeOffset)); - __ cmp(r0, Operand(FIRST_JS_OBJECT_TYPE)); + // Check that the receiver is a valid JS object. Put the map in r3. + __ CompareObjectType(r1, r3, r0, FIRST_JS_OBJECT_TYPE); __ b(lt, &miss); // If this assert fails, we have to check upper bound too. @@ -392,9 +386,7 @@ __ ldr(r2, MemOperand(sp, argc * kPointerSize)); // receiver __ tst(r2, Operand(kSmiTagMask)); __ b(eq, &invoke); - __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); - __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); - __ cmp(r3, Operand(JS_GLOBAL_OBJECT_TYPE)); + __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE); __ b(eq, &global); __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE)); __ b(ne, &invoke); @@ -447,10 +439,8 @@ __ tst(r0, Operand(kSmiTagMask)); __ b(eq, &miss); - // Check that the receiver is a valid JS object. - __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); - __ ldrb(r1, FieldMemOperand(r3, Map::kInstanceTypeOffset)); - __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); + // Check that the receiver is a valid JS object. Put the map in r3. + __ CompareObjectType(r0, r3, r1, FIRST_JS_OBJECT_TYPE); __ b(lt, &miss); // If this assert fails, we have to check upper bound too. ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); Modified: branches/bleeding_edge/src/arm/macro-assembler-arm.cc ============================================================================== --- branches/bleeding_edge/src/arm/macro-assembler-arm.cc (original) +++ branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Jun 10 04:42:13 2009 @@ -750,6 +750,62 @@ } +void MacroAssembler::CompareObjectType(Register function, + Register map, + Register type_reg, + InstanceType type) { + ldr(map, FieldMemOperand(function, HeapObject::kMapOffset)); + ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); + cmp(type_reg, Operand(type)); +} + + +void MacroAssembler::TryGetFunctionPrototype(Register function, + Register result, + Register scratch, + Label* miss) { + // Check that the receiver isn't a smi. + BranchOnSmi(function, miss); + + // Check that the function really is a function. Load map into result reg. + CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE); + b(ne, miss); + + // Make sure that the function has an instance prototype. + Label non_instance; + ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); + tst(scratch, Operand(1 << Map::kHasNonInstancePrototype)); + b(ne, &non_instance); + + // Get the prototype or initial map from the function. + ldr(result, + FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); + + // If the prototype or initial map is the hole, don't return it and + // simply miss the cache instead. This will allow us to allocate a + // prototype object on-demand in the runtime system. + cmp(result, Operand(Factory::the_hole_value())); + b(eq, miss); + + // If the function does not have an initial map, we're done. + Label done; + CompareObjectType(result, scratch, scratch, MAP_TYPE); + b(ne, &done); + + // Get the prototype from the initial map. + ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); + jmp(&done); + + // Non-instance prototype: Fetch prototype from constructor field + // in initial map. + bind(&non_instance); + ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); + + // All done. + bind(&done); +} + + void MacroAssembler::CallStub(CodeStub* stub) { ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs Call(stub->GetCode(), RelocInfo::CODE_TARGET); Modified: branches/bleeding_edge/src/arm/macro-assembler-arm.h ============================================================================== --- branches/bleeding_edge/src/arm/macro-assembler-arm.h (original) +++ branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Jun 10 04:42:13 2009 @@ -187,6 +187,38 @@ // --------------------------------------------------------------------------- // Support functions. + // Try to get function prototype of a function and puts the value in + // the result register. Checks that the function really is a + // function and jumps to the miss label if the fast checks fail. The + // function register will be untouched; the other registers may be + // clobbered. + void TryGetFunctionPrototype(Register function, + Register result, + Register scratch, + Label* miss); + + // Compare object type for heap object. heap_object contains a non-Smi + // whose object type should be compared with the given type. This both + // sets the flags and leaves the object type in the type_reg register. + // It leaves the map in the map register (unless the type_reg and map register + // are the same register). It leaves the heap object in the heap_object + // register unless the heap_object register is the same register as one of the + // other // registers. + void CompareObjectType(Register heap_object, + Register map, + Register type_reg, + InstanceType type); + + inline void BranchOnSmi(Register value, Label* smi_label) { + tst(value, Operand(kSmiTagMask)); + b(eq, smi_label); + } + + inline void BranchOnNotSmi(Register value, Label* not_smi_label) { + tst(value, Operand(kSmiTagMask)); + b(ne, not_smi_label); + } + // Generates code for reporting that an illegal operation has // occurred. void IllegalOperation(int num_arguments); Modified: branches/bleeding_edge/src/arm/stub-cache-arm.cc ============================================================================== --- branches/bleeding_edge/src/arm/stub-cache-arm.cc (original) +++ branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Jun 10 04:42:13 2009 @@ -283,9 +283,7 @@ __ b(eq, miss_label); // Check that the object is a JS array. - __ ldr(scratch, FieldMemOperand(receiver, HeapObject::kMapOffset)); - __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); - __ cmp(scratch, Operand(JS_ARRAY_TYPE)); + __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); __ b(ne, miss_label); // Load length directly from the JS array. @@ -523,9 +521,7 @@ __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &miss); // Get the map. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(ne, &miss); // Patch the receiver on the stack with the global proxy if @@ -588,9 +584,7 @@ case STRING_CHECK: // Check that the object is a two-byte string or a symbol. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(FIRST_NONSTRING_TYPE)); + __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE); __ b(hs, &miss); // Check that the maps starting from the prototype haven't changed. GenerateLoadGlobalFunctionPrototype(masm(), @@ -605,9 +599,7 @@ // Check that the object is a smi or a heap number. __ tst(r1, Operand(kSmiTagMask)); __ b(eq, &fast); - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(HEAP_NUMBER_TYPE)); + __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); __ b(ne, &miss); __ bind(&fast); // Check that the maps starting from the prototype haven't changed. Modified: branches/bleeding_edge/src/arm/virtual-frame-arm.cc ============================================================================== --- branches/bleeding_edge/src/arm/virtual-frame-arm.cc (original) +++ branches/bleeding_edge/src/arm/virtual-frame-arm.cc Wed Jun 10 04:42:13 2009 @@ -156,9 +156,7 @@ __ b(ne, &map_check); __ stop("VirtualFrame::Enter - r1 is not a function (smi check)."); __ bind(&map_check); - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - __ cmp(r2, Operand(JS_FUNCTION_TYPE)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(eq, &done); __ stop("VirtualFrame::Enter - r1 is not a function (map check)."); __ bind(&done); Modified: branches/bleeding_edge/src/codegen.h ============================================================================== --- branches/bleeding_edge/src/codegen.h (original) +++ branches/bleeding_edge/src/codegen.h Wed Jun 10 04:42:13 2009 @@ -228,6 +228,18 @@ }; +class InstanceofStub: public CodeStub { + public: + InstanceofStub() { } + + void Generate(MacroAssembler* masm); + + private: + Major MajorKey() { return Instanceof; } + int MinorKey() { return 0; } +}; + + class UnarySubStub : public CodeStub { public: explicit UnarySubStub(bool overwrite) Modified: branches/bleeding_edge/src/ia32/codegen-ia32.cc ============================================================================== --- branches/bleeding_edge/src/ia32/codegen-ia32.cc (original) +++ branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Jun 10 04:42:13 2009 @@ -5466,18 +5466,6 @@ } -class InstanceofStub: public CodeStub { - public: - InstanceofStub() { } - - void Generate(MacroAssembler* masm); - - private: - Major MajorKey() { return Instanceof; } - int MinorKey() { return 0; } -}; - - void CodeGenerator::VisitCompareOperation(CompareOperation* node) { Comment cmnt(masm_, "[ CompareOperation"); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list v8-dev@googlegroups.com http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---