Author: [email protected]
Date: Wed Jun  3 05:04:53 2009
New Revision: 2094

Modified:
    branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
    branches/bleeding_edge/src/objects.h
    branches/bleeding_edge/src/stub-cache.h
    branches/bleeding_edge/test/cctest/test-api.cc

Log:
Follow up to r2093: forgotten files and changes.



Modified: branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/stub-cache-ia32.cc  (original)
+++ branches/bleeding_edge/src/ia32/stub-cache-ia32.cc  Wed Jun  3 05:04:53  
2009
@@ -327,6 +327,26 @@
                                             Register scratch1,
                                             Register scratch2,
                                             Label* miss_label) {
+  GenerateLoadInterceptor(masm,
+                          object,
+                          holder,
+                          Smi::FromInt(JSObject::kLookupInHolder),
+                          receiver,
+                          name,
+                          scratch1,
+                          scratch2,
+                          miss_label);
+}
+
+void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
+                                           JSObject* object,
+                                           JSObject* holder,
+                                           Smi* lookup_hint,
+                                           Register receiver,
+                                           Register name,
+                                           Register scratch1,
+                                           Register scratch2,
+                                           Label* miss_label) {
    // Check that the receiver isn't a smi.
    __ test(receiver, Immediate(kSmiTagMask));
    __ j(zero, miss_label, not_taken);
@@ -340,12 +360,15 @@
    __ push(receiver);  // receiver
    __ push(reg);  // holder
    __ push(name);  // name
+  // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or
+  // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method?
+  __ push(Immediate(lookup_hint));
    __ push(scratch2);  // restore return address

    // Do tail-call to the runtime system.
    ExternalReference load_ic_property =
        ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
-  __ TailCallRuntime(load_ic_property, 3);
+  __ TailCallRuntime(load_ic_property, 4);
  }


@@ -670,11 +693,12 @@
    __ push(edx);  // receiver
    __ push(reg);  // holder
    __ push(Operand(ebp, (argc + 3) * kPointerSize));  // name
+  __ push(Immediate(holder->InterceptorPropertyLookupHint(name)));

    // Perform call.
    ExternalReference load_interceptor =
        ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
-  __ mov(eax, Immediate(3));
+  __ mov(eax, Immediate(4));
    __ mov(ebx, Immediate(load_interceptor));

    CEntryStub stub;
@@ -974,7 +998,18 @@
    Label miss;

    __ mov(eax, (Operand(esp, kPointerSize)));
-  GenerateLoadInterceptor(masm(), receiver, holder, eax, ecx, edx, ebx,  
&miss);
+  // TODO(368): Compile in the whole chain: all the interceptors in
+  // prototypes and ultimate answer.
+  GenerateLoadInterceptor(masm(),
+                          receiver,
+                          holder,
+                          holder->InterceptorPropertyLookupHint(name),
+                          eax,
+                          ecx,
+                          edx,
+                          ebx,
+                          &miss);
+
    __ bind(&miss);
    GenerateLoadMiss(masm(), Code::LOAD_IC);


Modified: branches/bleeding_edge/src/objects.h
==============================================================================
--- branches/bleeding_edge/src/objects.h        (original)
+++ branches/bleeding_edge/src/objects.h        Wed Jun  3 05:04:53 2009
@@ -1349,6 +1349,14 @@
    Object* LookupCallbackSetterInPrototypes(uint32_t index);
    void LookupCallback(String* name, LookupResult* result);

+  inline Smi* InterceptorPropertyLookupHint(String* name);
+  Object* GetInterceptorPropertyWithLookupHint(JSObject* receiver,
+                                               Smi* lookup_hint,
+                                               String* name,
+                                               PropertyAttributes*  
attributes);
+  static const int kLookupInHolder = -1;
+  static const int kLookupInPrototype = -2;
+
    // Returns the number of properties on this object filtering out  
properties
    // with the specified attributes (ignoring interceptors).
    int NumberOfLocalProperties(PropertyAttributes filter);
@@ -1539,6 +1547,10 @@
    Object* DefineGetterSetter(String* name, PropertyAttributes attributes);

    void LookupInDescriptor(String* name, LookupResult* result);
