Line data Source code
1 : // Copyright 2013 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_ALLOCATION_SITE_SCOPES_H_
6 : #define V8_ALLOCATION_SITE_SCOPES_H_
7 :
8 : #include "src/handles.h"
9 : #include "src/objects.h"
10 : #include "src/objects/map.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // AllocationSiteContext is the base class for walking and copying a nested
16 : // boilerplate with AllocationSite and AllocationMemento support.
17 : class AllocationSiteContext {
18 : public:
19 : explicit AllocationSiteContext(Isolate* isolate) {
20 1200318 : isolate_ = isolate;
21 : }
22 :
23 : Handle<AllocationSite> top() { return top_; }
24 : Handle<AllocationSite> current() { return current_; }
25 :
26 : bool ShouldCreateMemento(Handle<JSObject> object) { return false; }
27 :
28 : Isolate* isolate() { return isolate_; }
29 :
30 : protected:
31 : void update_current_site(AllocationSite* site) {
32 1318611 : *(current_.location()) = site;
33 : }
34 :
35 2400636 : void InitializeTraversal(Handle<AllocationSite> site) {
36 1200318 : top_ = site;
37 : // {current_} is updated in place to not create unnecessary Handles, hence
38 : // we initially need a separate handle.
39 1200318 : current_ = Handle<AllocationSite>::New(*top_, isolate());
40 1200318 : }
41 :
42 : private:
43 : Isolate* isolate_;
44 : Handle<AllocationSite> top_;
45 : Handle<AllocationSite> current_;
46 : };
47 :
48 :
49 : // AllocationSiteUsageContext aids in the creation of AllocationMementos placed
50 : // behind some/all components of a copied object literal.
51 : class AllocationSiteUsageContext : public AllocationSiteContext {
52 : public:
53 : AllocationSiteUsageContext(Isolate* isolate, Handle<AllocationSite> site,
54 : bool activated)
55 : : AllocationSiteContext(isolate),
56 : top_site_(site),
57 1002370 : activated_(activated) { }
58 :
59 2272872 : inline Handle<AllocationSite> EnterNewScope() {
60 4545744 : if (top().is_null()) {
61 1002370 : InitializeTraversal(top_site_);
62 : } else {
63 : // Advance current site
64 : Object* nested_site = current()->nested_site();
65 : // Something is wrong if we advance to the end of the list here.
66 : update_current_site(AllocationSite::cast(nested_site));
67 : }
68 2272872 : return Handle<AllocationSite>(*current(), isolate());
69 : }
70 :
71 : inline void ExitScope(Handle<AllocationSite> scope_site,
72 : Handle<JSObject> object) {
73 : // This assert ensures that we are pointing at the right sub-object in a
74 : // recursive walk of a nested literal.
75 : DCHECK(object.is_null() || *object == scope_site->boilerplate());
76 : }
77 :
78 2267681 : bool ShouldCreateMemento(Handle<JSObject> object) {
79 4388486 : if (activated_ &&
80 : AllocationSite::CanTrack(object->map()->instance_type())) {
81 2120805 : if (FLAG_allocation_site_pretenuring ||
82 : AllocationSite::ShouldTrack(object->GetElementsKind())) {
83 : if (FLAG_trace_creation_allocation_sites) {
84 : PrintF("*** Creating Memento for %s %p\n",
85 : object->IsJSArray() ? "JSArray" : "JSObject",
86 : static_cast<void*>(*object));
87 : }
88 : return true;
89 : }
90 : }
91 : return false;
92 : }
93 :
94 : static const bool kCopying = true;
95 :
96 : private:
97 : Handle<AllocationSite> top_site_;
98 : bool activated_;
99 : };
100 :
101 :
102 : } // namespace internal
103 : } // namespace v8
104 :
105 : #endif // V8_ALLOCATION_SITE_SCOPES_H_
|