Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 4568) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -8624,6 +8624,9 @@ |
// rsp[0] : return address |
// rsp[1] : function pointer |
// rsp[2] : value |
+ // Returns a bitwise zero to indicate that the value |
+ // is and instance of the function and anything else to |
+ // indicate that the value is not an instance. |
// Get the object - go slow case if it's a smi. |
Label slow; |
@@ -8638,6 +8641,18 @@ |
// Get the prototype of the function. |
__ movq(rdx, Operand(rsp, 1 * kPointerSize)); |
+ // rdx is function, rax is map. |
+ |
+ // Look up the function and the map in the instanceof cache. |
+ Label miss; |
+ __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); |
+ __ j(not_equal, &miss); |
+ __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex); |
+ __ j(not_equal, &miss); |
+ __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); |
+ __ ret(2 * kPointerSize); |
+ |
+ __ bind(&miss); |
__ TryGetFunctionPrototype(rdx, rbx, &slow); |
// Check that the function prototype is a JS object. |
@@ -8647,7 +8662,13 @@ |
__ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE); |
__ j(above, &slow); |
- // Register mapping: rax is object map and rbx is function prototype. |
+ // Register mapping: |
+ // rax is object map. |
+ // rdx is function. |
+ // rbx is function prototype. |
+ __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); |
+ __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex); |
+ |
__ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset)); |
// Loop through the prototype chain looking for the function prototype. |
@@ -8657,6 +8678,8 @@ |
__ cmpq(rcx, rbx); |
__ j(equal, &is_instance); |
__ cmpq(rcx, kScratchRegister); |
+ // The code at is_not_instance assumes that kScratchRegister contains a |
+ // non-zero GCable value (the null object in this case). |
__ j(equal, &is_not_instance); |
__ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset)); |
__ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset)); |
@@ -8664,10 +8687,14 @@ |
__ bind(&is_instance); |
__ xorl(rax, rax); |
+ // Store bitwise zero in the cache. This is a Smi in GC terms. |
+ ASSERT_EQ(0, kSmiTag); |
+ __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); |
__ ret(2 * kPointerSize); |
__ bind(&is_not_instance); |
- __ movl(rax, Immediate(1)); |
+ // We have to store a non-zero value in the cache. |
+ __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); |
__ ret(2 * kPointerSize); |
// Slow-case: Go through the JavaScript implementation. |