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

Side by Side Diff: src/objects.cc

Issue 24250005: AllocationSites for all literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 7 years, 2 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "accessors.h" 30 #include "accessors.h"
31 #include "allocation-site-scopes.h"
31 #include "api.h" 32 #include "api.h"
32 #include "arguments.h" 33 #include "arguments.h"
33 #include "bootstrapper.h" 34 #include "bootstrapper.h"
34 #include "codegen.h" 35 #include "codegen.h"
35 #include "cpu-profiler.h" 36 #include "cpu-profiler.h"
36 #include "debug.h" 37 #include "debug.h"
37 #include "deoptimizer.h" 38 #include "deoptimizer.h"
38 #include "date.h" 39 #include "date.h"
39 #include "elements.h" 40 #include "elements.h"
40 #include "execution.h" 41 #include "execution.h"
(...skipping 5524 matching lines...) Expand 10 before | Expand all | Expand 10 after
5565 MaybeObject* maybe_copy = map()->Copy(); 5566 MaybeObject* maybe_copy = map()->Copy();
5566 if (!maybe_copy->To(&new_map)) return maybe_copy; 5567 if (!maybe_copy->To(&new_map)) return maybe_copy;
5567 new_map->set_is_observed(true); 5568 new_map->set_is_observed(true);
5568 } 5569 }
5569 set_map(new_map); 5570 set_map(new_map);
5570 5571
5571 return heap->undefined_value(); 5572 return heap->undefined_value();
5572 } 5573 }
5573 5574
5574 5575
5576 Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
5577 AllocationSiteContext* site_context) {
5578 Isolate* isolate = object->GetIsolate();
5579 CALL_HEAP_FUNCTION(isolate,
5580 isolate->heap()->CopyJSObject(*object,
5581 *(site_context->current())),
5582 JSObject);
5583 }
5584
5585
5575 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5586 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5576 Isolate* isolate = object->GetIsolate(); 5587 Isolate* isolate = object->GetIsolate();
5577 CALL_HEAP_FUNCTION(isolate, 5588 CALL_HEAP_FUNCTION(isolate,
5578 isolate->heap()->CopyJSObject(*object), JSObject); 5589 isolate->heap()->CopyJSObject(*object), JSObject);
5579 } 5590 }
5580 5591
5581 5592
5582 class JSObjectWalkVisitor { 5593 class JSObjectWalkVisitor {
5583 public: 5594 public:
5584 explicit JSObjectWalkVisitor() {} 5595 explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) :
5596 site_context_(site_context) {}
5585 virtual ~JSObjectWalkVisitor() {} 5597 virtual ~JSObjectWalkVisitor() {}
5586 5598
5587 Handle<JSObject> Visit(Handle<JSObject> object) { 5599 Handle<JSObject> Visit(Handle<JSObject> object) {
5588 return StructureWalk(object); 5600 return StructureWalk(object);
5589 } 5601 }
5590 5602
5591 // Returns true if the visitor is a copying visitor.
5592 virtual bool is_copying() = 0; 5603 virtual bool is_copying() = 0;
5593 5604
5594 protected: 5605 protected:
5595 Handle<JSObject> StructureWalk(Handle<JSObject> object); 5606 Handle<JSObject> StructureWalk(Handle<JSObject> object);
5596 5607
5597 // The returned handle should point to a new object if the visitor is a 5608 // The returned handle will be used for the object in all
5598 // copying visitor, otherwise it should be the same as the input object. 5609 // subsequent usages. This allows VisitObject to make a copy
5610 // of the object if desired.
5599 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; 5611 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
5600
5601 // The returned handle should point to a new value if the visitor is a
5602 // copying visitor, otherwise it should be the same as the input value.
5603 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, 5612 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
5604 Handle<JSObject> value) = 0; 5613 Handle<JSObject> value) = 0;
5614
5615 AllocationSiteContext* site_context() { return site_context_; }
5616
5617 private:
5618 AllocationSiteContext* site_context_;
5605 }; 5619 };
5606 5620
5607 5621
5608 class JSObjectCopyVisitor: public JSObjectWalkVisitor { 5622 class JSObjectCopyVisitor: public JSObjectWalkVisitor {
5609 public: 5623 public:
5610 explicit JSObjectCopyVisitor() {} 5624 explicit JSObjectCopyVisitor(AllocationSiteContext* site_context)
5625 : JSObjectWalkVisitor(site_context) {}
5611 5626
5612 virtual bool is_copying() V8_OVERRIDE { return true; } 5627 virtual bool is_copying() V8_OVERRIDE { return true; }
5613 5628
5614 protected: 5629 // The returned handle will be used for the object in all
5630 // subsequent usages. This allows VisitObject to make a copy
5631 // of the object if desired.
5615 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { 5632 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5616 return JSObject::Copy(object); 5633 // Only create a memento if
5634 // 1) we have a JSArray, and
Hannes Payer (out of office) 2013/10/11 12:55:44 What about JSObject?
mvstanton 2013/10/11 13:41:47 At this moment in the code, we only emit mementos
5635 // 2) the elements kind is palatable
5636 // 3) allow_mementos is true
5637 Handle<JSObject> copy;
5638 if (site_context()->activated() &&
5639 AllocationSite::CanTrack(object->map()->instance_type()) &&
5640 AllocationSite::GetMode(object->GetElementsKind()) ==
5641 TRACK_ALLOCATION_SITE) {
5642 copy = JSObject::Copy(object, site_context());
5643 } else {
5644 copy = JSObject::Copy(object);
5645 }
5646
5647 return copy;
5617 } 5648 }
5618 5649
5619 virtual Handle<JSObject> VisitElementOrProperty( 5650 virtual Handle<JSObject> VisitElementOrProperty(
5620 Handle<JSObject> object, 5651 Handle<JSObject> object,
5621 Handle<JSObject> value) V8_OVERRIDE { 5652 Handle<JSObject> value) V8_OVERRIDE {
5622 return StructureWalk(value); 5653 AllocationSiteUsageScope scope(site_context(), value);
5654 value = StructureWalk(value);
5655 return value;
5623 } 5656 }
5624 }; 5657 };
5625 5658
5659
5660 class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor {
5661 public:
5662 explicit JSObjectCreateAllocationSitesVisitor(
5663 AllocationSiteContext* site_context)
5664 : JSObjectWalkVisitor(site_context) {}
5665
5666 virtual bool is_copying() V8_OVERRIDE { return false; }
5667
5668 // The returned handle will be used for the object in all
5669 // subsequent usages. This allows VisitObject to make a copy
5670 // of the object if desired.
5671 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5672 return object;
5673 }
5674
5675 virtual Handle<JSObject> VisitElementOrProperty(
5676 Handle<JSObject> object,
5677 Handle<JSObject> value) V8_OVERRIDE {
5678 AllocationSiteCreationScope scope(site_context());
5679 value = StructureWalk(value);
5680 if (!value.is_null()) {
5681 scope.RecordTransitionInfo(value);
5682 }
5683 return value;
5684 }
5685 };
5686
5626 5687
5627 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { 5688 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
5628 bool copying = is_copying(); 5689 bool copying = is_copying();
5629 Isolate* isolate = object->GetIsolate(); 5690 Isolate* isolate = object->GetIsolate();
5630 StackLimitCheck check(isolate); 5691 StackLimitCheck check(isolate);
5631 if (check.HasOverflowed()) { 5692 if (check.HasOverflowed()) {
5632 isolate->StackOverflow(); 5693 isolate->StackOverflow();
5633 return Handle<JSObject>::null(); 5694 return Handle<JSObject>::null();
5634 } 5695 }
5635 5696
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5759 case EXTERNAL_DOUBLE_ELEMENTS: 5820 case EXTERNAL_DOUBLE_ELEMENTS:
5760 case FAST_DOUBLE_ELEMENTS: 5821 case FAST_DOUBLE_ELEMENTS:
5761 case FAST_HOLEY_DOUBLE_ELEMENTS: 5822 case FAST_HOLEY_DOUBLE_ELEMENTS:
5762 // No contained objects, nothing to do. 5823 // No contained objects, nothing to do.
5763 break; 5824 break;
5764 } 5825 }
5765 return copy; 5826 return copy;
5766 } 5827 }
5767 5828
5768 5829
5769 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { 5830 Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object,
5770 JSObjectCopyVisitor v; 5831 AllocationSiteContext* site_context) {
5832 JSObjectCreateAllocationSitesVisitor v(site_context);
5833 Handle<JSObject> copy = v.Visit(object);
5834 ASSERT(!v.is_copying() && copy.is_identical_to(object));
5835 return copy;
5836 }
5837
5838
5839 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
5840 AllocationSiteContext* site_context) {
5841 JSObjectCopyVisitor v(site_context);
5771 Handle<JSObject> copy = v.Visit(object); 5842 Handle<JSObject> copy = v.Visit(object);
5772 ASSERT(v.is_copying() && !copy.is_identical_to(object)); 5843 ASSERT(v.is_copying() && !copy.is_identical_to(object));
5773 return copy; 5844 return copy;
5774 } 5845 }
5775 5846
5776 5847
5777 // Tests for the fast common case for property enumeration: 5848 // Tests for the fast common case for property enumeration:
5778 // - This object and all prototypes has an enum cache (which means that 5849 // - This object and all prototypes has an enum cache (which means that
5779 // it is no proxy, has no interceptors and needs no access checks). 5850 // it is no proxy, has no interceptors and needs no access checks).
5780 // - This object has no elements. 5851 // - This object has no elements.
(...skipping 6744 matching lines...) Expand 10 before | Expand all | Expand 10 after
12525 return this; 12596 return this;
12526 } 12597 }
12527 12598
12528 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); 12599 AllocationMemento* memento = AllocationMemento::FindForJSObject(this);
12529 if (memento == NULL || !memento->IsValid()) { 12600 if (memento == NULL || !memento->IsValid()) {
12530 return this; 12601 return this;
12531 } 12602 }
12532 12603
12533 // Walk through to the Allocation Site 12604 // Walk through to the Allocation Site
12534 AllocationSite* site = memento->GetAllocationSite(); 12605 AllocationSite* site = memento->GetAllocationSite();
12535 if (site->IsLiteralSite()) { 12606 if (site->IsLiteralSite() &&
12607 site->transition_info()->IsJSArray()) {
12536 JSArray* transition_info = JSArray::cast(site->transition_info()); 12608 JSArray* transition_info = JSArray::cast(site->transition_info());
12609 bool is_nested = !(site->nested_site()->IsSmi());
12537 ElementsKind kind = transition_info->GetElementsKind(); 12610 ElementsKind kind = transition_info->GetElementsKind();
12538 // if kind is holey ensure that to_kind is as well. 12611 // if kind is holey ensure that to_kind is as well.
12539 if (IsHoleyElementsKind(kind)) { 12612 if (IsHoleyElementsKind(kind)) {
12540 to_kind = GetHoleyElementsKind(to_kind); 12613 to_kind = GetHoleyElementsKind(to_kind);
12541 } 12614 }
12542 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12615 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12543 // If the array is huge, it's not likely to be defined in a local 12616 // If the array is huge, it's not likely to be defined in a local
12544 // function, so we shouldn't make new instances of it very often. 12617 // function, so we shouldn't make new instances of it very often.
12545 uint32_t length = 0; 12618 uint32_t length = 0;
12546 CHECK(transition_info->length()->ToArrayIndex(&length)); 12619 CHECK(transition_info->length()->ToArrayIndex(&length));
12547 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { 12620 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
12548 if (FLAG_trace_track_allocation_sites) { 12621 if (FLAG_trace_track_allocation_sites) {
12549 PrintF( 12622 PrintF(
12550 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", 12623 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
12551 reinterpret_cast<void*>(this), 12624 reinterpret_cast<void*>(this),
12625 is_nested ? "(nested)" : "",
12552 ElementsKindToString(kind), 12626 ElementsKindToString(kind),
12553 ElementsKindToString(to_kind)); 12627 ElementsKindToString(to_kind));
12554 } 12628 }
12555 return transition_info->TransitionElementsKind(to_kind); 12629 return transition_info->TransitionElementsKind(to_kind);
12556 } 12630 }
12557 } 12631 }
12558 } else { 12632 } else {
12559 ElementsKind kind = site->GetElementsKind(); 12633 ElementsKind kind = site->GetElementsKind();
12560 // if kind is holey ensure that to_kind is as well. 12634 // if kind is holey ensure that to_kind is as well.
12561 if (IsHoleyElementsKind(kind)) { 12635 if (IsHoleyElementsKind(kind)) {
(...skipping 3659 matching lines...) Expand 10 before | Expand all | Expand 10 after
16221 #define ERROR_MESSAGES_TEXTS(C, T) T, 16295 #define ERROR_MESSAGES_TEXTS(C, T) T,
16222 static const char* error_messages_[] = { 16296 static const char* error_messages_[] = {
16223 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16297 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16224 }; 16298 };
16225 #undef ERROR_MESSAGES_TEXTS 16299 #undef ERROR_MESSAGES_TEXTS
16226 return error_messages_[reason]; 16300 return error_messages_[reason];
16227 } 16301 }
16228 16302
16229 16303
16230 } } // namespace v8::internal 16304 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698