39 ObjectGroup::~ObjectGroup() {
72 in_new_space_list_ =
false;
73 parameter_or_next_free_.next_free =
NULL;
79 index_ =
static_cast<uint8_t
>(index);
80 ASSERT(static_cast<int>(index_) == index);
82 in_new_space_list_ =
false;
83 parameter_or_next_free_.next_free = *first_free;
93 parameter_or_next_free_.parameter =
NULL;
95 IncreaseBlockUses(global_handles);
101 global_handles->number_of_weak_handles_--;
102 if (object_->IsJSGlobalObject()) {
103 global_handles->number_of_global_object_weak_handles_--;
107 parameter_or_next_free_.next_free = global_handles->first_free_;
108 global_handles->first_free_ =
this;
109 DecreaseBlockUses(global_handles);
123 class_id_ = class_id;
167 parameter_or_next_free_.parameter =
parameter;
171 return parameter_or_next_free_.parameter;
177 return parameter_or_next_free_.next_free;
181 parameter_or_next_free_.next_free = value;
189 global_handles->number_of_weak_handles_++;
190 if (object_->IsJSGlobalObject()) {
191 global_handles->number_of_global_object_weak_handles_++;
202 global_handles->number_of_weak_handles_--;
203 if (object_->IsJSGlobalObject()) {
204 global_handles->number_of_global_object_weak_handles_--;
227 ASSERT(!object_->IsExternalAsciiString() ||
229 ASSERT(!object_->IsExternalTwoByteString() ||
232 VMState
state(isolate, EXTERNAL);
243 inline void IncreaseBlockUses(
GlobalHandles* global_handles);
244 inline void DecreaseBlockUses(
GlobalHandles* global_handles);
262 bool independent_ : 1;
263 bool in_new_space_list_ : 1;
273 } parameter_or_next_free_;
275 DISALLOW_COPY_AND_ASSIGN(
Node);
284 : next_(next), used_nodes_(0), next_used_(
NULL), prev_used_(
NULL) {}
287 for (
int i =
kSize - 1; i >= 0; --i) {
294 return &nodes_[index];
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;
304 if (old_first ==
NULL)
return;
305 old_first->prev_used_ =
this;
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_;
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);
345 void GlobalHandles::Node::IncreaseBlockUses(GlobalHandles* global_handles) {
346 FindBlock()->IncreaseUses(global_handles);
350 void GlobalHandles::Node::DecreaseBlockUses(GlobalHandles* global_handles) {
351 FindBlock()->DecreaseUses(global_handles);
358 : block_(global_handles->first_used_block_),
365 return block_->node_at(index_);
372 block_ = block_->next_used();
385 number_of_weak_handles_(0),
386 number_of_global_object_weak_handles_(0),
387 number_of_global_handles_(0),
389 first_used_block_(
NULL),
391 post_gc_processing_count_(0) {}
396 while (block !=
NULL) {
406 isolate_->
counters()->global_handles()->Increment();
407 number_of_global_handles_++;
408 if (first_free_ ==
NULL) {
409 first_block_ =
new NodeBlock(first_block_);
414 Node* result = first_free_;
419 new_space_nodes_.Add(result);
427 isolate_->
counters()->global_handles()->Decrement();
428 number_of_global_handles_--;
429 if (location ==
NULL)
return;
468 if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location());
476 if (it.node()->IsWeak() && it.node()->callback() == callback) {
477 f(it.node()->object(), it.node()->parameter());
485 if (it.node()->IsWeak() && f(it.node()->location())) {
486 it.node()->MarkPending();
493 for (
int i = 0; i < new_space_nodes_.length(); ++i) {
494 Node* node = new_space_nodes_[i];
505 for (
int i = 0; i < new_space_nodes_.length(); ++i) {
506 Node* node = new_space_nodes_[i];
517 for (
int i = 0; i < new_space_nodes_.length(); ++i) {
518 Node* node = new_space_nodes_[i];
533 const int initial_post_gc_processing_count = ++post_gc_processing_count_;
534 bool next_gc_likely_to_collect_more =
false;
536 for (
int i = 0; i < new_space_nodes_.length(); ++i) {
537 Node* node = new_space_nodes_[i];
544 if (initial_post_gc_processing_count != post_gc_processing_count_) {
549 return next_gc_likely_to_collect_more;
553 next_gc_likely_to_collect_more =
true;
558 if (it.node()->PostGarbageCollectionProcessing(isolate_,
this)) {
559 if (initial_post_gc_processing_count != post_gc_processing_count_) {
561 return next_gc_likely_to_collect_more;
564 if (!it.node()->IsRetainer()) {
565 next_gc_likely_to_collect_more =
true;
571 for (
int i = 0; i < new_space_nodes_.length(); ++i) {
572 Node* node = new_space_nodes_[i];
575 new_space_nodes_[last++] = node;
580 new_space_nodes_.Rewind(last);
581 return next_gc_likely_to_collect_more;
587 if (it.node()->IsStrongRetainer()) {
588 v->VisitPointer(it.node()->location());
596 if (it.node()->IsRetainer()) {
597 v->VisitPointer(it.node()->location());
605 if (it.node()->has_wrapper_class_id() && it.node()->IsRetainer()) {
606 v->VisitEmbedderReference(it.node()->location(),
607 it.node()->wrapper_class_id());
627 }
else if (it.node()->state() ==
Node::FREE) {
635 void GlobalHandles::PrintStats() {
642 for (NodeIterator it(
this); !it.done(); it.Advance()) {
647 if (it.node()->state() ==
Node::FREE) destroyed++;
650 PrintF(
"Global Handle Statistics:\n");
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);
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)" :
"");
677 for (
size_t i = 0; i < length; ++i) {
694 for (
size_t i = 0; i < length; ++i) {
698 if (length == 0)
return;
704 for (
int i = 0; i < object_groups_.length(); i++) {
705 object_groups_.at(i)->Dispose();
707 object_groups_.Clear();
712 for (
int i = 0; i < implicit_ref_groups_.length(); i++) {
713 implicit_ref_groups_.at(i)->Dispose();
715 implicit_ref_groups_.Clear();
bool(* WeakSlotCallbackWithHeap)(Heap *heap, Object **pointer)
void RemoveImplicitRefGroups()
void Destroy(Object **location)
static ObjectGroup * New(Object ***handles, size_t length, v8::RetainedObjectInfo *info)
Node * node_at(int index)
bool is_in_new_space_list() const
void MakeWeak(GlobalHandles *global_handles, void *parameter, WeakReferenceCallback callback)
bool IsStrongRetainer() const
void PrintF(const char *format,...)
bool InNewSpace(Object *object)
void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f)
void IncreaseUses(GlobalHandles *global_handles)
void AddImplicitReferences(HeapObject **parent, Object ***children, size_t length)
static ExternalTwoByteString * cast(Object *obj)
NodeBlock(NodeBlock *next)
static bool IsNearDeath(Object **location)
NodeBlock * prev_used() const
void IterateWeakRoots(ObjectVisitor *v)
#define ASSERT(condition)
static Node * FromLocation(Object **location)
void ClearWeakness(Object **location)
v8::Handle< v8::Value > Print(const v8::Arguments &args)
void IterateStrongRoots(ObjectVisitor *v)
WeakReferenceCallback callback()
void Acquire(Object *object, GlobalHandles *global_handles)
const Resource * resource()
Handle< Object > handle()
static ExternalAsciiString * cast(Object *obj)
void AddObjectGroup(Object ***handles, size_t length, v8::RetainedObjectInfo *info)
int * pending_global_handle_count
void set_next_free(Node *value)
int * near_death_global_handle_count
void DecreaseUses(GlobalHandles *global_handles)
uint16_t wrapper_class_id() const
void set_in_new_space_list(bool v)
bool PostGarbageCollectionProcessing(GarbageCollector collector)
void set_wrapper_class_id(uint16_t class_id)
void PutNodesOnFreeList(Node **first_free)
#define OFFSET_OF(type, field)
static const uint16_t kPersistentHandleNoClassId
NodeIterator(GlobalHandles *global_handles)
Handle< Object > Create(Object *value)
int * global_handle_count
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
void IterateAllRoots(ObjectVisitor *v)
static void SetWrapperClassId(Object **location, uint16_t class_id)
void set_parameter(void *parameter)
void(* WeakReferenceCallback)(Persistent< Value > object, void *parameter)
int * free_global_handle_count
void IterateAllRootsWithClassIds(ObjectVisitor *v)
void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor *v)
NodeBlock * next_used() const
int * weak_global_handle_count
void IdentifyWeakHandles(WeakSlotCallback f)
void RecordStats(HeapStats *stats)
const Resource * resource()
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
void MarkIndependent(Object **location)
static bool IsWeak(Object **location)
void RemoveObjectGroups()
void IterateNewSpaceWeakIndependentRoots(ObjectVisitor *v)
void MakeWeak(Object **location, void *parameter, WeakReferenceCallback callback)
bool is_independent() const
void ClearWeakness(GlobalHandles *global_handles)
bool IsWeakRetainer() const
bool has_wrapper_class_id() const
bool PostGarbageCollectionProcessing(Isolate *isolate, GlobalHandles *global_handles)
bool(* WeakSlotCallback)(Object **pointer)
v8::RetainedObjectInfo * info_
void Initialize(int index, Node **first_free)
void Release(GlobalHandles *global_handles)