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

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: Created 7 years, 4 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
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 #ifdef ENABLE_EXTRA_CHECKS 121 #ifdef ENABLE_EXTRA_CHECKS
122 // Zap the values for eager trapping. 122 // Zap the values for eager trapping.
123 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 123 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
124 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 124 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
125 set_independent(false); 125 set_independent(false);
126 set_partially_dependent(false); 126 set_partially_dependent(false);
127 weak_reference_callback_ = NULL; 127 weak_callback_ = NULL;
128 #endif 128 #endif
129 DecreaseBlockUses(); 129 DecreaseBlockUses();
130 } 130 }
131 131
132 // Object slot accessors. 132 // Object slot accessors.
133 Object* object() const { return object_; } 133 Object* object() const { return object_; }
134 Object** location() { return &object_; } 134 Object** location() { return &object_; }
135 Handle<Object> handle() { return Handle<Object>(location()); } 135 Handle<Object> handle() { return Handle<Object>(location()); }
136 136
137 // Wrapper class ID accessors. 137 // Wrapper class ID accessors.
(...skipping 26 matching lines...) Expand all
164 flags_ = IsPartiallyDependent::update(flags_, v); 164 flags_ = IsPartiallyDependent::update(flags_, v);
165 } 165 }
166 166
167 bool is_in_new_space_list() { 167 bool is_in_new_space_list() {
168 return IsInNewSpaceList::decode(flags_); 168 return IsInNewSpaceList::decode(flags_);
169 } 169 }
170 void set_in_new_space_list(bool v) { 170 void set_in_new_space_list(bool v) {
171 flags_ = IsInNewSpaceList::update(flags_, v); 171 flags_ = IsInNewSpaceList::update(flags_, v);
172 } 172 }
173 173
174 bool is_revivable_callback() {
175 return IsRevivableCallback::decode(flags_);
176 }
177 void set_revivable_callback(bool v) {
178 flags_ = IsRevivableCallback::update(flags_, v);
179 }
180
174 bool IsNearDeath() const { 181 bool IsNearDeath() const {
175 // Check for PENDING to ensure correct answer when processing callbacks. 182 // Check for PENDING to ensure correct answer when processing callbacks.
176 return state() == PENDING || state() == NEAR_DEATH; 183 return state() == PENDING || state() == NEAR_DEATH;
177 } 184 }
178 185
179 bool IsWeak() const { return state() == WEAK; } 186 bool IsWeak() const { return state() == WEAK; }
180 187
181 bool IsRetainer() const { return state() != FREE; } 188 bool IsRetainer() const { return state() != FREE; }
182 189
183 bool IsStrongRetainer() const { return state() == NORMAL; } 190 bool IsStrongRetainer() const { return state() == NORMAL; }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 Node* next_free() { 230 Node* next_free() {
224 ASSERT(state() == FREE); 231 ASSERT(state() == FREE);
225 return parameter_or_next_free_.next_free; 232 return parameter_or_next_free_.next_free;
226 } 233 }
227 void set_next_free(Node* value) { 234 void set_next_free(Node* value) {
228 ASSERT(state() == FREE); 235 ASSERT(state() == FREE);
229 parameter_or_next_free_.next_free = value; 236 parameter_or_next_free_.next_free = value;
230 } 237 }
231 238
232 void MakeWeak(void* parameter, 239 void MakeWeak(void* parameter,
233 RevivableCallback weak_reference_callback) { 240 WeakCallback weak_callback,
241 RevivableCallback revivable_callback) {
242 ASSERT((weak_callback == NULL) != (revivable_callback == NULL));
234 ASSERT(state() != FREE); 243 ASSERT(state() != FREE);
235 set_state(WEAK); 244 set_state(WEAK);
236 set_parameter(parameter); 245 set_parameter(parameter);
237 weak_reference_callback_ = weak_reference_callback; 246 if (weak_callback != NULL) {
247 weak_callback_ = weak_callback;
248 set_revivable_callback(false);
249 } else {
250 weak_callback_ =
251 reinterpret_cast<WeakCallback>(revivable_callback);
252 set_revivable_callback(true);
253 }
238 } 254 }
239 255
240 void ClearWeakness() { 256 void ClearWeakness() {
241 ASSERT(state() != FREE); 257 ASSERT(state() != FREE);
242 set_state(NORMAL); 258 set_state(NORMAL);
243 set_parameter(NULL); 259 set_parameter(NULL);
244 } 260 }
245 261
246 bool PostGarbageCollectionProcessing(Isolate* isolate) { 262 bool PostGarbageCollectionProcessing(Isolate* isolate) {
247 if (state() != Node::PENDING) return false; 263 if (state() != Node::PENDING) return false;
248 if (weak_reference_callback_ == NULL) { 264 if (weak_callback_ == NULL) {
249 Release(); 265 Release();
250 return false; 266 return false;
251 } 267 }
252 void* par = parameter(); 268 void* par = parameter();
253 set_state(NEAR_DEATH); 269 set_state(NEAR_DEATH);
254 set_parameter(NULL); 270 set_parameter(NULL);
255 271
256 Object** object = location(); 272 Object** object = location();
257 { 273 {
258 // Check that we are not passing a finalized external string to 274 // Check that we are not passing a finalized external string to
259 // the callback. 275 // the callback.
260 ASSERT(!object_->IsExternalAsciiString() || 276 ASSERT(!object_->IsExternalAsciiString() ||
261 ExternalAsciiString::cast(object_)->resource() != NULL); 277 ExternalAsciiString::cast(object_)->resource() != NULL);
262 ASSERT(!object_->IsExternalTwoByteString() || 278 ASSERT(!object_->IsExternalTwoByteString() ||
263 ExternalTwoByteString::cast(object_)->resource() != NULL); 279 ExternalTwoByteString::cast(object_)->resource() != NULL);
264 // Leaving V8. 280 // Leaving V8.
265 VMState<EXTERNAL> state(isolate); 281 VMState<EXTERNAL> state(isolate);
266 HandleScope handle_scope(isolate); 282 HandleScope handle_scope(isolate);
267 weak_reference_callback_(reinterpret_cast<v8::Isolate*>(isolate), 283 if (is_revivable_callback()) {
268 reinterpret_cast<Persistent<Value>*>(&object), 284 RevivableCallback revivable =
269 par); 285 reinterpret_cast<RevivableCallback>(weak_callback_);
286 revivable(reinterpret_cast<v8::Isolate*>(isolate),
287 reinterpret_cast<Persistent<Value>*>(&object),
288 par);
289 } else {
290 Handle<Object> handle(*object, isolate);
291 v8::WeakCallbackData<v8::Value, void> data(
292 reinterpret_cast<v8::Isolate*>(isolate),
293 v8::Utils::ToLocal(handle),
294 par);
295 weak_callback_(&data);
296 }
270 } 297 }
271 // Absence of explicit cleanup or revival of weak handle 298 // Absence of explicit cleanup or revival of weak handle
272 // in most of the cases would lead to memory leak. 299 // in most of the cases would lead to memory leak.
273 ASSERT(state() != NEAR_DEATH); 300 ASSERT(state() != NEAR_DEATH);
274 return true; 301 return true;
275 } 302 }
276 303
304 inline GlobalHandles* GetGlobalHandles();
305
277 private: 306 private:
278 inline NodeBlock* FindBlock(); 307 inline NodeBlock* FindBlock();
279 inline GlobalHandles* GetGlobalHandles();
280 inline void IncreaseBlockUses(); 308 inline void IncreaseBlockUses();
281 inline void DecreaseBlockUses(); 309 inline void DecreaseBlockUses();
282 310
283 // Storage for object pointer. 311 // Storage for object pointer.
284 // Placed first to avoid offset computation. 312 // Placed first to avoid offset computation.
285 Object* object_; 313 Object* object_;
286 314
287 // Next word stores class_id, index, state, and independent. 315 // Next word stores class_id, index, state, and independent.
288 // Note: the most aligned fields should go first. 316 // Note: the most aligned fields should go first.
289 317
290 // Wrapper class ID. 318 // Wrapper class ID.
291 uint16_t class_id_; 319 uint16_t class_id_;
292 320
293 // Index in the containing handle block. 321 // Index in the containing handle block.
294 uint8_t index_; 322 uint8_t index_;
295 323
296 // This stores three flags (independent, partially_dependent and 324 // This stores three flags (independent, partially_dependent and
297 // in_new_space_list) and a State. 325 // in_new_space_list) and a State.
298 class NodeState: public BitField<State, 0, 4> {}; 326 class NodeState: public BitField<State, 0, 4> {};
299 class IsIndependent: public BitField<bool, 4, 1> {}; 327 class IsIndependent: public BitField<bool, 4, 1> {};
300 class IsPartiallyDependent: public BitField<bool, 5, 1> {}; 328 class IsPartiallyDependent: public BitField<bool, 5, 1> {};
301 class IsInNewSpaceList: public BitField<bool, 6, 1> {}; 329 class IsInNewSpaceList: public BitField<bool, 6, 1> {};
330 class IsRevivableCallback: public BitField<bool, 7, 1> {};
302 331
303 uint8_t flags_; 332 uint8_t flags_;
304 333
305 // Handle specific callback - might be a weak reference in disguise. 334 // Handle specific callback - might be a weak reference in disguise.
306 RevivableCallback weak_reference_callback_; 335 WeakCallback weak_callback_;
307 336
308 // Provided data for callback. In FREE state, this is used for 337 // Provided data for callback. In FREE state, this is used for
309 // the free list link. 338 // the free list link.
310 union { 339 union {
311 void* parameter; 340 void* parameter;
312 Node* next_free; 341 Node* next_free;
313 } parameter_or_next_free_; 342 } parameter_or_next_free_;
314 343
315 DISALLOW_COPY_AND_ASSIGN(Node); 344 DISALLOW_COPY_AND_ASSIGN(Node);
316 }; 345 };
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 result->Acquire(value); 504 result->Acquire(value);
476 if (isolate_->heap()->InNewSpace(value) && 505 if (isolate_->heap()->InNewSpace(value) &&
477 !result->is_in_new_space_list()) { 506 !result->is_in_new_space_list()) {
478 new_space_nodes_.Add(result); 507 new_space_nodes_.Add(result);
479 result->set_in_new_space_list(true); 508 result->set_in_new_space_list(true);
480 } 509 }
481 return result->handle(); 510 return result->handle();
482 } 511 }
483 512
484 513
514 Handle<Object> GlobalHandles::CopyGlobal(Object** location) {
515 ASSERT(location != NULL);
516 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
517 }
518
519
485 void GlobalHandles::Destroy(Object** location) { 520 void GlobalHandles::Destroy(Object** location) {
486 if (location != NULL) Node::FromLocation(location)->Release(); 521 if (location != NULL) Node::FromLocation(location)->Release();
487 } 522 }
488 523
489 524
490 void GlobalHandles::MakeWeak(Object** location, 525 void GlobalHandles::MakeWeak(Object** location,
491 void* parameter, 526 void* parameter,
492 RevivableCallback weak_reference_callback) { 527 WeakCallback weak_callback,
493 ASSERT(weak_reference_callback != NULL); 528 RevivableCallback revivable_callback) {
494 Node::FromLocation(location)->MakeWeak(parameter, weak_reference_callback); 529 Node::FromLocation(location)->MakeWeak(
530 parameter, weak_callback, revivable_callback);
495 } 531 }
496 532
497 533
498 void GlobalHandles::ClearWeakness(Object** location) { 534 void GlobalHandles::ClearWeakness(Object** location) {
499 Node::FromLocation(location)->ClearWeakness(); 535 Node::FromLocation(location)->ClearWeakness();
500 } 536 }
501 537
502 538
503 void GlobalHandles::MarkIndependent(Object** location) { 539 void GlobalHandles::MarkIndependent(Object** location) {
504 Node::FromLocation(location)->MarkIndependent(); 540 Node::FromLocation(location)->MarkIndependent();
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1113 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]);
1078 blocks_[block][offset] = object; 1114 blocks_[block][offset] = object;
1079 if (isolate->heap()->InNewSpace(object)) { 1115 if (isolate->heap()->InNewSpace(object)) {
1080 new_space_indices_.Add(size_); 1116 new_space_indices_.Add(size_);
1081 } 1117 }
1082 return size_++; 1118 return size_++;
1083 } 1119 }
1084 1120
1085 1121
1086 } } // namespace v8::internal 1122 } } // namespace v8::internal
OLDNEW
« src/global-handles.h ('K') | « 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