In case of holder with fast properties that allows to fetch the property
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 3 Jun 2009 11:25:34 +0000 (11:25 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 3 Jun 2009 11:25:34 +0000 (11:25 +0000)
immediately if holder has this property or saves binary search on holder if
property doesn't belong to holder.  Of course, in the cases when named getter
returns nothing.

That gives ~20% for dom benchmark/Document Object String Get, speeds up overall
dom_perf (not dramatically) and overall score for peacekeeper.  Strange, but DOM
part of peacekeepr runs somewhat slower.
Review URL: http://codereview.chromium.org/118118

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2093 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects-inl.h
src/objects.cc
src/stub-cache.cc

index 475b57bf82c31cf68290caaacf8885332df074a9..242c0985889746bc86e400281cc52fabfdcdcf8f 100644 (file)
@@ -2554,6 +2554,24 @@ bool JSObject::HasElement(uint32_t index) {
 }
 
 
+Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
+  // TODO(antonm): Do we want to do any shortcuts for global object?
+  if (HasFastProperties()) {
+    LookupResult lookup;
+    LocalLookupRealNamedProperty(name, &lookup);
+    if (lookup.IsValid()) {
+      if (lookup.type() == FIELD && lookup.IsCacheable()) {
+        return Smi::FromInt(lookup.GetFieldIndex());
+      }
+    } else {
+      return Smi::FromInt(kLookupInPrototype);
+    }
+  }
+
+  return Smi::FromInt(kLookupInHolder);
+}
+
+
 bool AccessorInfo::all_can_read() {
   return BooleanBit::get(flag(), kAllCanReadBit);
 }
index a3526ebc46690f7b1d37e96ef7d87f101773bc60..e8e0cafdb1bfdb217ee837c104526df17278e928 100644 (file)
@@ -5617,9 +5617,10 @@ Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver,
 }
 
 
-Object* JSObject::GetPropertyWithInterceptor(JSObject* receiver,
-                                             String* name,
-                                             PropertyAttributes* attributes) {
+Object* JSObject::GetPropertyWithInterceptorProper(
+    JSObject* receiver,
+    String* name,
+    PropertyAttributes* attributes) {
   HandleScope scope;
   Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
   Handle<JSObject> receiver_handle(receiver);
@@ -5647,12 +5648,75 @@ Object* JSObject::GetPropertyWithInterceptor(JSObject* receiver,
     }
   }
 
-  Object* raw_result = holder_handle->GetPropertyPostInterceptor(
+  return NULL;
+}
+
+
+Object* JSObject::GetInterceptorPropertyWithLookupHint(
+    JSObject* receiver,
+    Smi* lookup_hint,
+    String* name,
+    PropertyAttributes* attributes) {
+  HandleScope scope;
+  Handle<JSObject> receiver_handle(receiver);
+  Handle<JSObject> holder_handle(this);
+  Handle<String> name_handle(name);
+
+  Object* result = GetPropertyWithInterceptorProper(receiver, name, attributes);
+  if (result) return result;
+
+  int property_index = lookup_hint->value();
+  if (property_index >= 0) {
+    result = holder_handle->FastPropertyAt(property_index);
+  } else {
+    switch (property_index) {
+      case kLookupInPrototype: {
+          Object* pt = holder_handle->GetPrototype();
+          *attributes = ABSENT;
+          if (pt == Heap::null_value()) return Heap::undefined_value();
+          result = pt->GetPropertyWithReceiver(
+              *receiver_handle,
+              *name_handle,
+              attributes);
+          RETURN_IF_SCHEDULED_EXCEPTION();
+        }
+        break;
+
+      case kLookupInHolder:
+        result = holder_handle->GetPropertyPostInterceptor(
+            *receiver_handle,
+            *name_handle,
+            attributes);
+        RETURN_IF_SCHEDULED_EXCEPTION();
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  return result;
+}
+
+
+Object* JSObject::GetPropertyWithInterceptor(
+    JSObject* receiver,
+    String* name,
+    PropertyAttributes* attributes) {
+  HandleScope scope;
+  Handle<JSObject> receiver_handle(receiver);
+  Handle<JSObject> holder_handle(this);
+  Handle<String> name_handle(name);
+
+  Object* result = GetPropertyWithInterceptorProper(receiver, name, attributes);
+  if (result) return result;
+
+  result = holder_handle->GetPropertyPostInterceptor(
       *receiver_handle,
       *name_handle,
       attributes);
   RETURN_IF_SCHEDULED_EXCEPTION();
-  return raw_result;
+  return result;
 }
 
 
index ca14d1a5fbb10b485f9261476d728ab947be71bc..f7e5456ef85c518389e1f87fe411aed35078cb3f 100644 (file)
@@ -719,10 +719,12 @@ Object* LoadInterceptorProperty(Arguments args) {
   JSObject* recv = JSObject::cast(args[0]);
   JSObject* holder = JSObject::cast(args[1]);
   String* name = String::cast(args[2]);
+  Smi* lookup_hint = Smi::cast(args[3]);
   ASSERT(holder->HasNamedInterceptor());
   PropertyAttributes attr = NONE;
-  Object* result = holder->GetPropertyWithInterceptor(recv, name, &attr);
 
+  Object* result = holder->GetInterceptorPropertyWithLookupHint(
+      recv, lookup_hint, name, &attr);
   if (result->IsFailure()) return result;
 
   // If the property is present, return it.