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

Side by Side Diff: src/global-handles.cc

Issue 23401003: new persistent semantics (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: comments, etc Created 7 years, 3 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
« no previous file with comments | « src/global-handles.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 ~Node() { 83 ~Node() {
84 // TODO(1428): if it's a weak handle we should have invoked its callback. 84 // TODO(1428): if it's a weak handle we should have invoked its callback.
85 // Zap the values for eager trapping. 85 // Zap the values for eager trapping.
86 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 86 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
87 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 87 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
88 index_ = 0; 88 index_ = 0;
89 set_independent(false); 89 set_independent(false);
90 set_partially_dependent(false); 90 set_partially_dependent(false);
91 set_in_new_space_list(false); 91 set_in_new_space_list(false);
92 parameter_or_next_free_.next_free = NULL; 92 parameter_or_next_free_.next_free = NULL;
93 weak_reference_callback_ = NULL; 93 weak_callback_ = NULL;
94 } 94 }
95 #endif 95 #endif
96 96
97 void Initialize(int index, Node** first_free) { 97 void Initialize(int index, Node** first_free) {
98 index_ = static_cast<uint8_t>(index); 98 index_ = static_cast<uint8_t>(index);
99 ASSERT(static_cast<int>(index_) == index); 99 ASSERT(static_cast<int>(index_) == index);
100 set_state(FREE); 100 set_state(FREE);
101 set_in_new_space_list(false); 101 set_in_new_space_list(false);
102 parameter_or_next_free_.next_free = *first_free; 102 parameter_or_next_free_.next_free = *first_free;
103 *first_free = this; 103 *first_free = this;
104 } 104 }
105 105
106 void Acquire(Object* object) { 106 void Acquire(Object* object) {
107 ASSERT(state() == FREE); 107 ASSERT(state() == FREE);
108 object_ = object; 108 object_ = object;
109 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 109 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
110 set_independent(false); 110 set_independent(false);
111 set_partially_dependent(false); 111 set_partially_dependent(false);
112 set_state(NORMAL); 112 set_state(NORMAL);
113 parameter_or_next_free_.parameter = NULL; 113 parameter_or_next_free_.parameter = NULL;
114 weak_reference_callback_ = NULL; 114 weak_callback_ = NULL;
115 IncreaseBlockUses(); 115 IncreaseBlockUses();
116 } 116 }
117 117
118 void Release() { 118 void Release() {
119 ASSERT(state() != FREE); 119 ASSERT(state() != FREE);
120 set_state(FREE); 120 set_state(FREE);
121 // Zap the values for eager trapping. 121 // Zap the values for eager trapping.
122 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 122 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
123 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 123 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
124 set_independent(false); 124 set_independent(false);
125 set_partially_dependent(false); 125 set_partially_dependent(false);
126 weak_reference_callback_ = NULL; 126 weak_callback_ = NULL;
127 DecreaseBlockUses(); 127 DecreaseBlockUses();
128 } 128 }
129 129
130 // Object slot accessors. 130 // Object slot accessors.
131 Object* object() const { return object_; } 131 Object* object() const { return object_; }
132 Object** location() { return &object_; } 132 Object** location() { return &object_; }
133 Handle<Object> handle() { return Handle<Object>(location()); } 133 Handle<Object> handle() { return Handle<Object>(location()); }
134 134
135 // Wrapper class ID accessors. 135 // Wrapper class ID accessors.
136 bool has_wrapper_class_id() const { 136 bool has_wrapper_class_id() const {
(...skipping 25 matching lines...) Expand all
162 flags_ = IsPartiallyDependent::update(flags_, v); 162 flags_ = IsPartiallyDependent::update(flags_, v);
163 } 163 }
164 164
165 bool is_in_new_space_list() { 165 bool is_in_new_space_list() {
166 return IsInNewSpaceList::decode(flags_); 166 return IsInNewSpaceList::decode(flags_);
167 } 167 }
168 void set_in_new_space_list(bool v) { 168 void set_in_new_space_list(bool v) {
169 flags_ = IsInNewSpaceList::update(flags_, v); 169 flags_ = IsInNewSpaceList::update(flags_, v);
170 } 170 }
171 171
172 bool is_revivable_callback() {
173 return IsRevivableCallback::decode(flags_);
174 }
175 void set_revivable_callback(bool v) {
176 flags_ = IsRevivableCallback::update(flags_, v);
177 }
178
172 bool IsNearDeath() const { 179 bool IsNearDeath() const {
173 // Check for PENDING to ensure correct answer when processing callbacks. 180 // Check for PENDING to ensure correct answer when processing callbacks.
174 return state() == PENDING || state() == NEAR_DEATH; 181 return state() == PENDING || state() == NEAR_DEATH;
175 } 182 }
176 183
177 bool IsWeak() const { return state() == WEAK; } 184 bool IsWeak() const { return state() == WEAK; }
178 185
179 bool IsRetainer() const { return state() != FREE; } 186 bool IsRetainer() const { return state() != FREE; }
180 187
181 bool IsStrongRetainer() const { return state() == NORMAL; } 188 bool IsStrongRetainer() const { return state() == NORMAL; }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 Node* next_free() { 228 Node* next_free() {
222 ASSERT(state() == FREE); 229 ASSERT(state() == FREE);
223 return parameter_or_next_free_.next_free; 230 return parameter_or_next_free_.next_free;
224 } 231 }
225 void set_next_free(Node* value) { 232 void set_next_free(Node* value) {
226 ASSERT(state() == FREE); 233 ASSERT(state() == FREE);
227 parameter_or_next_free_.next_free = value; 234 parameter_or_next_free_.next_free = value;
228 } 235 }
229 236
230 void MakeWeak(void* parameter, 237 void MakeWeak(void* parameter,
231 RevivableCallback weak_reference_callback) { 238 WeakCallback weak_callback,
239 RevivableCallback revivable_callback) {
240 ASSERT((weak_callback == NULL) != (revivable_callback == NULL));
232 ASSERT(state() != FREE); 241 ASSERT(state() != FREE);
233 set_state(WEAK); 242 set_state(WEAK);
234 set_parameter(parameter); 243 set_parameter(parameter);
235 weak_reference_callback_ = weak_reference_callback; 244 if (weak_callback != NULL) {
245 weak_callback_ = weak_callback;
246 set_revivable_callback(false);
247 } else {
248 weak_callback_ =
249 reinterpret_cast<WeakCallback>(revivable_callback);
250 set_revivable_callback(true);
251 }
236 } 252 }
237 253
238 void ClearWeakness() { 254 void ClearWeakness() {
239 ASSERT(state() != FREE); 255 ASSERT(state() != FREE);
240 set_state(NORMAL); 256 set_state(NORMAL);
241 set_parameter(NULL); 257 set_parameter(NULL);
242 } 258 }
243 259
244 bool PostGarbageCollectionProcessing(Isolate* isolate) { 260 bool PostGarbageCollectionProcessing(Isolate* isolate) {
245 if (state() != Node::PENDING) return false; 261 if (state() != Node::PENDING) return false;
246 if (weak_reference_callback_ == NULL) { 262 if (weak_callback_ == NULL) {
247 Release(); 263 Release();
248 return false; 264 return false;
249 } 265 }
250 void* par = parameter(); 266 void* par = parameter();
251 set_state(NEAR_DEATH); 267 set_state(NEAR_DEATH);
252 set_parameter(NULL); 268 set_parameter(NULL);
253 269
254 Object** object = location(); 270 Object** object = location();
255 { 271 {
256 // Check that we are not passing a finalized external string to 272 // Check that we are not passing a finalized external string to
257 // the callback. 273 // the callback.
258 ASSERT(!object_->IsExternalAsciiString() || 274 ASSERT(!object_->IsExternalAsciiString() ||
259 ExternalAsciiString::cast(object_)->resource() != NULL); 275 ExternalAsciiString::cast(object_)->resource() != NULL);
260 ASSERT(!object_->IsExternalTwoByteString() || 276 ASSERT(!object_->IsExternalTwoByteString() ||
261 ExternalTwoByteString::cast(object_)->resource() != NULL); 277 ExternalTwoByteString::cast(object_)->resource() != NULL);
262 // Leaving V8. 278 // Leaving V8.
263 VMState<EXTERNAL> state(isolate); 279 VMState<EXTERNAL> state(isolate);
264 HandleScope handle_scope(isolate); 280 HandleScope handle_scope(isolate);
265 weak_reference_callback_(reinterpret_cast<v8::Isolate*>(isolate), 281 if (is_revivable_callback()) {
266 reinterpret_cast<Persistent<Value>*>(&object), 282 RevivableCallback revivable =
267 par); 283 reinterpret_cast<RevivableCallback>(weak_callback_);
284 revivable(reinterpret_cast<v8::Isolate*>(isolate),
285 reinterpret_cast<Persistent<Value>*>(&object),
286 par);
287 } else {
288 Handle<Object> handle(*object, isolate);
289 v8::WeakCallbackData<v8::Value, void> data(
290 reinterpret_cast<v8::Isolate*>(isolate),
291 v8::Utils::ToLocal(handle),
292 par);
293 weak_callback_(data);
294 }
268 } 295 }
269 // Absence of explicit cleanup or revival of weak handle 296 // Absence of explicit cleanup or revival of weak handle
270 // in most of the cases would lead to memory leak. 297 // in most of the cases would lead to memory leak.
271 ASSERT(state() != NEAR_DEATH); 298 ASSERT(state() != NEAR_DEATH);
272 return true; 299 return true;
273 } 300 }
274 301
302 inline GlobalHandles* GetGlobalHandles();
303
275 private: 304 private:
276 inline NodeBlock* FindBlock(); 305 inline NodeBlock* FindBlock();
277 inline GlobalHandles* GetGlobalHandles();
278 inline void IncreaseBlockUses(); 306 inline void IncreaseBlockUses();
279 inline void DecreaseBlockUses(); 307 inline void DecreaseBlockUses();
280 308
281 // Storage for object pointer. 309 // Storage for object pointer.
282 // Placed first to avoid offset computation. 310 // Placed first to avoid offset computation.
283 Object* object_; 311 Object* object_;
284 312
285 // Next word stores class_id, index, state, and independent. 313 // Next word stores class_id, index, state, and independent.
286 // Note: the most aligned fields should go first. 314 // Note: the most aligned fields should go first.
287 315
288 // Wrapper class ID. 316 // Wrapper class ID.
289 uint16_t class_id_; 317 uint16_t class_id_;
290 318
291 // Index in the containing handle block. 319 // Index in the containing handle block.
292 uint8_t index_; 320 uint8_t index_;
293 321
294 // This stores three flags (independent, partially_dependent and 322 // This stores three flags (independent, partially_dependent and
295 // in_new_space_list) and a State. 323 // in_new_space_list) and a State.
296 class NodeState: public BitField<State, 0, 4> {}; 324 class NodeState: public BitField<State, 0, 4> {};
297 class IsIndependent: public BitField<bool, 4, 1> {}; 325 class IsIndependent: public BitField<bool, 4, 1> {};
298 class IsPartiallyDependent: public BitField<bool, 5, 1> {}; 326 class IsPartiallyDependent: public BitField<bool, 5, 1> {};
299 class IsInNewSpaceList: public BitField<bool, 6, 1> {}; 327 class IsInNewSpaceList: public BitField<bool, 6, 1> {};
328 class IsRevivableCallback: public BitField<bool, 7, 1> {};
300 329
301 uint8_t flags_; 330 uint8_t flags_;
302 331
303 // Handle specific callback - might be a weak reference in disguise. 332 // Handle specific callback - might be a weak reference in disguise.
304 RevivableCallback weak_reference_callback_; 333 WeakCallback weak_callback_;
305 334
306 // Provided data for callback. In FREE state, this is used for 335 // Provided data for callback. In FREE state, this is used for
307 // the free list link. 336 // the free list link.
308 union { 337 union {
309 void* parameter; 338 void* parameter;
310 Node* next_free; 339 Node* next_free;
311 } parameter_or_next_free_; 340 } parameter_or_next_free_;
312 341
313 DISALLOW_COPY_AND_ASSIGN(Node); 342 DISALLOW_COPY_AND_ASSIGN(Node);
314 }; 343 };
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 result->Acquire(value); 502 result->Acquire(value);
474 if (isolate_->heap()->InNewSpace(value) && 503 if (isolate_->heap()->InNewSpace(value) &&
475 !result->is_in_new_space_list()) { 504 !result->is_in_new_space_list()) {
476 new_space_nodes_.Add(result); 505 new_space_nodes_.Add(result);
477 result->set_in_new_space_list(true); 506 result->set_in_new_space_list(true);
478 } 507 }
479 return result->handle(); 508 return result->handle();
480 } 509 }
481 510
482 511
512 Handle<Object> GlobalHandles::CopyGlobal(Object** location) {
513 ASSERT(location != NULL);
514 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
515 }
516
517
483 void GlobalHandles::Destroy(Object** location) { 518 void GlobalHandles::Destroy(Object** location) {
484 if (location != NULL) Node::FromLocation(location)->Release(); 519 if (location != NULL) Node::FromLocation(location)->Release();
485 } 520 }
486 521
487 522
488 void GlobalHandles::MakeWeak(Object** location, 523 void GlobalHandles::MakeWeak(Object** location,
489 void* parameter, 524 void* parameter,
490 RevivableCallback weak_reference_callback) { 525 WeakCallback weak_callback,
491 ASSERT(weak_reference_callback != NULL); 526 RevivableCallback revivable_callback) {
492 Node::FromLocation(location)->MakeWeak(parameter, weak_reference_callback); 527 Node::FromLocation(location)->MakeWeak(
528 parameter, weak_callback, revivable_callback);
493 } 529 }
494 530
495 531
496 void GlobalHandles::ClearWeakness(Object** location) { 532 void GlobalHandles::ClearWeakness(Object** location) {
497 Node::FromLocation(location)->ClearWeakness(); 533 Node::FromLocation(location)->ClearWeakness();
498 } 534 }
499 535
500 536
501 void GlobalHandles::MarkIndependent(Object** location) { 537 void GlobalHandles::MarkIndependent(Object** location) {
502 Node::FromLocation(location)->MarkIndependent(); 538 Node::FromLocation(location)->MarkIndependent();
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1111 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]);
1076 blocks_[block][offset] = object; 1112 blocks_[block][offset] = object;
1077 if (isolate->heap()->InNewSpace(object)) { 1113 if (isolate->heap()->InNewSpace(object)) {
1078 new_space_indices_.Add(size_); 1114 new_space_indices_.Add(size_);
1079 } 1115 }
1080 *index = size_++; 1116 *index = size_++;
1081 } 1117 }
1082 1118
1083 1119
1084 } } // namespace v8::internal 1120 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698