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

Reply via email to