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

Side by Side 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, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 case CONSTANT_TRANSITION: 596 case CONSTANT_TRANSITION:
597 case NULL_DESCRIPTOR: 597 case NULL_DESCRIPTOR:
598 break; 598 break;
599 } 599 }
600 UNREACHABLE(); 600 UNREACHABLE();
601 return NULL; 601 return NULL;
602 } 602 }
603 603
604 604
605 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { 605 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
606 Object* holder = NULL; 606 Heap* heap = IsSmi()
607 if (IsSmi()) { 607 ? Isolate::Current()->heap()
608 Context* global_context = Isolate::Current()->context()->global_context(); 608 : HeapObject::cast(this)->GetHeap();
609 holder = global_context->number_function()->instance_prototype(); 609 Object* holder = this;
610 } else {
611 HeapObject* heap_object = HeapObject::cast(this);
612 610
613 if (heap_object->IsJSObject()) { 611 // Iterate up the prototype chain until an element is found or the null
614 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); 612 // prototype is encountered.
613 for (holder = this;
614 holder != heap->null_value();
615 holder = holder->GetPrototype()) {
616 if (holder->IsSmi()) {
617 Context* global_context = Isolate::Current()->context()->global_context();
618 holder = global_context->number_function()->instance_prototype();
619 } else {
620 HeapObject* heap_object = HeapObject::cast(holder);
621 if (!heap_object->IsJSObject()) {
622 Isolate* isolate = heap->isolate();
623 Context* global_context = isolate->context()->global_context();
624 if (heap_object->IsString()) {
625 holder = global_context->string_function()->instance_prototype();
626 } else if (heap_object->IsHeapNumber()) {
627 holder = global_context->number_function()->instance_prototype();
628 } else if (heap_object->IsBoolean()) {
629 holder = global_context->boolean_function()->instance_prototype();
630 } else if (heap_object->IsJSProxy()) {
631 return heap->undefined_value(); // For now...
632 } else {
633 // Undefined and null have no indexed properties.
634 ASSERT(heap_object->IsUndefined() || heap_object->IsNull());
635 return heap->undefined_value();
636 }
637 }
615 } 638 }
616 Heap* heap = heap_object->GetHeap();
617 Isolate* isolate = heap->isolate();
618 639
619 Context* global_context = isolate->context()->global_context(); 640 // Inline the case for JSObjects. Doing so significantly improves the
620 if (heap_object->IsString()) { 641 // performance of fetching elements where checking the prototype chain is
621 holder = global_context->string_function()->instance_prototype(); 642 // necessary.
622 } else if (heap_object->IsHeapNumber()) { 643 JSObject* js_object = JSObject::cast(holder);
623 holder = global_context->number_function()->instance_prototype(); 644
624 } else if (heap_object->IsBoolean()) { 645 // Check access rights if needed.
625 holder = global_context->boolean_function()->instance_prototype(); 646 if (js_object->IsAccessCheckNeeded()) {
626 } else if (heap_object->IsJSProxy()) { 647 Isolate* isolate = heap->isolate();
627 return heap->undefined_value(); // For now... 648 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
628 } else { 649 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
629 // Undefined and null have no indexed properties. 650 return heap->undefined_value();
630 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); 651 }
631 return heap->undefined_value(); 652 }
653
654 if (js_object->HasIndexedInterceptor()) {
655 return js_object->GetElementWithInterceptor(receiver, index);
656 }
657
658 if (js_object->elements() != heap->empty_fixed_array()) {
659 MaybeObject* result = js_object->GetElementsAccessor()->GetWithReceiver(
660 js_object,
661 receiver,
662 index);
663 if (result != heap->the_hole_value()) return result;
632 } 664 }
633 } 665 }
634 666
635 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); 667 return heap->undefined_value();
636 } 668 }
637 669
638 670
639 Object* Object::GetPrototype() { 671 Object* Object::GetPrototype() {
640 if (IsSmi()) { 672 if (IsSmi()) {
641 Heap* heap = Isolate::Current()->heap(); 673 Heap* heap = Isolate::Current()->heap();
642 Context* context = heap->isolate()->context()->global_context(); 674 Context* context = heap->isolate()->context()->global_context();
643 return context->number_function()->instance_prototype(); 675 return context->number_function()->instance_prototype();
644 } 676 }
645 677
(...skipping 8336 matching lines...) Expand 10 before | Expand all | Expand 10 after
8982 if (raw_result != heap->the_hole_value()) return raw_result; 9014 if (raw_result != heap->the_hole_value()) return raw_result;
8983 9015
8984 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 9016 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
8985 9017
8986 Object* pt = holder_handle->GetPrototype(); 9018 Object* pt = holder_handle->GetPrototype();
8987 if (pt == heap->null_value()) return heap->undefined_value(); 9019 if (pt == heap->null_value()) return heap->undefined_value();
8988 return pt->GetElementWithReceiver(*this_handle, index); 9020 return pt->GetElementWithReceiver(*this_handle, index);
8989 } 9021 }
8990 9022
8991 9023
8992 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver,
8993 uint32_t index) {
8994 // Check access rights if needed.
8995 if (IsAccessCheckNeeded()) {
8996 Heap* heap = GetHeap();
8997 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) {
8998 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET);
8999 return heap->undefined_value();
9000 }
9001 }
9002
9003 if (HasIndexedInterceptor()) {
9004 return GetElementWithInterceptor(receiver, index);
9005 }
9006
9007 Heap* heap = GetHeap();
9008 if (elements() != heap->empty_fixed_array()) {
9009 MaybeObject* result = GetElementsAccessor()->GetWithReceiver(this,
9010 receiver,
9011 index);
9012 if (result != heap->the_hole_value()) return result;
9013 }
9014
9015 Object* pt = GetPrototype();
9016 if (pt == heap->null_value()) return heap->undefined_value();
9017 return pt->GetElementWithReceiver(receiver, index);
9018 }
9019
9020
9021 bool JSObject::HasDenseElements() { 9024 bool JSObject::HasDenseElements() {
9022 int capacity = 0; 9025 int capacity = 0;
9023 int used = 0; 9026 int used = 0;
9024 GetElementsCapacityAndUsage(&capacity, &used); 9027 GetElementsCapacityAndUsage(&capacity, &used);
9025 return (capacity == 0) || (used > (capacity / 2)); 9028 return (capacity == 0) || (used > (capacity / 2));
9026 } 9029 }
9027 9030
9028 9031
9029 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { 9032 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
9030 *capacity = 0; 9033 *capacity = 0;
(...skipping 2855 matching lines...) Expand 10 before | Expand all | Expand 10 after
11886 if (break_point_objects()->IsUndefined()) return 0; 11889 if (break_point_objects()->IsUndefined()) return 0;
11887 // Single break point. 11890 // Single break point.
11888 if (!break_point_objects()->IsFixedArray()) return 1; 11891 if (!break_point_objects()->IsFixedArray()) return 1;
11889 // Multiple break points. 11892 // Multiple break points.
11890 return FixedArray::cast(break_point_objects())->length(); 11893 return FixedArray::cast(break_point_objects())->length();
11891 } 11894 }
11892 #endif 11895 #endif
11893 11896
11894 11897
11895 } } // namespace v8::internal 11898 } } // namespace v8::internal
OLDNEW
« 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