v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
global-handles.cc
Go to the documentation of this file.
1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #include "api.h"
31 #include "global-handles.h"
32 
33 #include "vm-state-inl.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 
39 ObjectGroup::~ObjectGroup() {
40  if (info_ != NULL) info_->Dispose();
41 }
42 
43 
45  public:
46  // State transition diagram:
47  // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
48  enum State {
50  NORMAL, // Normal global handle.
51  WEAK, // Flagged as weak but not yet finalized.
52  PENDING, // Has been recognized as only reachable by weak handles.
53  NEAR_DEATH // Callback has informed the handle is near death.
54  };
55 
56  // Maps handle location (slot) to the containing node.
58  ASSERT(OFFSET_OF(Node, object_) == 0);
59  return reinterpret_cast<Node*>(location);
60  }
61 
62  Node() {}
63 
64 #ifdef DEBUG
65  ~Node() {
66  // TODO(1428): if it's a weak handle we should have invoked its callback.
67  // Zap the values for eager trapping.
68  object_ = NULL;
70  index_ = 0;
71  independent_ = false;
72  in_new_space_list_ = false;
73  parameter_or_next_free_.next_free = NULL;
74  callback_ = NULL;
75  }
76 #endif
77 
78  void Initialize(int index, Node** first_free) {
79  index_ = static_cast<uint8_t>(index);
80  ASSERT(static_cast<int>(index_) == index);
81  state_ = FREE;
82  in_new_space_list_ = false;
83  parameter_or_next_free_.next_free = *first_free;
84  *first_free = this;
85  }
86 
87  void Acquire(Object* object, GlobalHandles* global_handles) {
88  ASSERT(state_ == FREE);
89  object_ = object;
91  independent_ = false;
92  state_ = NORMAL;
93  parameter_or_next_free_.parameter = NULL;
94  callback_ = NULL;
95  IncreaseBlockUses(global_handles);
96  }
97 
98  void Release(GlobalHandles* global_handles) {
99  ASSERT(state_ != FREE);
100  if (IsWeakRetainer()) {
101  global_handles->number_of_weak_handles_--;
102  if (object_->IsJSGlobalObject()) {
103  global_handles->number_of_global_object_weak_handles_--;
104  }
105  }
106  state_ = FREE;
107  parameter_or_next_free_.next_free = global_handles->first_free_;
108  global_handles->first_free_ = this;
109  DecreaseBlockUses(global_handles);
110  }
111 
112  // Object slot accessors.
113  Object* object() const { return object_; }
114  Object** location() { return &object_; }
116 
117  // Wrapper class ID accessors.
118  bool has_wrapper_class_id() const {
120  }
121  uint16_t wrapper_class_id() const { return class_id_; }
123  class_id_ = class_id;
124  }
125 
126  // State accessors.
127 
128  State state() const { return state_; }
129 
130  bool IsNearDeath() const {
131  // Check for PENDING to ensure correct answer when processing callbacks.
132  return state_ == PENDING || state_ == NEAR_DEATH;
133  }
134 
135  bool IsWeak() const { return state_ == WEAK; }
136 
137  bool IsRetainer() const { return state_ != FREE; }
138 
139  bool IsStrongRetainer() const { return state_ == NORMAL; }
140 
141  bool IsWeakRetainer() const {
142  return state_ == WEAK || state_ == PENDING || state_ == NEAR_DEATH;
143  }
144 
145  void MarkPending() {
146  ASSERT(state_ == WEAK);
147  state_ = PENDING;
148  }
149 
150  // Independent flag accessors.
152  ASSERT(state_ != FREE);
153  independent_ = true;
154  }
155  bool is_independent() const { return independent_; }
156 
157  // In-new-space-list flag accessors.
158  void set_in_new_space_list(bool v) { in_new_space_list_ = v; }
159  bool is_in_new_space_list() const { return in_new_space_list_; }
160 
161  // Callback accessor.
162  WeakReferenceCallback callback() { return callback_; }
163 
164  // Callback parameter accessors.
165  void set_parameter(void* parameter) {
166  ASSERT(state_ != FREE);
167  parameter_or_next_free_.parameter = parameter;
168  }
169  void* parameter() const {
170  ASSERT(state_ != FREE);
171  return parameter_or_next_free_.parameter;
172  }
173 
174  // Accessors for next free node in the free list.
176  ASSERT(state_ == FREE);
177  return parameter_or_next_free_.next_free;
178  }
179  void set_next_free(Node* value) {
180  ASSERT(state_ == FREE);
181  parameter_or_next_free_.next_free = value;
182  }
183 
184  void MakeWeak(GlobalHandles* global_handles,
185  void* parameter,
187  ASSERT(state_ != FREE);
188  if (!IsWeakRetainer()) {
189  global_handles->number_of_weak_handles_++;
190  if (object_->IsJSGlobalObject()) {
191  global_handles->number_of_global_object_weak_handles_++;
192  }
193  }
194  state_ = WEAK;
195  set_parameter(parameter);
196  callback_ = callback;
197  }
198 
199  void ClearWeakness(GlobalHandles* global_handles) {
200  ASSERT(state_ != FREE);
201  if (IsWeakRetainer()) {
202  global_handles->number_of_weak_handles_--;
203  if (object_->IsJSGlobalObject()) {
204  global_handles->number_of_global_object_weak_handles_--;
205  }
206  }
207  state_ = NORMAL;
209  }
210 
212  GlobalHandles* global_handles) {
213  if (state_ != Node::PENDING) return false;
215  if (func == NULL) {
216  Release(global_handles);
217  return false;
218  }
219  void* par = parameter();
220  state_ = NEAR_DEATH;
222 
223  v8::Persistent<v8::Object> object = ToApi<v8::Object>(handle());
224  {
225  // Check that we are not passing a finalized external string to
226  // the callback.
227  ASSERT(!object_->IsExternalAsciiString() ||
228  ExternalAsciiString::cast(object_)->resource() != NULL);
229  ASSERT(!object_->IsExternalTwoByteString() ||
230  ExternalTwoByteString::cast(object_)->resource() != NULL);
231  // Leaving V8.
232  VMState state(isolate, EXTERNAL);
233  func(object, par);
234  }
235  // Absence of explicit cleanup or revival of weak handle
236  // in most of the cases would lead to memory leak.
237  ASSERT(state_ != NEAR_DEATH);
238  return true;
239  }
240 
241  private:
242  inline NodeBlock* FindBlock();
243  inline void IncreaseBlockUses(GlobalHandles* global_handles);
244  inline void DecreaseBlockUses(GlobalHandles* global_handles);
245 
246  // Storage for object pointer.
247  // Placed first to avoid offset computation.
248  Object* object_;
249 
250  // Next word stores class_id, index, state, and independent.
251  // Note: the most aligned fields should go first.
252 
253  // Wrapper class ID.
254  uint16_t class_id_;
255 
256  // Index in the containing handle block.
257  uint8_t index_;
258 
259  // Need one more bit for MSVC as it treats enums as signed.
260  State state_ : 4;
261 
262  bool independent_ : 1;
263  bool in_new_space_list_ : 1;
264 
265  // Handle specific callback.
266  WeakReferenceCallback callback_;
267 
268  // Provided data for callback. In FREE state, this is used for
269  // the free list link.
270  union {
271  void* parameter;
273  } parameter_or_next_free_;
274 
275  DISALLOW_COPY_AND_ASSIGN(Node);
276 };
277 
278 
280  public:
281  static const int kSize = 256;
282 
284  : next_(next), used_nodes_(0), next_used_(NULL), prev_used_(NULL) {}
285 
286  void PutNodesOnFreeList(Node** first_free) {
287  for (int i = kSize - 1; i >= 0; --i) {
288  nodes_[i].Initialize(i, first_free);
289  }
290  }
291 
292  Node* node_at(int index) {
293  ASSERT(0 <= index && index < kSize);
294  return &nodes_[index];
295  }
296 
297  void IncreaseUses(GlobalHandles* global_handles) {
298  ASSERT(used_nodes_ < kSize);
299  if (used_nodes_++ == 0) {
300  NodeBlock* old_first = global_handles->first_used_block_;
301  global_handles->first_used_block_ = this;
302  next_used_ = old_first;
303  prev_used_ = NULL;
304  if (old_first == NULL) return;
305  old_first->prev_used_ = this;
306  }
307  }
308 
309  void DecreaseUses(GlobalHandles* global_handles) {
310  ASSERT(used_nodes_ > 0);
311  if (--used_nodes_ == 0) {
312  if (next_used_ != NULL) next_used_->prev_used_ = prev_used_;
313  if (prev_used_ != NULL) prev_used_->next_used_ = next_used_;
314  if (this == global_handles->first_used_block_) {
315  global_handles->first_used_block_ = next_used_;
316  }
317  }
318  }
319 
320  // Next block in the list of all blocks.
321  NodeBlock* next() const { return next_; }
322 
323  // Next/previous block in the list of blocks with used nodes.
324  NodeBlock* next_used() const { return next_used_; }
325  NodeBlock* prev_used() const { return prev_used_; }
326 
327  private:
328  Node nodes_[kSize];
329  NodeBlock* const next_;
330  int used_nodes_;
331  NodeBlock* next_used_;
332  NodeBlock* prev_used_;
333 };
334 
335 
336 GlobalHandles::NodeBlock* GlobalHandles::Node::FindBlock() {
337  intptr_t ptr = reinterpret_cast<intptr_t>(this);
338  ptr = ptr - index_ * sizeof(Node);
339  NodeBlock* block = reinterpret_cast<NodeBlock*>(ptr);
340  ASSERT(block->node_at(index_) == this);
341  return block;
342 }
343 
344 
345 void GlobalHandles::Node::IncreaseBlockUses(GlobalHandles* global_handles) {
346  FindBlock()->IncreaseUses(global_handles);
347 }
348 
349 
350 void GlobalHandles::Node::DecreaseBlockUses(GlobalHandles* global_handles) {
351  FindBlock()->DecreaseUses(global_handles);
352 }
353 
354 
356  public:
357  explicit NodeIterator(GlobalHandles* global_handles)
358  : block_(global_handles->first_used_block_),
359  index_(0) {}
360 
361  bool done() const { return block_ == NULL; }
362 
363  Node* node() const {
364  ASSERT(!done());
365  return block_->node_at(index_);
366  }
367 
368  void Advance() {
369  ASSERT(!done());
370  if (++index_ < NodeBlock::kSize) return;
371  index_ = 0;
372  block_ = block_->next_used();
373  }
374 
375  private:
376  NodeBlock* block_;
377  int index_;
378 
380 };
381 
382 
383 GlobalHandles::GlobalHandles(Isolate* isolate)
384  : isolate_(isolate),
385  number_of_weak_handles_(0),
386  number_of_global_object_weak_handles_(0),
387  number_of_global_handles_(0),
388  first_block_(NULL),
389  first_used_block_(NULL),
390  first_free_(NULL),
391  post_gc_processing_count_(0) {}
392 
393 
395  NodeBlock* block = first_block_;
396  while (block != NULL) {
397  NodeBlock* tmp = block->next();
398  delete block;
399  block = tmp;
400  }
401  first_block_ = NULL;
402 }
403 
404 
406  isolate_->counters()->global_handles()->Increment();
407  number_of_global_handles_++;
408  if (first_free_ == NULL) {
409  first_block_ = new NodeBlock(first_block_);
410  first_block_->PutNodesOnFreeList(&first_free_);
411  }
412  ASSERT(first_free_ != NULL);
413  // Take the first node in the free list.
414  Node* result = first_free_;
415  first_free_ = result->next_free();
416  result->Acquire(value, this);
417  if (isolate_->heap()->InNewSpace(value) &&
418  !result->is_in_new_space_list()) {
419  new_space_nodes_.Add(result);
420  result->set_in_new_space_list(true);
421  }
422  return result->handle();
423 }
424 
425 
426 void GlobalHandles::Destroy(Object** location) {
427  isolate_->counters()->global_handles()->Decrement();
428  number_of_global_handles_--;
429  if (location == NULL) return;
430  Node::FromLocation(location)->Release(this);
431 }
432 
433 
434 void GlobalHandles::MakeWeak(Object** location, void* parameter,
435  WeakReferenceCallback callback) {
436  ASSERT(callback != NULL);
437  Node::FromLocation(location)->MakeWeak(this, parameter, callback);
438 }
439 
440 
442  Node::FromLocation(location)->ClearWeakness(this);
443 }
444 
445 
447  Node::FromLocation(location)->MarkIndependent();
448 }
449 
450 
452  return Node::FromLocation(location)->IsNearDeath();
453 }
454 
455 
456 bool GlobalHandles::IsWeak(Object** location) {
457  return Node::FromLocation(location)->IsWeak();
458 }
459 
460 
462  Node::FromLocation(location)->set_wrapper_class_id(class_id);
463 }
464 
465 
466 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
467  for (NodeIterator it(this); !it.done(); it.Advance()) {
468  if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location());
469  }
470 }
471 
472 
474  WeakReferenceCallback callback) {
475  for (NodeIterator it(this); !it.done(); it.Advance()) {
476  if (it.node()->IsWeak() && it.node()->callback() == callback) {
477  f(it.node()->object(), it.node()->parameter());
478  }
479  }
480 }
481 
482 
484  for (NodeIterator it(this); !it.done(); it.Advance()) {
485  if (it.node()->IsWeak() && f(it.node()->location())) {
486  it.node()->MarkPending();
487  }
488  }
489 }
490 
491 
493  for (int i = 0; i < new_space_nodes_.length(); ++i) {
494  Node* node = new_space_nodes_[i];
495  if (node->IsStrongRetainer() ||
496  (node->IsWeakRetainer() && !node->is_independent())) {
497  v->VisitPointer(node->location());
498  }
499  }
500 }
501 
502 
505  for (int i = 0; i < new_space_nodes_.length(); ++i) {
506  Node* node = new_space_nodes_[i];
507  ASSERT(node->is_in_new_space_list());
508  if (node->is_independent() && node->IsWeak() &&
509  f(isolate_->heap(), node->location())) {
510  node->MarkPending();
511  }
512  }
513 }
514 
515 
517  for (int i = 0; i < new_space_nodes_.length(); ++i) {
518  Node* node = new_space_nodes_[i];
519  ASSERT(node->is_in_new_space_list());
520  if (node->is_independent() && node->IsWeakRetainer()) {
521  v->VisitPointer(node->location());
522  }
523  }
524 }
525 
526 
528  GarbageCollector collector) {
529  // Process weak global handle callbacks. This must be done after the
530  // GC is completely done, because the callbacks may invoke arbitrary
531  // API functions.
532  ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
533  const int initial_post_gc_processing_count = ++post_gc_processing_count_;
534  bool next_gc_likely_to_collect_more = false;
535  if (collector == SCAVENGER) {
536  for (int i = 0; i < new_space_nodes_.length(); ++i) {
537  Node* node = new_space_nodes_[i];
538  ASSERT(node->is_in_new_space_list());
539  // Skip dependent handles. Their weak callbacks might expect to be
540  // called between two global garbage collection callbacks which
541  // are not called for minor collections.
542  if (!node->is_independent()) continue;
543  if (node->PostGarbageCollectionProcessing(isolate_, this)) {
544  if (initial_post_gc_processing_count != post_gc_processing_count_) {
545  // Weak callback triggered another GC and another round of
546  // PostGarbageCollection processing. The current node might
547  // have been deleted in that round, so we need to bail out (or
548  // restart the processing).
549  return next_gc_likely_to_collect_more;
550  }
551  }
552  if (!node->IsRetainer()) {
553  next_gc_likely_to_collect_more = true;
554  }
555  }
556  } else {
557  for (NodeIterator it(this); !it.done(); it.Advance()) {
558  if (it.node()->PostGarbageCollectionProcessing(isolate_, this)) {
559  if (initial_post_gc_processing_count != post_gc_processing_count_) {
560  // See the comment above.
561  return next_gc_likely_to_collect_more;
562  }
563  }
564  if (!it.node()->IsRetainer()) {
565  next_gc_likely_to_collect_more = true;
566  }
567  }
568  }
569  // Update the list of new space nodes.
570  int last = 0;
571  for (int i = 0; i < new_space_nodes_.length(); ++i) {
572  Node* node = new_space_nodes_[i];
573  ASSERT(node->is_in_new_space_list());
574  if (node->IsRetainer() && isolate_->heap()->InNewSpace(node->object())) {
575  new_space_nodes_[last++] = node;
576  } else {
577  node->set_in_new_space_list(false);
578  }
579  }
580  new_space_nodes_.Rewind(last);
581  return next_gc_likely_to_collect_more;
582 }
583 
584 
585 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) {
586  for (NodeIterator it(this); !it.done(); it.Advance()) {
587  if (it.node()->IsStrongRetainer()) {
588  v->VisitPointer(it.node()->location());
589  }
590  }
591 }
592 
593 
594 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
595  for (NodeIterator it(this); !it.done(); it.Advance()) {
596  if (it.node()->IsRetainer()) {
597  v->VisitPointer(it.node()->location());
598  }
599  }
600 }
601 
602 
604  for (NodeIterator it(this); !it.done(); it.Advance()) {
605  if (it.node()->has_wrapper_class_id() && it.node()->IsRetainer()) {
606  v->VisitEmbedderReference(it.node()->location(),
607  it.node()->wrapper_class_id());
608  }
609  }
610 }
611 
612 
614  *stats->global_handle_count = 0;
615  *stats->weak_global_handle_count = 0;
616  *stats->pending_global_handle_count = 0;
617  *stats->near_death_global_handle_count = 0;
618  *stats->free_global_handle_count = 0;
619  for (NodeIterator it(this); !it.done(); it.Advance()) {
620  *stats->global_handle_count += 1;
621  if (it.node()->state() == Node::WEAK) {
622  *stats->weak_global_handle_count += 1;
623  } else if (it.node()->state() == Node::PENDING) {
624  *stats->pending_global_handle_count += 1;
625  } else if (it.node()->state() == Node::NEAR_DEATH) {
626  *stats->near_death_global_handle_count += 1;
627  } else if (it.node()->state() == Node::FREE) {
628  *stats->free_global_handle_count += 1;
629  }
630  }
631 }
632 
633 #ifdef DEBUG
634 
635 void GlobalHandles::PrintStats() {
636  int total = 0;
637  int weak = 0;
638  int pending = 0;
639  int near_death = 0;
640  int destroyed = 0;
641 
642  for (NodeIterator it(this); !it.done(); it.Advance()) {
643  total++;
644  if (it.node()->state() == Node::WEAK) weak++;
645  if (it.node()->state() == Node::PENDING) pending++;
646  if (it.node()->state() == Node::NEAR_DEATH) near_death++;
647  if (it.node()->state() == Node::FREE) destroyed++;
648  }
649 
650  PrintF("Global Handle Statistics:\n");
651  PrintF(" allocated memory = %" V8_PTR_PREFIX "dB\n", sizeof(Node) * total);
652  PrintF(" # weak = %d\n", weak);
653  PrintF(" # pending = %d\n", pending);
654  PrintF(" # near_death = %d\n", near_death);
655  PrintF(" # free = %d\n", destroyed);
656  PrintF(" # total = %d\n", total);
657 }
658 
659 void GlobalHandles::Print() {
660  PrintF("Global handles:\n");
661  for (NodeIterator it(this); !it.done(); it.Advance()) {
662  PrintF(" handle %p to %p%s\n",
663  reinterpret_cast<void*>(it.node()->location()),
664  reinterpret_cast<void*>(it.node()->object()),
665  it.node()->IsWeak() ? " (weak)" : "");
666  }
667 }
668 
669 #endif
670 
671 
672 
674  size_t length,
675  v8::RetainedObjectInfo* info) {
676 #ifdef DEBUG
677  for (size_t i = 0; i < length; ++i) {
678  ASSERT(!Node::FromLocation(handles[i])->is_independent());
679  }
680 #endif
681  if (length == 0) {
682  if (info != NULL) info->Dispose();
683  return;
684  }
685  object_groups_.Add(ObjectGroup::New(handles, length, info));
686 }
687 
688 
690  Object*** children,
691  size_t length) {
692 #ifdef DEBUG
693  ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
694  for (size_t i = 0; i < length; ++i) {
695  ASSERT(!Node::FromLocation(children[i])->is_independent());
696  }
697 #endif
698  if (length == 0) return;
699  implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
700 }
701 
702 
704  for (int i = 0; i < object_groups_.length(); i++) {
705  object_groups_.at(i)->Dispose();
706  }
707  object_groups_.Clear();
708 }
709 
710 
712  for (int i = 0; i < implicit_ref_groups_.length(); i++) {
713  implicit_ref_groups_.at(i)->Dispose();
714  }
715  implicit_ref_groups_.Clear();
716 }
717 
718 
720  // TODO(1428): invoke weak callbacks.
721 }
722 
723 
724 } } // namespace v8::internal
bool(* WeakSlotCallbackWithHeap)(Heap *heap, Object **pointer)
Definition: v8globals.h:174
void Destroy(Object **location)
static ObjectGroup * New(Object ***handles, size_t length, v8::RetainedObjectInfo *info)
void MakeWeak(GlobalHandles *global_handles, void *parameter, WeakReferenceCallback callback)
void PrintF(const char *format,...)
Definition: v8utils.cc:40
bool InNewSpace(Object *object)
Definition: heap-inl.h:292
void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f)
void IncreaseUses(GlobalHandles *global_handles)
void AddImplicitReferences(HeapObject **parent, Object ***children, size_t length)
static ExternalTwoByteString * cast(Object *obj)
static bool IsNearDeath(Object **location)
void IterateWeakRoots(ObjectVisitor *v)
#define ASSERT(condition)
Definition: checks.h:270
static Node * FromLocation(Object **location)
void ClearWeakness(Object **location)
v8::Handle< v8::Value > Print(const v8::Arguments &args)
unsigned short uint16_t
Definition: unicode.cc:46
void IterateStrongRoots(ObjectVisitor *v)
WeakReferenceCallback callback()
void Acquire(Object *object, GlobalHandles *global_handles)
static ExternalAsciiString * cast(Object *obj)
void AddObjectGroup(Object ***handles, size_t length, v8::RetainedObjectInfo *info)
int * pending_global_handle_count
Definition: heap.h:2084
int * near_death_global_handle_count
Definition: heap.h:2085
void DecreaseUses(GlobalHandles *global_handles)
bool PostGarbageCollectionProcessing(GarbageCollector collector)
void set_wrapper_class_id(uint16_t class_id)
void PutNodesOnFreeList(Node **first_free)
#define OFFSET_OF(type, field)
Definition: globals.h:287
static const uint16_t kPersistentHandleNoClassId
Definition: v8-profiler.h:481
NodeIterator(GlobalHandles *global_handles)
Handle< Object > Create(Object *value)
int * global_handle_count
Definition: heap.h:2082
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:321
HeapState gc_state()
Definition: heap.h:1280
void IterateAllRoots(ObjectVisitor *v)
#define V8_PTR_PREFIX
Definition: globals.h:196
static void SetWrapperClassId(Object **location, uint16_t class_id)
void set_parameter(void *parameter)
void(* WeakReferenceCallback)(Persistent< Value > object, void *parameter)
Definition: v8.h:137
int * free_global_handle_count
Definition: heap.h:2086
void IterateAllRootsWithClassIds(ObjectVisitor *v)
void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor *v)
int * weak_global_handle_count
Definition: heap.h:2083
virtual void Dispose()=0
void IdentifyWeakHandles(WeakSlotCallback f)
void RecordStats(HeapStats *stats)
void(* WeakReferenceGuest)(Object *object, void *parameter)
static ImplicitRefGroup * New(HeapObject **parent, Object ***children, size_t length)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
Counters * counters()
Definition: isolate.h:804
void MarkIndependent(Object **location)
static bool IsWeak(Object **location)
void IterateNewSpaceWeakIndependentRoots(ObjectVisitor *v)
void MakeWeak(Object **location, void *parameter, WeakReferenceCallback callback)
void ClearWeakness(GlobalHandles *global_handles)
bool PostGarbageCollectionProcessing(Isolate *isolate, GlobalHandles *global_handles)
bool(* WeakSlotCallback)(Object **pointer)
Definition: v8globals.h:172
v8::RetainedObjectInfo * info_
void Initialize(int index, Node **first_free)
void Release(GlobalHandles *global_handles)