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
11namespace v8 {
12namespace internal {
13
14
15// AllocationSiteContext is the base class for walking and copying a nested
16// boilerplate with AllocationSite and AllocationMemento support.
17class AllocationSiteContext {
18 public:
19  explicit AllocationSiteContext(Isolate* isolate) {
20    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    *(current_.location()) = site;
33  }
34
35  void InitializeTraversal(Handle<AllocationSite> site) {
36    top_ = site;
37    current_ = Handle<AllocationSite>::New(*top_, isolate());
38  }
39
40 private:
41  Isolate* isolate_;
42  Handle<AllocationSite> top_;
43  Handle<AllocationSite> current_;
44};
45
46
47// AllocationSiteCreationContext aids in the creation of AllocationSites to
48// accompany object literals.
49class AllocationSiteCreationContext : public AllocationSiteContext {
50 public:
51  explicit AllocationSiteCreationContext(Isolate* isolate)
52      : AllocationSiteContext(isolate) { }
53
54  Handle<AllocationSite> EnterNewScope();
55  void ExitScope(Handle<AllocationSite> site, Handle<JSObject> object);
56};
57
58
59// AllocationSiteUsageContext aids in the creation of AllocationMementos placed
60// behind some/all components of a copied object literal.
61class AllocationSiteUsageContext : public AllocationSiteContext {
62 public:
63  AllocationSiteUsageContext(Isolate* isolate, Handle<AllocationSite> site,
64                             bool activated)
65      : AllocationSiteContext(isolate),
66        top_site_(site),
67        activated_(activated) { }
68
69  inline Handle<AllocationSite> EnterNewScope() {
70    if (top().is_null()) {
71      InitializeTraversal(top_site_);
72    } else {
73      // Advance current site
74      Object* nested_site = current()->nested_site();
75      // Something is wrong if we advance to the end of the list here.
76      update_current_site(AllocationSite::cast(nested_site));
77    }
78    return Handle<AllocationSite>(*current(), isolate());
79  }
80
81  inline void ExitScope(Handle<AllocationSite> scope_site,
82                        Handle<JSObject> object) {
83    // This assert ensures that we are pointing at the right sub-object in a
84    // recursive walk of a nested literal.
85    DCHECK(object.is_null() || *object == scope_site->transition_info());
86  }
87
88  bool ShouldCreateMemento(Handle<JSObject> object);
89
90 private:
91  Handle<AllocationSite> top_site_;
92  bool activated_;
93};
94
95
96}  // namespace internal
97}  // namespace v8
98
99#endif  // V8_ALLOCATION_SITE_SCOPES_H_
100