Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Unified Diff: src/objects.cc

Issue 7569001: Fix performance regression due to elements refactor (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 26736d9e6860083a699cc7fd9f4ecdefabb22d58..e5a5bd5c09fbe365f4d6751d967bc92b2abfdf90 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -603,36 +603,68 @@ MaybeObject* Object::GetProperty(Object* receiver,
MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
- Object* holder = NULL;
- if (IsSmi()) {
- Context* global_context = Isolate::Current()->context()->global_context();
- holder = global_context->number_function()->instance_prototype();
- } else {
- HeapObject* heap_object = HeapObject::cast(this);
+ Heap* heap = IsSmi()
+ ? Isolate::Current()->heap()
+ : HeapObject::cast(this)->GetHeap();
+ Object* holder = this;
+
+ // Iterate up the prototype chain until an element is found or the null
+ // prototype is encountered.
+ for (holder = this;
+ holder != heap->null_value();
+ holder = holder->GetPrototype()) {
+ if (holder->IsSmi()) {
+ Context* global_context = Isolate::Current()->context()->global_context();
+ holder = global_context->number_function()->instance_prototype();
+ } else {
+ HeapObject* heap_object = HeapObject::cast(holder);
+ if (!heap_object->IsJSObject()) {
+ Isolate* isolate = heap->isolate();
+ Context* global_context = isolate->context()->global_context();
+ if (heap_object->IsString()) {
+ holder = global_context->string_function()->instance_prototype();
+ } else if (heap_object->IsHeapNumber()) {
+ holder = global_context->number_function()->instance_prototype();
+ } else if (heap_object->IsBoolean()) {
+ holder = global_context->boolean_function()->instance_prototype();
+ } else if (heap_object->IsJSProxy()) {
+ return heap->undefined_value(); // For now...
+ } else {
+ // Undefined and null have no indexed properties.
+ ASSERT(heap_object->IsUndefined() || heap_object->IsNull());
+ return heap->undefined_value();
+ }
+ }
+ }
- if (heap_object->IsJSObject()) {
- return JSObject::cast(this)->GetElementWithReceiver(receiver, index);
+ // Inline the case for JSObjects. Doing so significantly improves the
+ // performance of fetching elements where checking the prototype chain is
+ // necessary.
+ JSObject* js_object = JSObject::cast(holder);
+
+ // Check access rights if needed.
+ if (js_object->IsAccessCheckNeeded()) {
+ Isolate* isolate = heap->isolate();
+ if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
+ return heap->undefined_value();
+ }
}
- Heap* heap = heap_object->GetHeap();
- Isolate* isolate = heap->isolate();
- Context* global_context = isolate->context()->global_context();
- if (heap_object->IsString()) {
- holder = global_context->string_function()->instance_prototype();
- } else if (heap_object->IsHeapNumber()) {
- holder = global_context->number_function()->instance_prototype();
- } else if (heap_object->IsBoolean()) {
- holder = global_context->boolean_function()->instance_prototype();
- } else if (heap_object->IsJSProxy()) {
- return heap->undefined_value(); // For now...
- } else {
- // Undefined and null have no indexed properties.
- ASSERT(heap_object->IsUndefined() || heap_object->IsNull());
- return heap->undefined_value();
+ if (js_object->HasIndexedInterceptor()) {
+ return js_object->GetElementWithInterceptor(receiver, index);
+ }
+
+ if (js_object->elements() != heap->empty_fixed_array()) {
+ MaybeObject* result = js_object->GetElementsAccessor()->GetWithReceiver(
+ js_object,
+ receiver,
+ index);
+ if (result != heap->the_hole_value()) return result;
}
}
- return JSObject::cast(holder)->GetElementWithReceiver(receiver, index);
+ return heap->undefined_value();
}
@@ -8989,35 +9021,6 @@ MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver,
}
-MaybeObject* JSObject::GetElementWithReceiver(Object* receiver,
- uint32_t index) {
- // Check access rights if needed.
- if (IsAccessCheckNeeded()) {
- Heap* heap = GetHeap();
- if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) {
- heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET);
- return heap->undefined_value();
- }
- }
-
- if (HasIndexedInterceptor()) {
- return GetElementWithInterceptor(receiver, index);
- }
-
- Heap* heap = GetHeap();
- if (elements() != heap->empty_fixed_array()) {
- MaybeObject* result = GetElementsAccessor()->GetWithReceiver(this,
- receiver,
- index);
- if (result != heap->the_hole_value()) return result;
- }
-
- Object* pt = GetPrototype();
- if (pt == heap->null_value()) return heap->undefined_value();
- return pt->GetElementWithReceiver(receiver, index);
-}
-
-
bool JSObject::HasDenseElements() {
int capacity = 0;
int used = 0;
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698