Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: src/codegen-ia32.cc

Issue 6341: Improve the generated code for the instanceof operator. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 469)
+++ src/codegen-ia32.cc (working copy)
@@ -894,18 +894,8 @@
void Generate(MacroAssembler* masm);
private:
-
Major MajorKey() { return ToBoolean; }
-
int MinorKey() { return 0; }
-
- const char* GetName() { return "ToBooleanStub"; }
-
-#ifdef DEBUG
- void Print() {
- PrintF("ToBooleanStub\n");
- }
-#endif
};
@@ -1476,8 +1466,6 @@
return (static_cast<int>(cc_) << 1) | (strict_ ? 1 : 0);
}
- const char* GetName() { return "CompareStub"; }
-
#ifdef DEBUG
void Print() {
PrintF("CompareStub (cc %d), (strict %s)\n",
@@ -1585,8 +1573,6 @@
private:
int argc_;
- const char* GetName() { return "CallFunctionStub"; }
-
#ifdef DEBUG
void Print() { PrintF("CallFunctionStub (args %d)\n", argc_); }
#endif
@@ -3521,8 +3507,6 @@
int MinorKey() { return is_increment_ ? 1 : 0; }
void Generate(MacroAssembler* masm);
- const char* GetName() { return "RevertToNumberStub"; }
-
#ifdef DEBUG
void Print() {
PrintF("RevertToNumberStub (is_increment %s)\n",
@@ -3552,8 +3536,6 @@
}
void Generate(MacroAssembler* masm);
- const char* GetName() { return "CounterOpStub"; }
-
#ifdef DEBUG
void Print() {
PrintF("CounterOpStub (result_offset %d), (is_postfix %s),"
@@ -3754,6 +3736,18 @@
}
+class InstanceofStub: public CodeStub {
+ public:
+ InstanceofStub() { }
+
+ void Generate(MacroAssembler* masm);
+
+ private:
+ Major MajorKey() { return Instanceof; }
+ int MinorKey() { return 0; }
+};
+
+
void Ia32CodeGenerator::VisitCompareOperation(CompareOperation* node) {
Comment cmnt(masm_, "[ CompareOperation");
@@ -3934,8 +3928,10 @@
case Token::INSTANCEOF: {
Load(left);
Load(right);
- __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
- __ push(eax); // push the result
+ InstanceofStub stub;
+ __ CallStub(&stub);
+ __ test(eax, Operand(eax));
+ cc_reg_ = zero;
return;
}
default:
@@ -5289,6 +5285,53 @@
}
+void InstanceofStub::Generate(MacroAssembler* masm) {
+ // Get the object - go slow case if it's a smi.
+ Label slow;
+ __ mov(eax, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, function
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(zero, &slow, not_taken);
+
+ // Check that the left hand is a JS object.
+ __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); // ebx - object map
+ __ movzx_b(ecx, FieldOperand(eax, Map::kInstanceTypeOffset)); // ecx - type
+ __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ __ j(less, &slow, not_taken);
+ __ cmp(ecx, LAST_JS_OBJECT_TYPE);
+ __ j(greater, &slow, not_taken);
+
+ // Get the prototype of the function.
+ __ mov(edx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
+ __ TryGetFunctionPrototype(edx, ebx, ecx, &slow);
+
+ // Register mapping: eax is object map and ebx is function prototype.
+ __ mov(ecx, FieldOperand(eax, Map::kPrototypeOffset));
+
+ // Loop through the prototype chain looking for the function prototype.
+ Label loop, is_instance, is_not_instance;
+ __ bind(&loop);
+ __ cmp(ecx, Operand(ebx));
+ __ j(equal, &is_instance);
+ __ cmp(Operand(ecx), Immediate(Factory::null_value()));
+ __ j(equal, &is_not_instance);
+ __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
+ __ mov(ecx, FieldOperand(ecx, Map::kPrototypeOffset));
+ __ jmp(&loop);
+
+ __ bind(&is_instance);
+ __ Set(eax, Immediate(0));
+ __ ret(2 * kPointerSize);
+
+ __ bind(&is_not_instance);
+ __ Set(eax, Immediate(Smi::FromInt(1)));
+ __ ret(2 * kPointerSize);
+
+ // Slow-case: Go through the JavaScript implementation.
+ __ bind(&slow);
+ __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
+}
+
+
#undef __
// -----------------------------------------------------------------------------
« no previous file with comments | « src/codegen-arm.cc ('k') | src/macro-assembler-ia32.h » ('j') | src/macro-assembler-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698