v8  3.14.5(node0.10.28)
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)->is_independent();
453 }
454 
455 
457  return Node::FromLocation(location)->IsNearDeath();
458 }
459 
460 
461 bool GlobalHandles::IsWeak(Object** location) {
462  return Node::FromLocation(location)->IsWeak();
463 }
464 
465 
467  Node::FromLocation(location)->set_wrapper_class_id(class_id);
468 }
469 
471  return Node::FromLocation(location)->wrapper_class_id();
472 }
473 
474 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
475  for (NodeIterator it(this); !it.done(); it.Advance()) {
476  if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location());
477  }
478 }
479 
480 
482  WeakReferenceCallback callback) {
483  for (NodeIterator it(this); !it.done(); it.Advance()) {
484  if (it.node()->IsWeak() && it.node()->callback() == callback) {
485  f(it.node()->object(), it.node()->parameter());
486  }
487  }
488 }
489 
490 
492  for (NodeIterator it(this); !it.done(); it.Advance()) {
493  if (it.node()->IsWeak() && f(it.node()->location())) {
494  it.node()->MarkPending();
495  }
496  }
497 }
498 
499 
501  for (int i = 0; i < new_space_nodes_.length(); ++i) {
502  Node* node = new_space_nodes_[i];
503  if (node->IsStrongRetainer() ||
504  (node->IsWeakRetainer() && !node->is_independent())) {
505  v->VisitPointer(node->location());
506  }
507  }
508 }
509 
510 
513  for (int i = 0; i < new_space_nodes_.length(); ++i) {
514  Node* node = new_space_nodes_[i];
515  ASSERT(node->is_in_new_space_list());
516  if (node->is_independent() && node->IsWeak() &&
517  f(isolate_->heap(), node->location())) {
518  node->MarkPending();
519  }
520  }
521 }
522 
523 
525  for (int i = 0; i < new_space_nodes_.length(); ++i) {
526  Node* node = new_space_nodes_[i];
527  ASSERT(node->is_in_new_space_list());
528  if (node->is_independent() && node->IsWeakRetainer()) {
529  v->VisitPointer(node->location());
530  }
531  }
532 }
533 
534 
536  GarbageCollector collector) {
537  // Process weak global handle callbacks. This must be done after the
538  // GC is completely done, because the callbacks may invoke arbitrary
539  // API functions.
540  ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
541  const int initial_post_gc_processing_count = ++post_gc_processing_count_;
542  bool next_gc_likely_to_collect_more = false;
543  if (collector == SCAVENGER) {
544  for (int i = 0; i < new_space_nodes_.length(); ++i) {
545  Node* node = new_space_nodes_[i];
546  ASSERT(node->is_in_new_space_list());
547  // Skip dependent handles. Their weak callbacks might expect to be
548  // called between two global garbage collection callbacks which
549  // are not called for minor collections.
550  if (!node->is_independent()) continue;
551  if (node->PostGarbageCollectionProcessing(isolate_, this)) {
552  if (initial_post_gc_processing_count != post_gc_processing_count_) {
553  // Weak callback triggered another GC and another round of
554  // PostGarbageCollection processing. The current node might
555  // have been deleted in that round, so we need to bail out (or
556  // restart the processing).
557  return next_gc_likely_to_collect_more;
558  }
559  }
560  if (!node->IsRetainer()) {
561  next_gc_likely_to_collect_more = true;
562  }
563  }
564  } else {
565  for (NodeIterator it(this); !it.done(); it.Advance()) {
566  if (it.node()->PostGarbageCollectionProcessing(isolate_, this)) {
567  if (initial_post_gc_processing_count != post_gc_processing_count_) {
568  // See the comment above.
569  return next_gc_likely_to_collect_more;
570  }
571  }
572  if (!it.node()->IsRetainer()) {
573  next_gc_likely_to_collect_more = true;
574  }
575  }
576  }
577  // Update the list of new space nodes.
578  int last = 0;
579  for (int i = 0; i < new_space_nodes_.length(); ++i) {
580  Node* node = new_space_nodes_[i];
581  ASSERT(node->is_in_new_space_list());
582  if (node->IsRetainer() && isolate_->heap()->InNewSpace(node->object())) {
583  new_space_nodes_[last++] = node;
584  } else {
585  node->set_in_new_space_list(false);
586  }
587  }
588  new_space_nodes_.Rewind(last);
589  return next_gc_likely_to_collect_more;
590 }
591 
592 
593 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) {
594  for (NodeIterator it(this); !it.done(); it.Advance()) {
595  if (it.node()->IsStrongRetainer()) {
596  v->VisitPointer(it.node()->location());
597  }
598  }
599 }
600 
601 
602 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
603  for (NodeIterator it(this); !it.done(); it.Advance()) {
604  if (it.node()->IsRetainer()) {
605  v->VisitPointer(it.node()->location());
606  }
607  }
608 }
609 
610 
612  for (NodeIterator it(this); !it.done(); it.Advance()) {
613  if (it.node()->has_wrapper_class_id() && it.node()->IsRetainer()) {
614  v->VisitEmbedderReference(it.node()->location(),
615  it.node()->wrapper_class_id());
616  }
617  }
618 }
619 
620 
622  *stats->global_handle_count = 0;
623  *stats->weak_global_handle_count = 0;
624  *stats->pending_global_handle_count = 0;
625  *stats->near_death_global_handle_count = 0;
626  *stats->free_global_handle_count = 0;
627  for (NodeIterator it(this); !it.done(); it.Advance()) {
628  *stats->global_handle_count += 1;
629  if (it.node()->state() == Node::WEAK) {
630  *stats->weak_global_handle_count += 1;
631  } else if (it.node()->state() == Node::PENDING) {
632  *stats->pending_global_handle_count += 1;
633  } else if (it.node()->state() == Node::NEAR_DEATH) {
634  *stats->near_death_global_handle_count += 1;
635  } else if (it.node()->state() == Node::FREE) {
636  *stats->free_global_handle_count += 1;
637  }
638  }
639 }
640 
641 #ifdef DEBUG
642 
643 void GlobalHandles::PrintStats() {
644  int total = 0;
645  int weak = 0;
646  int pending = 0;
647  int near_death = 0;
648  int destroyed = 0;
649 
650  for (NodeIterator it(this); !it.done(); it.Advance()) {
651  total++;
652  if (it.node()->state() == Node::WEAK) weak++;
653  if (it.node()->state() == Node::PENDING) pending++;
654  if (it.node()->state() == Node::NEAR_DEATH) near_death++;
655  if (it.node()->state() == Node::FREE) destroyed++;
656  }
657 
658  PrintF("Global Handle Statistics:\n");
659  PrintF(" allocated memory = %" V8_PTR_PREFIX "dB\n", sizeof(Node) * total);
660  PrintF(" # weak = %d\n", weak);
661  PrintF(" # pending = %d\n", pending);
662  PrintF(" # near_death = %d\n", near_death);
663  PrintF(" # free = %d\n", destroyed);
664  PrintF(" # total = %d\n", total);
665 }
666 
667 void GlobalHandles::Print() {
668  PrintF("Global handles:\n");
669  for (NodeIterator it(this); !it.done(); it.Advance()) {
670  PrintF(" handle %p to %p%s\n",
671  reinterpret_cast<void*>(it.node()->location()),
672  reinterpret_cast<void*>(it.node()->object()),
673  it.node()->IsWeak() ? " (weak)" : "");
674  }
675 }
676 
677 #endif
678 
679 
680 
682  size_t length,
683  v8::RetainedObjectInfo* info) {
684 #ifdef DEBUG
685  for (size_t i = 0; i < length; ++i) {
686  ASSERT(!Node::FromLocation(handles[i])->is_independent());
687  }
688 #endif
689  if (length == 0) {
690  if (info != NULL) info->Dispose();
691  return;
692  }
693  object_groups_.Add(ObjectGroup::New(handles, length, info));
694 }
695 
696 
698  Object*** children,
699  size_t length) {
700 #ifdef DEBUG
701  ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
702  for (size_t i = 0; i < length; ++i) {
703  ASSERT(!Node::FromLocation(children[i])->is_independent());
704  }
705 #endif
706  if (length == 0) return;
707  implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
708 }
709 
710 
712  for (int i = 0; i < object_groups_.length(); i++) {
713  object_groups_.at(i)->Dispose();
714  }
715  object_groups_.Clear();
716 }
717 
718 
720  for (int i = 0; i < implicit_ref_groups_.length(); i++) {
721  implicit_ref_groups_.at(i)->Dispose();
722  }
723  implicit_ref_groups_.Clear();
724 }
725 
726 
728  // TODO(1428): invoke weak callbacks.
729 }
730 
731 
732 } } // namespace v8::internal
bool(* WeakSlotCallbackWithHeap)(Heap *heap, Object **pointer)
Definition: v8globals.h:167
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:288
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:2192
int * near_death_global_handle_count
Definition: heap.h:2193
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:273
static const uint16_t kPersistentHandleNoClassId
Definition: v8-profiler.h:462
NodeIterator(GlobalHandles *global_handles)
Handle< Object > Create(Object *value)
static uint16_t GetWrapperClassId(Object **location)
int * global_handle_count
Definition: heap.h:2190
static bool IsIndependent(Object **location)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:307
HeapState gc_state()
Definition: heap.h:1326
void IterateAllRoots(ObjectVisitor *v)
#define V8_PTR_PREFIX
Definition: globals.h:181
static void SetWrapperClassId(Object **location, uint16_t class_id)
void set_parameter(void *parameter)
void(* WeakReferenceCallback)(Persistent< Value > object, void *parameter)
Definition: v8.h:138
int * free_global_handle_count
Definition: heap.h:2194
void IterateAllRootsWithClassIds(ObjectVisitor *v)
void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor *v)
int * weak_global_handle_count
Definition: heap.h:2191
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)
Counters * counters()
Definition: isolate.h:819
void MarkIndependent(Object **location)
static bool IsWeak(Object **location)
void IterateNewSpaceWeakIndependentRoots(ObjectVisitor *v)
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
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:165
v8::RetainedObjectInfo * info_
void Initialize(int index, Node **first_free)
void Release(GlobalHandles *global_handles)