Revision: 4599
Author: [email protected]
Date: Thu May 6 02:35:18 2010
Log: Add a single-element global positive and negative cache to
the implementation of instanceof.
Review URL: http://codereview.chromium.org/1765012
http://code.google.com/p/v8/source/detail?r=4599
Added:
/branches/bleeding_edge/test/mjsunit/instanceof-2.js
Modified:
/branches/bleeding_edge/src/arm/codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/instanceof-2.js Thu May 6
02:35:18 2010
@@ -0,0 +1,329 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var except = "exception";
+
+var correct_answer_index = 0;
+var correct_answers = [
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, true, false, false, true,
+ false, true, true, false, false, true, true, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, false, true,
+except, except, true, false, except, except, true, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, true, false, except, except,
+ false, true, except, except, false, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, false, true, true, false,
+ true, true, false, false, false, true, true, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, true, false,
+except, except, false, false, except, except, true, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, true, false, except, except,
+ false, true, except, except, false, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, true, true, false,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, false, true, true, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, false, true,
+except, except, true, false, except, except, true, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, true, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, false, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, true, true, false,
+ true, false, false, true, false, true, true, false,
+ false, true, true, false, false, true, true, false,
+ true, true, false, false, false, true, true, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, true, false,
+except, except, false, false, except, except, true, false,
+ false, false, except, except, false, true, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, false, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, false, false, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, false, false, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, true, true, false, false,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, true, true, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, true, true, false, false,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, true, true, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, false, false, true, true,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, false, false,
+except, except, true, false, except, except, true, true,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, false, false, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, false, false, true, true,
+ true, true, false, false, false, false, true, true,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, true, true,
+except, except, false, false, except, except, true, true,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, false, false, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, false, false, true, true,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, false, false,
+except, except, true, false, except, except, true, true,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, false, false, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, false, false, true, true,
+ true, true, false, false, false, false, true, true,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, true, true,
+except, except, false, false, except, except, true, true,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, false, false, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, false, false, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, false, false, true, true,
+ true, false, false, true, false, false, true, true,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, false, false, except, except,
+ true, false, except, except, false, false, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, true, true, false, false,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, true, true, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+ false, false, true, true, true, true, false, false,
+ true, false, false, true, true, true, false, false,
+ false, true, true, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+except, except, true, true, except, except, true, true,
+except, except, false, true, except, except, true, true,
+except, except, true, false, except, except, false, false,
+except, except, false, false, except, except, false, false,
+ false, false, except, except, true, true, except, except,
+ true, false, except, except, true, true, except, except,
+ false, true, except, except, true, true, except, except,
+ true, true, except, except, true, true, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except,
+except, except, except, except, except, except, except, except];
+
+for (var i = 0; i < 256; i++) {
+ Test(i & 1, i & 2, i & 4, i & 8, i & 0x10, i & 0x20, i & 0x40, i & 0x80);
+}
+
+
+function InstanceTest(x, func) {
+ try {
+ var answer = (x instanceof func);
+ assertEquals(correct_answers[correct_answer_index], answer);
+ } catch (e) {
+ assertTrue(/prototype/.test(e));
+ assertEquals(correct_answers[correct_answer_index], except);
+ }
+ correct_answer_index++;
+}
+
+
+function Test(a, b, c, d, e, f, g, h) {
+ var Foo = function() { }
+ var Bar = function() { }
+
+ if (c) Foo.prototype = 12;
+ if (d) Bar.prototype = 13;
+ var x = a ? new Foo() : new Bar();
+ var y = b ? new Foo() : new Bar();
+ InstanceTest(x, Foo);
+ InstanceTest(y, Foo);
+ InstanceTest(x, Bar);
+ InstanceTest(y, Bar);
+ if (e) x.__proto__ = Bar.prototype;
+ if (f) y.__proto__ = Foo.prototype;
+ if (g) {
+ x.__proto__ = y;
+ } else {
+ if (h) y.__proto__ = x
+ }
+ InstanceTest(x, Foo);
+ InstanceTest(y, Foo);
+ InstanceTest(x, Bar);
+ InstanceTest(y, Bar);
+}
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc Tue May 4 23:57:41 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc Thu May 6 02:35:18 2010
@@ -8206,6 +8206,22 @@
// Get the prototype of the function (r4 is result, r2 is scratch).
__ ldr(r1, MemOperand(sp, 0));
+ // r1 is function, r3 is map.
+
+ // Look up the function and the map in the instanceof cache.
+ Label miss;
+ __ LoadRoot(ip, Heap::kInstanceofCacheFunctionRootIndex);
+ __ cmp(r1, ip);
+ __ b(ne, &miss);
+ __ LoadRoot(ip, Heap::kInstanceofCacheMapRootIndex);
+ __ cmp(r3, ip);
+ __ b(ne, &miss);
+ __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
+ __ pop();
+ __ pop();
+ __ mov(pc, Operand(lr));
+
+ __ bind(&miss);
__ TryGetFunctionPrototype(r1, r4, r2, &slow);
// Check that the function prototype is a JS object.
@@ -8215,6 +8231,9 @@
__ cmp(r5, Operand(LAST_JS_OBJECT_TYPE));
__ b(gt, &slow);
+ __ StoreRoot(r1, Heap::kInstanceofCacheFunctionRootIndex);
+ __ StoreRoot(r3, Heap::kInstanceofCacheMapRootIndex);
+
// Register mapping: r3 is object map and r4 is function prototype.
// Get prototype of object into r2.
__ ldr(r2, FieldMemOperand(r3, Map::kPrototypeOffset));
@@ -8232,12 +8251,14 @@
__ bind(&is_instance);
__ mov(r0, Operand(Smi::FromInt(0)));
+ __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
__ pop();
__ pop();
__ mov(pc, Operand(lr)); // Return.
__ bind(&is_not_instance);
__ mov(r0, Operand(Smi::FromInt(1)));
+ __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
__ pop();
__ pop();
__ mov(pc, Operand(lr)); // Return.
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 4
07:49:50 2010
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu May 6
02:35:18 2010
@@ -230,6 +230,13 @@
Condition cond) {
ldr(destination, MemOperand(roots, index << kPointerSizeLog2), cond);
}
+
+
+void MacroAssembler::StoreRoot(Register source,
+ Heap::RootListIndex index,
+ Condition cond) {
+ str(source, MemOperand(roots, index << kPointerSizeLog2), cond);
+}
void MacroAssembler::RecordWriteHelper(Register object,
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue May 4
07:49:50 2010
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Thu May 6
02:35:18 2010
@@ -85,6 +85,10 @@
void LoadRoot(Register destination,
Heap::RootListIndex index,
Condition cond = al);
+ // Store an object to the root table.
+ void StoreRoot(Register source,
+ Heap::RootListIndex index,
+ Condition cond = al);
// Check if object is in new space.
=======================================
--- /branches/bleeding_edge/src/heap.cc Tue May 4 09:42:11 2010
+++ /branches/bleeding_edge/src/heap.cc Thu May 6 02:35:18 2010
@@ -674,6 +674,8 @@
Top::MarkCompactPrologue(is_compacting);
ThreadManager::MarkCompactPrologue(is_compacting);
+ CompletelyClearInstanceofCache();
+
if (is_compacting) FlushNumberStringCache();
}
@@ -1685,6 +1687,10 @@
if (obj->IsFailure()) return false;
set_non_monomorphic_cache(NumberDictionary::cast(obj));
+ set_instanceof_cache_function(Smi::FromInt(0));
+ set_instanceof_cache_map(Smi::FromInt(0));
+ set_instanceof_cache_answer(Smi::FromInt(0));
+
CreateFixedStubs();
if (InitializeNumberStringCache()->IsFailure()) return false;
=======================================
--- /branches/bleeding_edge/src/heap.h Tue May 4 09:42:11 2010
+++ /branches/bleeding_edge/src/heap.h Thu May 6 02:35:18 2010
@@ -93,6 +93,9 @@
V(Map, proxy_map,
ProxyMap) \
V(Object, nan_value,
NanValue) \
V(Object, minus_zero_value,
MinusZeroValue) \
+ V(Object, instanceof_cache_function,
InstanceofCacheFunction) \
+ V(Object, instanceof_cache_map,
InstanceofCacheMap) \
+ V(Object, instanceof_cache_answer,
InstanceofCacheAnswer) \
V(String, empty_string,
EmptyString) \
V(DescriptorArray, empty_descriptor_array,
EmptyDescriptorArray) \
V(Map, neander_map,
NeanderMap) \
@@ -360,6 +363,11 @@
// Allocates an empty code cache.
static Object* AllocateCodeCache();
+
+ // Clear the Instanceof cache (used when a prototype changes).
+ static void ClearInstanceofCache() {
+ set_instanceof_cache_function(the_hole_value());
+ }
// Allocates and fully initializes a String. There are two String
// encodings: ASCII and two byte. One should choose between the three
string
@@ -1170,6 +1178,13 @@
// Code to be run before and after mark-compact.
static void MarkCompactPrologue(bool is_compacting);
static void MarkCompactEpilogue(bool is_compacting);
+
+ // Completely clear the Instanceof cache (to stop it keeping objects
alive
+ // around a GC).
+ static void CompletelyClearInstanceofCache() {
+ set_instanceof_cache_map(the_hole_value());
+ set_instanceof_cache_function(the_hole_value());
+ }
// Helper function used by CopyObject to copy a source object to an
// allocated target object and update the forwarding pointer in the
source
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed May 5 01:56:16
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Thu May 6 02:35:18
2010
@@ -12126,6 +12126,22 @@
// Get the prototype of the function.
__ mov(edx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
+ // edx is function, eax is map.
+
+ // Look up the function and the map in the instanceof cache.
+ Label miss;
+ ExternalReference roots_address = ExternalReference::roots_address();
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
+ __ cmp(edx, Operand::StaticArray(ecx, times_pointer_size,
roots_address));
+ __ j(not_equal, &miss);
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheMapRootIndex));
+ __ cmp(eax, Operand::StaticArray(ecx, times_pointer_size,
roots_address));
+ __ j(not_equal, &miss);
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
+ __ mov(eax, Operand::StaticArray(ecx, times_pointer_size,
roots_address));
+ __ ret(2 * kPointerSize);
+
+ __ bind(&miss);
__ TryGetFunctionPrototype(edx, ebx, ecx, &slow);
// Check that the function prototype is a JS object.
@@ -12138,7 +12154,15 @@
__ cmp(ecx, LAST_JS_OBJECT_TYPE);
__ j(greater, &slow, not_taken);
- // Register mapping: eax is object map and ebx is function prototype.
+ // Register mapping:
+ // eax is object map.
+ // edx is function.
+ // ebx is function prototype.
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheMapRootIndex));
+ __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address),
eax);
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
+ __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address),
edx);
+
__ mov(ecx, FieldOperand(eax, Map::kPrototypeOffset));
// Loop through the prototype chain looking for the function prototype.
@@ -12154,10 +12178,14 @@
__ bind(&is_instance);
__ Set(eax, Immediate(0));
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
+ __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address),
eax);
__ ret(2 * kPointerSize);
__ bind(&is_not_instance);
__ Set(eax, Immediate(Smi::FromInt(1)));
+ __ mov(ecx, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
+ __ mov(Operand::StaticArray(ecx, times_pointer_size, roots_address),
eax);
__ ret(2 * kPointerSize);
// Slow-case: Go through the JavaScript implementation.
=======================================
--- /branches/bleeding_edge/src/objects.cc Wed May 5 05:25:58 2010
+++ /branches/bleeding_edge/src/objects.cc Thu May 6 02:35:18 2010
@@ -4900,6 +4900,7 @@
// prototype is put into the initial map where it belongs.
set_prototype_or_initial_map(value);
}
+ Heap::ClearInstanceofCache();
return value;
}
@@ -5601,6 +5602,8 @@
Map::cast(new_map)->set_prototype(value);
real_receiver->set_map(Map::cast(new_map));
+ Heap::ClearInstanceofCache();
+
return value;
}
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Thu May 6 01:15:15 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Thu May 6 02:35:18 2010
@@ -8792,6 +8792,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;
@@ -8806,6 +8809,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.
@@ -8815,7 +8830,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.
@@ -8825,6 +8846,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));
@@ -8832,10 +8855,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.
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu May 6
01:15:15 2010
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu May 6
02:35:18 2010
@@ -48,6 +48,11 @@
void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex
index) {
movq(destination, Operand(kRootRegister, index << kPointerSizeLog2));
}
+
+
+void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index)
{
+ movq(Operand(kRootRegister, index << kPointerSizeLog2), source);
+}
void MacroAssembler::PushRoot(Heap::RootListIndex index) {
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Thu May 6
01:15:15 2010
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Thu May 6
02:35:18 2010
@@ -62,6 +62,7 @@
void CompareRoot(Register with, Heap::RootListIndex index);
void CompareRoot(Operand with, Heap::RootListIndex index);
void PushRoot(Heap::RootListIndex index);
+ void StoreRoot(Register source, Heap::RootListIndex index);
//
---------------------------------------------------------------------------
// GC Support
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev