Line data Source code
1 : // Copyright 2006-2008 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_HANDLES_INL_H_
6 : #define V8_HANDLES_INL_H_
7 :
8 : #include "src/api.h"
9 : #include "src/handles.h"
10 : #include "src/isolate.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : HandleBase::HandleBase(Object* object, Isolate* isolate)
16 442360109 : : location_(HandleScope::GetHandle(isolate, object)) {}
17 :
18 :
19 : template <typename T>
20 : // Allocate a new handle for the object, do not canonicalize.
21 : Handle<T> Handle<T>::New(T* object, Isolate* isolate) {
22 : return Handle(
23 : reinterpret_cast<T**>(HandleScope::CreateHandle(isolate, object)));
24 : }
25 :
26 :
27 308081540 : HandleScope::HandleScope(Isolate* isolate) {
28 : HandleScopeData* data = isolate->handle_scope_data();
29 330386531 : isolate_ = isolate;
30 625082042 : prev_next_ = data->next;
31 625082625 : prev_limit_ = data->limit;
32 625082625 : data->level++;
33 308081540 : }
34 :
35 : template <typename T>
36 : Handle<T>::Handle(T* object, Isolate* isolate) : HandleBase(object, isolate) {}
37 :
38 : template <typename T>
39 : inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) {
40 0 : return os << Brief(*handle);
41 : }
42 :
43 :
44 308081544 : HandleScope::~HandleScope() {
45 : #ifdef DEBUG
46 : if (FLAG_check_handle_count) {
47 : int before = NumberOfHandles(isolate_);
48 : CloseScope(isolate_, prev_next_, prev_limit_);
49 : int after = NumberOfHandles(isolate_);
50 : DCHECK(after - before < kCheckHandleThreshold);
51 : DCHECK(before < kCheckHandleThreshold);
52 : } else {
53 : #endif // DEBUG
54 624867943 : CloseScope(isolate_, prev_next_, prev_limit_);
55 : #ifdef DEBUG
56 : }
57 : #endif // DEBUG
58 308081538 : }
59 :
60 :
61 1382210522 : void HandleScope::CloseScope(Isolate* isolate,
62 : Object** prev_next,
63 : Object** prev_limit) {
64 : HandleScopeData* current = isolate->handle_scope_data();
65 :
66 : std::swap(current->next, prev_next);
67 1382210522 : current->level--;
68 1382210522 : if (current->limit != prev_limit) {
69 1166666 : current->limit = prev_limit;
70 1166666 : DeleteExtensions(isolate);
71 : #ifdef ENABLE_HANDLE_ZAPPING
72 1166670 : ZapRange(current->next, prev_limit);
73 : } else {
74 1381043856 : ZapRange(current->next, prev_next);
75 : #endif
76 : }
77 1382210532 : }
78 :
79 :
80 : template <typename T>
81 21161511 : Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) {
82 21161511 : HandleScopeData* current = isolate_->handle_scope_data();
83 :
84 : T* value = *handle_value;
85 : // Throw away all handles in the current scope.
86 21161511 : CloseScope(isolate_, prev_next_, prev_limit_);
87 : // Allocate one handle in the parent scope.
88 : DCHECK(current->level > current->sealed_level);
89 21161513 : Handle<T> result(value, isolate_);
90 : // Reinitialize the current scope (so that it's ready
91 : // to be used or closed again).
92 21161511 : prev_next_ = current->next;
93 21161511 : prev_limit_ = current->limit;
94 21161511 : current->level++;
95 21161511 : return result;
96 : }
97 :
98 : Object** HandleScope::CreateHandle(Isolate* isolate, Object* value) {
99 : DCHECK(AllowHandleAllocation::IsAllowed());
100 202096863 : HandleScopeData* data = isolate->handle_scope_data();
101 :
102 3285393430 : Object** result = data->next;
103 3285393430 : if (result == data->limit) result = Extend(isolate);
104 : // Update the current next field, set the value in the created
105 : // handle, and return the result.
106 : DCHECK(result < data->limit);
107 3285393382 : data->next = result + 1;
108 :
109 3285393382 : *result = value;
110 : return result;
111 : }
112 :
113 :
114 : Object** HandleScope::GetHandle(Isolate* isolate, Object* value) {
115 : DCHECK(AllowHandleAllocation::IsAllowed());
116 2980052180 : HandleScopeData* data = isolate->handle_scope_data();
117 3110523579 : CanonicalHandleScope* canonical = data->canonical_scope;
118 3110523579 : return canonical ? canonical->Lookup(value) : CreateHandle(isolate, value);
119 : }
120 :
121 :
122 : #ifdef DEBUG
123 : inline SealHandleScope::SealHandleScope(Isolate* isolate) : isolate_(isolate) {
124 : // Make sure the current thread is allowed to create handles to begin with.
125 : CHECK(AllowHandleAllocation::IsAllowed());
126 : HandleScopeData* current = isolate_->handle_scope_data();
127 : // Shrink the current handle scope to make it impossible to do
128 : // handle allocations without an explicit handle scope.
129 : prev_limit_ = current->limit;
130 : current->limit = current->next;
131 : prev_sealed_level_ = current->sealed_level;
132 : current->sealed_level = current->level;
133 : }
134 :
135 :
136 : inline SealHandleScope::~SealHandleScope() {
137 : // Restore state in current handle scope to re-enable handle
138 : // allocations.
139 : HandleScopeData* current = isolate_->handle_scope_data();
140 : DCHECK_EQ(current->next, current->limit);
141 : current->limit = prev_limit_;
142 : DCHECK_EQ(current->level, current->sealed_level);
143 : current->sealed_level = prev_sealed_level_;
144 : }
145 :
146 : #endif
147 :
148 : } // namespace internal
149 : } // namespace v8
150 :
151 : #endif // V8_HANDLES_INL_H_
|