Commit 9c96c68a authored by bak@chromium.org's avatar bak@chromium.org

Reduced the code sequence for testing for object type.

We now use cmpb instead of movzx_b and cmp.



git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1452 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 36dd91c5
......@@ -77,9 +77,7 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
__ test(edi, Immediate(kSmiTagMask));
__ j(zero, &rt_call);
// Check that function is a JSFunction
__ mov(eax, FieldOperand(edi, JSFunction::kMapOffset));
__ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
__ cmp(eax, JS_FUNCTION_TYPE);
__ CmpObjectType(edi, JS_FUNCTION_TYPE, eax);
__ j(not_equal, &rt_call);
// Verified that the constructor is a JSFunction.
......@@ -91,9 +89,7 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
__ j(zero, &rt_call);
// edi: constructor
// eax: initial map (if proven valid below)
__ mov(ebx, FieldOperand(eax, JSFunction::kMapOffset));
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
__ cmp(ebx, MAP_TYPE);
__ CmpObjectType(eax, MAP_TYPE, ebx);
__ j(not_equal, &rt_call);
// Check that the constructor is not constructing a JSFunction (see comments
......@@ -101,8 +97,7 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
// instance type would be JS_FUNCTION_TYPE.
// edi: constructor
// eax: initial map
__ movzx_b(ebx, FieldOperand(eax, Map::kInstanceTypeOffset));
__ cmp(ebx, JS_FUNCTION_TYPE);
__ CmpInstanceType(eax, JS_FUNCTION_TYPE);
__ j(equal, &rt_call);
// Now allocate the JSObject on the heap.
......@@ -391,9 +386,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize));
__ test(edi, Immediate(kSmiTagMask));
__ j(zero, &non_function, not_taken);
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); // get the map
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ cmp(ecx, JS_FUNCTION_TYPE);
__ CmpObjectType(edi,JS_FUNCTION_TYPE, ecx);
__ j(equal, &function, taken);
// Non-function called: Clear the function to force exception.
......
......@@ -1934,9 +1934,7 @@ void CodeGenerator::GenerateFastCaseSwitchJumpTable(
// heap number.
Result temp = allocator()->Allocate();
ASSERT(temp.is_valid());
__ mov(temp.reg(), FieldOperand(switch_value.reg(), HeapObject::kMapOffset));
__ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
__ cmp(temp.reg(), HEAP_NUMBER_TYPE);
__ CmpObjectType(switch_value.reg(), HEAP_NUMBER_TYPE, temp.reg());
temp.Unuse();
default_target->Branch(not_equal);
......@@ -4129,10 +4127,8 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
// It is a heap object - get map.
Result temp = allocator()->Allocate();
ASSERT(temp.is_valid());
__ mov(temp.reg(), FieldOperand(value.reg(), HeapObject::kMapOffset));
__ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
// Check if the object is a JS array or not.
__ cmp(temp.reg(), JS_ARRAY_TYPE);
__ CmpObjectType(value.reg(), JS_ARRAY_TYPE, temp.reg());
value.Unuse();
temp.Unuse();
destination()->Split(equal);
......@@ -4168,10 +4164,8 @@ void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
// It is a heap object - get map.
Result temp = allocator()->Allocate();
ASSERT(temp.is_valid());
__ mov(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
__ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
// if (!object->IsJSValue()) return object.
__ cmp(temp.reg(), JS_VALUE_TYPE);
__ CmpObjectType(object.reg(), JS_VALUE_TYPE, temp.reg());
leave.Branch(not_equal, not_taken);
__ mov(temp.reg(), FieldOperand(object.reg(), JSValue::kValueOffset));
object.Unuse();
......@@ -4197,11 +4191,8 @@ void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
// It is a heap object - get its map.
Result scratch = allocator_->Allocate();
ASSERT(scratch.is_valid());
__ mov(scratch.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
__ movzx_b(scratch.reg(),
FieldOperand(scratch.reg(), Map::kInstanceTypeOffset));
// if (!object->IsJSValue()) return value.
__ cmp(scratch.reg(), JS_VALUE_TYPE);
__ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg());
leave.Branch(not_equal, &value, not_taken);
// Store the value.
......@@ -4915,10 +4906,7 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
__ test(answer.reg(), Immediate(kSmiTagMask));
destination()->false_target()->Branch(zero);
frame_->Spill(answer.reg());
__ mov(answer.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
__ movzx_b(answer.reg(),
FieldOperand(answer.reg(), Map::kInstanceTypeOffset));
__ cmp(answer.reg(), JS_FUNCTION_TYPE);
__ CmpObjectType(answer.reg(), JS_FUNCTION_TYPE, answer.reg());
answer.Unuse();
destination()->Split(equal);
......@@ -6415,10 +6403,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Check that the function really is a JavaScript function.
__ test(edi, Immediate(kSmiTagMask));
__ j(zero, &slow, not_taken);
// Get the map.
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ cmp(ecx, JS_FUNCTION_TYPE);
// Goto slow case if we do not have a function.
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &slow, not_taken);
// Fast-case: Just invoke the function.
......
......@@ -130,9 +130,7 @@ static void GenerateCheckNonFunctionOrLoaded(MacroAssembler* masm, Label* miss,
__ test(value, Immediate(kSmiTagMask));
__ j(zero, &done, not_taken);
// Check if the value is a function.
__ mov(scratch, FieldOperand(value, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
__ cmp(scratch, JS_FUNCTION_TYPE);
__ CmpObjectType(value, JS_FUNCTION_TYPE, scratch);
__ j(not_equal, &done, taken);
// Check if the function has been loaded.
__ mov(scratch, FieldOperand(value, JSFunction::kSharedFunctionInfoOffset));
......@@ -441,9 +439,7 @@ void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
// Check for number.
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &number, not_taken);
__ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
__ cmp(ebx, HEAP_NUMBER_TYPE);
__ CmpObjectType(edx, HEAP_NUMBER_TYPE, ebx);
__ j(not_equal, &non_number, taken);
__ bind(&number);
StubCompiler::GenerateLoadGlobalFunctionPrototype(
......@@ -491,9 +487,7 @@ static void GenerateNormalHelper(MacroAssembler* masm,
__ j(zero, miss, not_taken);
// Check that the value is a JavaScript function.
__ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
__ cmp(edx, JS_FUNCTION_TYPE);
__ CmpObjectType(edx, JS_FUNCTION_TYPE, edx);
__ j(not_equal, miss, not_taken);
// Check that the function has been loaded.
......
......@@ -306,6 +306,20 @@ void MacroAssembler::Set(const Operand& dst, const Immediate& x) {
}
void MacroAssembler::CmpObjectType(Register heap_object,
InstanceType type,
Register map) {
mov(map, FieldOperand(heap_object, HeapObject::kMapOffset));
CmpInstanceType(map, type);
}
void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
cmpb(FieldOperand(map, Map::kInstanceTypeOffset),
static_cast<int8_t>(type));
}
void MacroAssembler::FCmp() {
fcompp();
push(eax);
......@@ -657,9 +671,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
j(zero, miss, not_taken);
// Check that the function really is a function.
mov(result, FieldOperand(function, HeapObject::kMapOffset));
movzx_b(scratch, FieldOperand(result, Map::kInstanceTypeOffset));
cmp(scratch, JS_FUNCTION_TYPE);
CmpObjectType(function, JS_FUNCTION_TYPE, result);
j(not_equal, miss, not_taken);
// Make sure that the function has an instance prototype.
......@@ -680,9 +692,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
// If the function does not have an initial map, we're done.
Label done;
mov(scratch, FieldOperand(result, HeapObject::kMapOffset));
movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
cmp(scratch, MAP_TYPE);
CmpObjectType(result, MAP_TYPE, scratch);
j(not_equal, &done);
// Get the prototype from the initial map.
......
......@@ -139,6 +139,13 @@ class MacroAssembler: public Assembler {
void Set(Register dst, const Immediate& x);
void Set(const Operand& dst, const Immediate& x);
// Compare object type for heap object.
// Incoming register is heap_object and outgoing register is map.
void CmpObjectType(Register heap_object, InstanceType type, Register map);
// Compare instance type for map.
void CmpInstanceType(Register map, InstanceType type);
// FCmp is similar to integer cmp, but requires unsigned
// jcc instructions (je, ja, jae, jb, jbe, je, and jz).
void FCmp();
......
......@@ -148,9 +148,7 @@ void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
__ j(zero, miss_label, not_taken);
// Check that the object is a JS array.
__ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
__ cmp(scratch, JS_ARRAY_TYPE);
__ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
__ j(not_equal, miss_label, not_taken);
// Load length directly from the JS array.
......@@ -494,9 +492,7 @@ Object* CallStubCompiler::CompileCallField(Object* object,
// Check that the function really is a function.
__ test(edi, Immediate(kSmiTagMask));
__ j(zero, &miss, not_taken);
__ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset)); // get the map
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
__ cmp(ebx, JS_FUNCTION_TYPE);
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
__ j(not_equal, &miss, not_taken);
// Patch the receiver on the stack with the global proxy if
......@@ -573,9 +569,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
// Check that the object is a smi or a heap number.
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &fast, taken);
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ cmp(ecx, HEAP_NUMBER_TYPE);
__ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx);
__ j(not_equal, &miss, not_taken);
__ bind(&fast);
// Check that the maps starting from the prototype haven't changed.
......@@ -691,9 +685,7 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
// Check that the function really is a function.
__ test(edi, Immediate(kSmiTagMask));
__ j(zero, &miss, not_taken);
__ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset));
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
__ cmp(ebx, JS_FUNCTION_TYPE);
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
__ j(not_equal, &miss, not_taken);
// Patch the receiver on the stack with the global proxy if
......
......@@ -396,9 +396,7 @@ void VirtualFrame::Enter() {
__ test(edi, Immediate(kSmiTagMask));
__ Check(not_zero,
"VirtualFrame::Enter - edi is not a function (smi check).");
__ mov(eax, FieldOperand(edi, HeapObject::kMapOffset));
__ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
__ cmp(eax, JS_FUNCTION_TYPE);
__ CmpObjectType(edi, JS_FUNCTION_TYPE, eax);
__ Check(equal,
"VirtualFrame::Enter - edi is not a function (map check).");
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment