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

Unified Diff: src/objects-visiting-inl.h

Issue 443933002: Move objects-visiting into heap. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects-visiting.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects-visiting-inl.h
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
deleted file mode 100644
index 19fe0c610a1226e4994a60fdfa0ce31eabad5a1d..0000000000000000000000000000000000000000
--- a/src/objects-visiting-inl.h
+++ /dev/null
@@ -1,971 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_OBJECTS_VISITING_INL_H_
-#define V8_OBJECTS_VISITING_INL_H_
-
-
-namespace v8 {
-namespace internal {
-
-template<typename StaticVisitor>
-void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
- table_.Register(kVisitShortcutCandidate,
- &FixedBodyVisitor<StaticVisitor,
- ConsString::BodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitConsString,
- &FixedBodyVisitor<StaticVisitor,
- ConsString::BodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitSlicedString,
- &FixedBodyVisitor<StaticVisitor,
- SlicedString::BodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitSymbol,
- &FixedBodyVisitor<StaticVisitor,
- Symbol::BodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitFixedArray,
- &FlexibleBodyVisitor<StaticVisitor,
- FixedArray::BodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitFixedDoubleArray, &VisitFixedDoubleArray);
- table_.Register(kVisitFixedTypedArray, &VisitFixedTypedArray);
- table_.Register(kVisitFixedFloat64Array, &VisitFixedTypedArray);
-
- table_.Register(kVisitNativeContext,
- &FixedBodyVisitor<StaticVisitor,
- Context::ScavengeBodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitByteArray, &VisitByteArray);
-
- table_.Register(kVisitSharedFunctionInfo,
- &FixedBodyVisitor<StaticVisitor,
- SharedFunctionInfo::BodyDescriptor,
- int>::Visit);
-
- table_.Register(kVisitSeqOneByteString, &VisitSeqOneByteString);
-
- table_.Register(kVisitSeqTwoByteString, &VisitSeqTwoByteString);
-
- table_.Register(kVisitJSFunction, &VisitJSFunction);
-
- table_.Register(kVisitJSArrayBuffer, &VisitJSArrayBuffer);
-
- table_.Register(kVisitJSTypedArray, &VisitJSTypedArray);
-
- table_.Register(kVisitJSDataView, &VisitJSDataView);
-
- table_.Register(kVisitFreeSpace, &VisitFreeSpace);
-
- table_.Register(kVisitJSWeakCollection, &JSObjectVisitor::Visit);
-
- table_.Register(kVisitJSRegExp, &JSObjectVisitor::Visit);
-
- table_.template RegisterSpecializations<DataObjectVisitor,
- kVisitDataObject,
- kVisitDataObjectGeneric>();
-
- table_.template RegisterSpecializations<JSObjectVisitor,
- kVisitJSObject,
- kVisitJSObjectGeneric>();
- table_.template RegisterSpecializations<StructVisitor,
- kVisitStruct,
- kVisitStructGeneric>();
-}
-
-
-template<typename StaticVisitor>
-int StaticNewSpaceVisitor<StaticVisitor>::VisitJSArrayBuffer(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
-
- STATIC_ASSERT(
- JSArrayBuffer::kWeakFirstViewOffset ==
- JSArrayBuffer::kWeakNextOffset + kPointerSize);
- VisitPointers(
- heap,
- HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset),
- HeapObject::RawField(object, JSArrayBuffer::kWeakNextOffset));
- VisitPointers(
- heap,
- HeapObject::RawField(object,
- JSArrayBuffer::kWeakNextOffset + 2 * kPointerSize),
- HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields));
- return JSArrayBuffer::kSizeWithInternalFields;
-}
-
-
-template<typename StaticVisitor>
-int StaticNewSpaceVisitor<StaticVisitor>::VisitJSTypedArray(
- Map* map, HeapObject* object) {
- VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset),
- HeapObject::RawField(object, JSTypedArray::kWeakNextOffset));
- VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object,
- JSTypedArray::kWeakNextOffset + kPointerSize),
- HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields));
- return JSTypedArray::kSizeWithInternalFields;
-}
-
-
-template<typename StaticVisitor>
-int StaticNewSpaceVisitor<StaticVisitor>::VisitJSDataView(
- Map* map, HeapObject* object) {
- VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset),
- HeapObject::RawField(object, JSDataView::kWeakNextOffset));
- VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object,
- JSDataView::kWeakNextOffset + kPointerSize),
- HeapObject::RawField(object, JSDataView::kSizeWithInternalFields));
- return JSDataView::kSizeWithInternalFields;
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::Initialize() {
- table_.Register(kVisitShortcutCandidate,
- &FixedBodyVisitor<StaticVisitor,
- ConsString::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitConsString,
- &FixedBodyVisitor<StaticVisitor,
- ConsString::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitSlicedString,
- &FixedBodyVisitor<StaticVisitor,
- SlicedString::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitSymbol,
- &FixedBodyVisitor<StaticVisitor,
- Symbol::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitFixedArray, &FixedArrayVisitor::Visit);
-
- table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitFixedTypedArray, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitFixedFloat64Array, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitConstantPoolArray, &VisitConstantPoolArray);
-
- table_.Register(kVisitNativeContext, &VisitNativeContext);
-
- table_.Register(kVisitAllocationSite, &VisitAllocationSite);
-
- table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitSeqOneByteString, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
-
- table_.Register(kVisitJSWeakCollection, &VisitWeakCollection);
-
- table_.Register(kVisitOddball,
- &FixedBodyVisitor<StaticVisitor,
- Oddball::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitMap, &VisitMap);
-
- table_.Register(kVisitCode, &VisitCode);
-
- table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo);
-
- table_.Register(kVisitJSFunction, &VisitJSFunction);
-
- table_.Register(kVisitJSArrayBuffer, &VisitJSArrayBuffer);
-
- table_.Register(kVisitJSTypedArray, &VisitJSTypedArray);
-
- table_.Register(kVisitJSDataView, &VisitJSDataView);
-
- // Registration for kVisitJSRegExp is done by StaticVisitor.
-
- table_.Register(kVisitCell,
- &FixedBodyVisitor<StaticVisitor,
- Cell::BodyDescriptor,
- void>::Visit);
-
- table_.Register(kVisitPropertyCell, &VisitPropertyCell);
-
- table_.template RegisterSpecializations<DataObjectVisitor,
- kVisitDataObject,
- kVisitDataObjectGeneric>();
-
- table_.template RegisterSpecializations<JSObjectVisitor,
- kVisitJSObject,
- kVisitJSObjectGeneric>();
-
- table_.template RegisterSpecializations<StructObjectVisitor,
- kVisitStruct,
- kVisitStructGeneric>();
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry(
- Heap* heap, Address entry_address) {
- Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
- heap->mark_compact_collector()->RecordCodeEntrySlot(entry_address, code);
- StaticVisitor::MarkObject(heap, code);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer(
- Heap* heap, RelocInfo* rinfo) {
- DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
- HeapObject* object = HeapObject::cast(rinfo->target_object());
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, object);
- // TODO(ulan): It could be better to record slots only for strongly embedded
- // objects here and record slots for weakly embedded object during clearing
- // of non-live references in mark-compact.
- if (!rinfo->host()->IsWeakObject(object)) {
- StaticVisitor::MarkObject(heap, object);
- }
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitCell(
- Heap* heap, RelocInfo* rinfo) {
- DCHECK(rinfo->rmode() == RelocInfo::CELL);
- Cell* cell = rinfo->target_cell();
- // No need to record slots because the cell space is not compacted during GC.
- if (!rinfo->host()->IsWeakObject(cell)) {
- StaticVisitor::MarkObject(heap, cell);
- }
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitDebugTarget(
- Heap* heap, RelocInfo* rinfo) {
- DCHECK((RelocInfo::IsJSReturn(rinfo->rmode()) &&
- rinfo->IsPatchedReturnSequence()) ||
- (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
- rinfo->IsPatchedDebugBreakSlotSequence()));
- Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
- StaticVisitor::MarkObject(heap, target);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(
- Heap* heap, RelocInfo* rinfo) {
- DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
- Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- // Monomorphic ICs are preserved when possible, but need to be flushed
- // when they might be keeping a Context alive, or when the heap is about
- // to be serialized.
- if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
- && (target->ic_state() == MEGAMORPHIC || target->ic_state() == GENERIC ||
- target->ic_state() == POLYMORPHIC || heap->flush_monomorphic_ics() ||
- heap->isolate()->serializer_enabled() ||
- target->ic_age() != heap->global_ic_age() ||
- target->is_invalidated_weak_stub())) {
- IC::Clear(heap->isolate(), rinfo->pc(), rinfo->host()->constant_pool());
- target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- }
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
- StaticVisitor::MarkObject(heap, target);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitCodeAgeSequence(
- Heap* heap, RelocInfo* rinfo) {
- DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
- Code* target = rinfo->code_age_stub();
- DCHECK(target != NULL);
- heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
- StaticVisitor::MarkObject(heap, target);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext(
- Map* map, HeapObject* object) {
- FixedBodyVisitor<StaticVisitor,
- Context::MarkCompactBodyDescriptor,
- void>::Visit(map, object);
-
- MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
- for (int idx = Context::FIRST_WEAK_SLOT;
- idx < Context::NATIVE_CONTEXT_SLOTS;
- ++idx) {
- Object** slot = Context::cast(object)->RawFieldOfElementAt(idx);
- collector->RecordSlot(slot, slot, *slot);
- }
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitMap(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- Map* map_object = Map::cast(object);
-
- // Clears the cache of ICs related to this map.
- if (FLAG_cleanup_code_caches_at_gc) {
- map_object->ClearCodeCache(heap);
- }
-
- // When map collection is enabled we have to mark through map's transitions
- // and back pointers in a special way to make these links weak.
- if (FLAG_collect_maps && map_object->CanTransition()) {
- MarkMapContents(heap, map_object);
- } else {
- StaticVisitor::VisitPointers(heap,
- HeapObject::RawField(object, Map::kPointerFieldsBeginOffset),
- HeapObject::RawField(object, Map::kPointerFieldsEndOffset));
- }
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitPropertyCell(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
-
- Object** slot =
- HeapObject::RawField(object, PropertyCell::kDependentCodeOffset);
- if (FLAG_collect_maps) {
- // Mark property cell dependent codes array but do not push it onto marking
- // stack, this will make references from it weak. We will clean dead
- // codes when we iterate over property cells in ClearNonLiveReferences.
- HeapObject* obj = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
- StaticVisitor::MarkObjectWithoutPush(heap, obj);
- } else {
- StaticVisitor::VisitPointer(heap, slot);
- }
-
- StaticVisitor::VisitPointers(heap,
- HeapObject::RawField(object, PropertyCell::kPointerFieldsBeginOffset),
- HeapObject::RawField(object, PropertyCell::kPointerFieldsEndOffset));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitAllocationSite(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
-
- Object** slot =
- HeapObject::RawField(object, AllocationSite::kDependentCodeOffset);
- if (FLAG_collect_maps) {
- // Mark allocation site dependent codes array but do not push it onto
- // marking stack, this will make references from it weak. We will clean
- // dead codes when we iterate over allocation sites in
- // ClearNonLiveReferences.
- HeapObject* obj = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
- StaticVisitor::MarkObjectWithoutPush(heap, obj);
- } else {
- StaticVisitor::VisitPointer(heap, slot);
- }
-
- StaticVisitor::VisitPointers(heap,
- HeapObject::RawField(object, AllocationSite::kPointerFieldsBeginOffset),
- HeapObject::RawField(object, AllocationSite::kPointerFieldsEndOffset));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitWeakCollection(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- JSWeakCollection* weak_collection =
- reinterpret_cast<JSWeakCollection*>(object);
-
- // Enqueue weak collection in linked list of encountered weak collections.
- if (weak_collection->next() == heap->undefined_value()) {
- weak_collection->set_next(heap->encountered_weak_collections());
- heap->set_encountered_weak_collections(weak_collection);
- }
-
- // Skip visiting the backing hash table containing the mappings and the
- // pointer to the other enqueued weak collections, both are post-processed.
- StaticVisitor::VisitPointers(heap,
- HeapObject::RawField(object, JSWeakCollection::kPropertiesOffset),
- HeapObject::RawField(object, JSWeakCollection::kTableOffset));
- STATIC_ASSERT(JSWeakCollection::kTableOffset + kPointerSize ==
- JSWeakCollection::kNextOffset);
- STATIC_ASSERT(JSWeakCollection::kNextOffset + kPointerSize ==
- JSWeakCollection::kSize);
-
- // Partially initialized weak collection is enqueued, but table is ignored.
- if (!weak_collection->table()->IsHashTable()) return;
-
- // Mark the backing hash table without pushing it on the marking stack.
- Object** slot = HeapObject::RawField(object, JSWeakCollection::kTableOffset);
- HeapObject* obj = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
- StaticVisitor::MarkObjectWithoutPush(heap, obj);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitCode(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- Code* code = Code::cast(object);
- if (FLAG_age_code && !heap->isolate()->serializer_enabled()) {
- code->MakeOlder(heap->mark_compact_collector()->marking_parity());
- }
- code->CodeIterateBody<StaticVisitor>(heap);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
- if (shared->ic_age() != heap->global_ic_age()) {
- shared->ResetForNewContext(heap->global_ic_age());
- }
- if (FLAG_cleanup_code_caches_at_gc) {
- shared->ClearTypeFeedbackInfo();
- }
- if (FLAG_cache_optimized_code &&
- FLAG_flush_optimized_code_cache &&
- !shared->optimized_code_map()->IsSmi()) {
- // Always flush the optimized code map if requested by flag.
- shared->ClearOptimizedCodeMap();
- }
- MarkCompactCollector* collector = heap->mark_compact_collector();
- if (collector->is_code_flushing_enabled()) {
- if (FLAG_cache_optimized_code && !shared->optimized_code_map()->IsSmi()) {
- // Add the shared function info holding an optimized code map to
- // the code flusher for processing of code maps after marking.
- collector->code_flusher()->AddOptimizedCodeMap(shared);
- // Treat all references within the code map weakly by marking the
- // code map itself but not pushing it onto the marking deque.
- FixedArray* code_map = FixedArray::cast(shared->optimized_code_map());
- StaticVisitor::MarkObjectWithoutPush(heap, code_map);
- }
- if (IsFlushable(heap, shared)) {
- // This function's code looks flushable. But we have to postpone
- // the decision until we see all functions that point to the same
- // SharedFunctionInfo because some of them might be optimized.
- // That would also make the non-optimized version of the code
- // non-flushable, because it is required for bailing out from
- // optimized code.
- collector->code_flusher()->AddCandidate(shared);
- // Treat the reference to the code object weakly.
- VisitSharedFunctionInfoWeakCode(heap, object);
- return;
- }
- } else {
- if (FLAG_cache_optimized_code && !shared->optimized_code_map()->IsSmi()) {
- // Flush optimized code map on major GCs without code flushing,
- // needed because cached code doesn't contain breakpoints.
- shared->ClearOptimizedCodeMap();
- }
- }
- VisitSharedFunctionInfoStrongCode(heap, object);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- ConstantPoolArray* array = ConstantPoolArray::cast(object);
- ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR);
- while (!code_iter.is_finished()) {
- Address code_entry = reinterpret_cast<Address>(
- array->RawFieldOfElementAt(code_iter.next_index()));
- StaticVisitor::VisitCodeEntry(heap, code_entry);
- }
-
- ConstantPoolArray::Iterator heap_iter(array, ConstantPoolArray::HEAP_PTR);
- while (!heap_iter.is_finished()) {
- Object** slot = array->RawFieldOfElementAt(heap_iter.next_index());
- HeapObject* object = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, object);
- bool is_weak_object =
- (array->get_weak_object_state() ==
- ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE &&
- Code::IsWeakObjectInOptimizedCode(object)) ||
- (array->get_weak_object_state() ==
- ConstantPoolArray::WEAK_OBJECTS_IN_IC &&
- Code::IsWeakObjectInIC(object));
- if (!is_weak_object) {
- StaticVisitor::MarkObject(heap, object);
- }
- }
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSFunction(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
- JSFunction* function = JSFunction::cast(object);
- MarkCompactCollector* collector = heap->mark_compact_collector();
- if (collector->is_code_flushing_enabled()) {
- if (IsFlushable(heap, function)) {
- // This function's code looks flushable. But we have to postpone
- // the decision until we see all functions that point to the same
- // SharedFunctionInfo because some of them might be optimized.
- // That would also make the non-optimized version of the code
- // non-flushable, because it is required for bailing out from
- // optimized code.
- collector->code_flusher()->AddCandidate(function);
- // Visit shared function info immediately to avoid double checking
- // of its flushability later. This is just an optimization because
- // the shared function info would eventually be visited.
- SharedFunctionInfo* shared = function->shared();
- if (StaticVisitor::MarkObjectWithoutPush(heap, shared)) {
- StaticVisitor::MarkObject(heap, shared->map());
- VisitSharedFunctionInfoWeakCode(heap, shared);
- }
- // Treat the reference to the code object weakly.
- VisitJSFunctionWeakCode(heap, object);
- return;
- } else {
- // Visit all unoptimized code objects to prevent flushing them.
- StaticVisitor::MarkObject(heap, function->shared()->code());
- if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
- MarkInlinedFunctionsCode(heap, function->code());
- }
- }
- }
- VisitJSFunctionStrongCode(heap, object);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(
- Map* map, HeapObject* object) {
- int last_property_offset =
- JSRegExp::kSize + kPointerSize * map->inobject_properties();
- StaticVisitor::VisitPointers(map->GetHeap(),
- HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
- HeapObject::RawField(object, last_property_offset));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSArrayBuffer(
- Map* map, HeapObject* object) {
- Heap* heap = map->GetHeap();
-
- STATIC_ASSERT(
- JSArrayBuffer::kWeakFirstViewOffset ==
- JSArrayBuffer::kWeakNextOffset + kPointerSize);
- StaticVisitor::VisitPointers(
- heap,
- HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset),
- HeapObject::RawField(object, JSArrayBuffer::kWeakNextOffset));
- StaticVisitor::VisitPointers(
- heap,
- HeapObject::RawField(object,
- JSArrayBuffer::kWeakNextOffset + 2 * kPointerSize),
- HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSTypedArray(
- Map* map, HeapObject* object) {
- StaticVisitor::VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset),
- HeapObject::RawField(object, JSTypedArray::kWeakNextOffset));
- StaticVisitor::VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object,
- JSTypedArray::kWeakNextOffset + kPointerSize),
- HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSDataView(
- Map* map, HeapObject* object) {
- StaticVisitor::VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset),
- HeapObject::RawField(object, JSDataView::kWeakNextOffset));
- StaticVisitor::VisitPointers(
- map->GetHeap(),
- HeapObject::RawField(object,
- JSDataView::kWeakNextOffset + kPointerSize),
- HeapObject::RawField(object, JSDataView::kSizeWithInternalFields));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(
- Heap* heap, Map* map) {
- // Make sure that the back pointer stored either in the map itself or
- // inside its transitions array is marked. Skip recording the back
- // pointer slot since map space is not compacted.
- StaticVisitor::MarkObject(heap, HeapObject::cast(map->GetBackPointer()));
-
- // Treat pointers in the transitions array as weak and also mark that
- // array to prevent visiting it later. Skip recording the transition
- // array slot, since it will be implicitly recorded when the pointer
- // fields of this map are visited.
- if (map->HasTransitionArray()) {
- TransitionArray* transitions = map->transitions();
- MarkTransitionArray(heap, transitions);
- }
-
- // Since descriptor arrays are potentially shared, ensure that only the
- // descriptors that belong to this map are marked. The first time a
- // non-empty descriptor array is marked, its header is also visited. The slot
- // holding the descriptor array will be implicitly recorded when the pointer
- // fields of this map are visited.
- DescriptorArray* descriptors = map->instance_descriptors();
- if (StaticVisitor::MarkObjectWithoutPush(heap, descriptors) &&
- descriptors->length() > 0) {
- StaticVisitor::VisitPointers(heap,
- descriptors->GetFirstElementAddress(),
- descriptors->GetDescriptorEndSlot(0));
- }
- int start = 0;
- int end = map->NumberOfOwnDescriptors();
- if (start < end) {
- StaticVisitor::VisitPointers(heap,
- descriptors->GetDescriptorStartSlot(start),
- descriptors->GetDescriptorEndSlot(end));
- }
-
- // Mark prototype dependent codes array but do not push it onto marking
- // stack, this will make references from it weak. We will clean dead
- // codes when we iterate over maps in ClearNonLiveTransitions.
- Object** slot = HeapObject::RawField(map, Map::kDependentCodeOffset);
- HeapObject* obj = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
- StaticVisitor::MarkObjectWithoutPush(heap, obj);
-
- // Mark the pointer fields of the Map. Since the transitions array has
- // been marked already, it is fine that one of these fields contains a
- // pointer to it.
- StaticVisitor::VisitPointers(heap,
- HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
- HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray(
- Heap* heap, TransitionArray* transitions) {
- if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return;
-
- // Simple transitions do not have keys nor prototype transitions.
- if (transitions->IsSimpleTransition()) return;
-
- if (transitions->HasPrototypeTransitions()) {
- // Mark prototype transitions array but do not push it onto marking
- // stack, this will make references from it weak. We will clean dead
- // prototype transitions in ClearNonLiveTransitions.
- Object** slot = transitions->GetPrototypeTransitionsSlot();
- HeapObject* obj = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
- StaticVisitor::MarkObjectWithoutPush(heap, obj);
- }
-
- for (int i = 0; i < transitions->number_of_transitions(); ++i) {
- StaticVisitor::VisitPointer(heap, transitions->GetKeySlot(i));
- }
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::MarkInlinedFunctionsCode(
- Heap* heap, Code* code) {
- // Skip in absence of inlining.
- // TODO(turbofan): Revisit once we support inlining.
- if (code->is_turbofanned()) return;
- // For optimized functions we should retain both non-optimized version
- // of its code and non-optimized version of all inlined functions.
- // This is required to support bailing out from inlined code.
- DeoptimizationInputData* data =
- DeoptimizationInputData::cast(code->deoptimization_data());
- FixedArray* literals = data->LiteralArray();
- for (int i = 0, count = data->InlinedFunctionCount()->value();
- i < count;
- i++) {
- JSFunction* inlined = JSFunction::cast(literals->get(i));
- StaticVisitor::MarkObject(heap, inlined->shared()->code());
- }
-}
-
-
-inline static bool IsValidNonBuiltinContext(Object* context) {
- return context->IsContext() &&
- !Context::cast(context)->global_object()->IsJSBuiltinsObject();
-}
-
-
-inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
- Object* undefined = heap->undefined_value();
- return (info->script() != undefined) &&
- (reinterpret_cast<Script*>(info->script())->source() != undefined);
-}
-
-
-template<typename StaticVisitor>
-bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(
- Heap* heap, JSFunction* function) {
- SharedFunctionInfo* shared_info = function->shared();
-
- // Code is either on stack, in compilation cache or referenced
- // by optimized version of function.
- MarkBit code_mark = Marking::MarkBitFrom(function->code());
- if (code_mark.Get()) {
- return false;
- }
-
- // The function must have a valid context and not be a builtin.
- if (!IsValidNonBuiltinContext(function->context())) {
- return false;
- }
-
- // We do not (yet) flush code for optimized functions.
- if (function->code() != shared_info->code()) {
- return false;
- }
-
- // Check age of optimized code.
- if (FLAG_age_code && !function->code()->IsOld()) {
- return false;
- }
-
- return IsFlushable(heap, shared_info);
-}
-
-
-template<typename StaticVisitor>
-bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(
- Heap* heap, SharedFunctionInfo* shared_info) {
- // Code is either on stack, in compilation cache or referenced
- // by optimized version of function.
- MarkBit code_mark = Marking::MarkBitFrom(shared_info->code());
- if (code_mark.Get()) {
- return false;
- }
-
- // The function must be compiled and have the source code available,
- // to be able to recompile it in case we need the function again.
- if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) {
- return false;
- }
-
- // We never flush code for API functions.
- Object* function_data = shared_info->function_data();
- if (function_data->IsFunctionTemplateInfo()) {
- return false;
- }
-
- // Only flush code for functions.
- if (shared_info->code()->kind() != Code::FUNCTION) {
- return false;
- }
-
- // Function must be lazy compilable.
- if (!shared_info->allows_lazy_compilation()) {
- return false;
- }
-
- // We do not (yet?) flush code for generator functions, because we don't know
- // if there are still live activations (generator objects) on the heap.
- if (shared_info->is_generator()) {
- return false;
- }
-
- // If this is a full script wrapped in a function we do not flush the code.
- if (shared_info->is_toplevel()) {
- return false;
- }
-
- // If this is a function initialized with %SetCode then the one-to-one
- // relation between SharedFunctionInfo and Code is broken.
- if (shared_info->dont_flush()) {
- return false;
- }
-
- // Check age of code. If code aging is disabled we never flush.
- if (!FLAG_age_code || !shared_info->code()->IsOld()) {
- return false;
- }
-
- return true;
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoStrongCode(
- Heap* heap, HeapObject* object) {
- Object** start_slot =
- HeapObject::RawField(object,
- SharedFunctionInfo::BodyDescriptor::kStartOffset);
- Object** end_slot =
- HeapObject::RawField(object,
- SharedFunctionInfo::BodyDescriptor::kEndOffset);
- StaticVisitor::VisitPointers(heap, start_slot, end_slot);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoWeakCode(
- Heap* heap, HeapObject* object) {
- Object** name_slot =
- HeapObject::RawField(object, SharedFunctionInfo::kNameOffset);
- StaticVisitor::VisitPointer(heap, name_slot);
-
- // Skip visiting kCodeOffset as it is treated weakly here.
- STATIC_ASSERT(SharedFunctionInfo::kNameOffset + kPointerSize ==
- SharedFunctionInfo::kCodeOffset);
- STATIC_ASSERT(SharedFunctionInfo::kCodeOffset + kPointerSize ==
- SharedFunctionInfo::kOptimizedCodeMapOffset);
-
- Object** start_slot =
- HeapObject::RawField(object,
- SharedFunctionInfo::kOptimizedCodeMapOffset);
- Object** end_slot =
- HeapObject::RawField(object,
- SharedFunctionInfo::BodyDescriptor::kEndOffset);
- StaticVisitor::VisitPointers(heap, start_slot, end_slot);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionStrongCode(
- Heap* heap, HeapObject* object) {
- Object** start_slot =
- HeapObject::RawField(object, JSFunction::kPropertiesOffset);
- Object** end_slot =
- HeapObject::RawField(object, JSFunction::kCodeEntryOffset);
- StaticVisitor::VisitPointers(heap, start_slot, end_slot);
-
- VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset);
- STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize ==
- JSFunction::kPrototypeOrInitialMapOffset);
-
- start_slot =
- HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset);
- end_slot =
- HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset);
- StaticVisitor::VisitPointers(heap, start_slot, end_slot);
-}
-
-
-template<typename StaticVisitor>
-void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionWeakCode(
- Heap* heap, HeapObject* object) {
- Object** start_slot =
- HeapObject::RawField(object, JSFunction::kPropertiesOffset);
- Object** end_slot =
- HeapObject::RawField(object, JSFunction::kCodeEntryOffset);
- StaticVisitor::VisitPointers(heap, start_slot, end_slot);
-
- // Skip visiting kCodeEntryOffset as it is treated weakly here.
- STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize ==
- JSFunction::kPrototypeOrInitialMapOffset);
-
- start_slot =
- HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset);
- end_slot =
- HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset);
- StaticVisitor::VisitPointers(heap, start_slot, end_slot);
-}
-
-
-void Code::CodeIterateBody(ObjectVisitor* v) {
- int mode_mask = RelocInfo::kCodeTargetMask |
- RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
- RelocInfo::ModeMask(RelocInfo::CELL) |
- RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
- RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
- RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
- RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
-
- // There are two places where we iterate code bodies: here and the
- // templated CodeIterateBody (below). They should be kept in sync.
- IteratePointer(v, kRelocationInfoOffset);
- IteratePointer(v, kHandlerTableOffset);
- IteratePointer(v, kDeoptimizationDataOffset);
- IteratePointer(v, kTypeFeedbackInfoOffset);
- IterateNextCodeLink(v, kNextCodeLinkOffset);
- IteratePointer(v, kConstantPoolOffset);
-
- RelocIterator it(this, mode_mask);
- Isolate* isolate = this->GetIsolate();
- for (; !it.done(); it.next()) {
- it.rinfo()->Visit(isolate, v);
- }
-}
-
-
-template<typename StaticVisitor>
-void Code::CodeIterateBody(Heap* heap) {
- int mode_mask = RelocInfo::kCodeTargetMask |
- RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
- RelocInfo::ModeMask(RelocInfo::CELL) |
- RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
- RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
- RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
- RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
-
- // There are two places where we iterate code bodies: here and the non-
- // templated CodeIterateBody (above). They should be kept in sync.
- StaticVisitor::VisitPointer(
- heap,
- reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset));
- StaticVisitor::VisitPointer(
- heap,
- reinterpret_cast<Object**>(this->address() + kHandlerTableOffset));
- StaticVisitor::VisitPointer(
- heap,
- reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset));
- StaticVisitor::VisitPointer(
- heap,
- reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset));
- StaticVisitor::VisitNextCodeLink(
- heap,
- reinterpret_cast<Object**>(this->address() + kNextCodeLinkOffset));
- StaticVisitor::VisitPointer(
- heap,
- reinterpret_cast<Object**>(this->address() + kConstantPoolOffset));
-
-
- RelocIterator it(this, mode_mask);
- for (; !it.done(); it.next()) {
- it.rinfo()->template Visit<StaticVisitor>(heap);
- }
-}
-
-
-} } // namespace v8::internal
-
-#endif // V8_OBJECTS_VISITING_INL_H_
« no previous file with comments | « src/objects-visiting.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698