• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
AllocationSiteContext(Isolate * isolate)19   explicit AllocationSiteContext(Isolate* isolate) {
20     isolate_ = isolate;
21   }
22 
top()23   Handle<AllocationSite> top() { return top_; }
current()24   Handle<AllocationSite> current() { return current_; }
25 
ShouldCreateMemento(Handle<JSObject> object)26   bool ShouldCreateMemento(Handle<JSObject> object) { return false; }
27 
isolate()28   Isolate* isolate() { return isolate_; }
29 
30  protected:
update_current_site(AllocationSite * site)31   void update_current_site(AllocationSite* site) {
32     *(current_.location()) = site;
33   }
34 
InitializeTraversal(Handle<AllocationSite> site)35   void InitializeTraversal(Handle<AllocationSite> site) {
36     top_ = site;
37     // {current_} is updated in place to not create unnecessary Handles, hence
38     // we initially need a separate handle.
39     current_ = Handle<AllocationSite>::New(*top_, isolate());
40   }
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:
AllocationSiteUsageContext(Isolate * isolate,Handle<AllocationSite> site,bool activated)53   AllocationSiteUsageContext(Isolate* isolate, Handle<AllocationSite> site,
54                              bool activated)
55       : AllocationSiteContext(isolate),
56         top_site_(site),
57         activated_(activated) { }
58 
EnterNewScope()59   inline Handle<AllocationSite> EnterNewScope() {
60     if (top().is_null()) {
61       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     return Handle<AllocationSite>(*current(), isolate());
69   }
70 
ExitScope(Handle<AllocationSite> scope_site,Handle<JSObject> object)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 
ShouldCreateMemento(Handle<JSObject> object)78   bool ShouldCreateMemento(Handle<JSObject> object) {
79     if (activated_ &&
80         AllocationSite::CanTrack(object->map()->instance_type())) {
81       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_
106