+
+  Object* GetPropertyWithInterceptorProper(JSObject* receiver,
+                                           String* name,
+                                           PropertyAttributes* attributes);

    DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
  };

Modified: branches/bleeding_edge/src/stub-cache.h
==============================================================================
--- branches/bleeding_edge/src/stub-cache.h     (original)
+++ branches/bleeding_edge/src/stub-cache.h     Wed Jun  3 05:04:53 2009
@@ -356,6 +356,16 @@
                                        Register scratch1,
                                        Register scratch2,
                                        Label* miss_label);
+  // TODO(antonm): Remove a function above.
+  static void GenerateLoadInterceptor(MacroAssembler* masm,
+                                      JSObject* object,
+                                      JSObject* holder,
+                                      Smi* lookup_hint,
+                                      Register receiver,
+                                      Register name,
+                                      Register scratch1,
+                                      Register scratch2,
+                                      Label* miss_label);
    static void GenerateLoadArrayLength(MacroAssembler* masm,
                                        Register receiver,
                                        Register scratch,

Modified: branches/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-api.cc      (original)
+++ branches/bleeding_edge/test/cctest/test-api.cc      Wed Jun  3 05:04:53 2009
@@ -4844,6 +4844,90 @@
  }


+// Below go several tests which verify that JITing for various
+// configurations of interceptor and explicit fields works fine
+// (those cases are special cased to get better performance).
+
+static v8::Handle<Value> InterceptorLoadXICGetter(Local<String> name,
+                                                 const AccessorInfo& info)  
{
+  ApiTestFuzzer::Fuzz();
+  return v8_str("x")->Equals(name)
+      ? v8::Integer::New(42) : v8::Handle<v8::Value>();
+}
+
+
+static void CheckInterceptorLoadIC(const char* source, int expected) {
+  v8::HandleScope scope;
+  v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  LocalContext context;
+  context->Global()->Set(v8_str("o"), templ->NewInstance());
+  v8::Handle<Value> value = CompileRun(source);
+  CHECK_EQ(expected, value->Int32Value());
+}
+
+
+THREADED_TEST(InterceptorLoadICWithFieldOnHolder) {
+  CheckInterceptorLoadIC(
+    "var result = 0;"
+    "o.y = 239;"
+    "for (var i = 0; i < 1000; i++) {"
+    "  result = o.y;"
+    "}",
+    239);
+}
+
+
+THREADED_TEST(InterceptorLoadICWithSubstitutedProto) {
+  CheckInterceptorLoadIC(
+    "var result = 0;"
+    "o.__proto__ = { 'y': 239 };"
+    "for (var i = 0; i < 1000; i++) {"
+    "  result = o.y + o.x;"
+    "}",
+    239 + 42);
+}
+
+
+THREADED_TEST(InterceptorLoadICWithPropertyOnProto) {
+  CheckInterceptorLoadIC(
+    "var result = 0;"
+    "o.__proto__.y = 239;"
+    "for (var i = 0; i < 1000; i++) {"
+    "  result = o.y + o.x;"
+    "}",
+    239 + 42);
+}
+
+
+THREADED_TEST(InterceptorLoadICUndefined) {
+  CheckInterceptorLoadIC(
+    "var result = 0;"
+    "for (var i = 0; i < 1000; i++) {"
+    "  result = (o.y == undefined) ? 239 : 42;"
+    "}",
+    239);
+}
+
+
+THREADED_TEST(InterceptorLoadICWithOverride) {
+  CheckInterceptorLoadIC(
+    "fst = new Object();  fst.__proto__ = o;"
+    "snd = new Object();  snd.__proto__ = fst;"
+    "var result1 = 0;"
+    "for (var i = 0; i < 1000;  i++) {"
+    "  result1 = snd.x;"
+    "}"
+    "fst.x = 239;"
+    "var result = 0;"
+    "for (var i = 0; i < 1000; i++) {"
+    "  result = snd.x;"
+    "}"
+    "result + result1",
+    239 + 42);
+}
+
+
  static v8::Handle<Value> InterceptorStoreICSetter(
      Local<String> key, Local<Value> value, const AccessorInfo&) {
    CHECK(v8_str("x")->Equals(key));

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to