From 7f6dc1ff9b6f4325475e69e8980aa164c19ba6ff Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 17 Feb 2014 10:41:25 +0000 Subject: [PATCH] Do not visit smis in the root list during GC. R=mstarzinger@chromium.org BUG=328804 LOG=N Review URL: https://codereview.chromium.org/166023003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19400 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 2 +- src/heap-inl.h | 7 +++++++ src/heap.cc | 9 +++++++++ src/heap.h | 38 +++++++++++++++++++++++++++++--------- src/objects.h | 1 + src/serialize.cc | 4 ++-- src/serialize.h | 1 - 7 files changed, 49 insertions(+), 13 deletions(-) diff --git a/include/v8.h b/include/v8.h index dc1506f..dd8f268 100644 --- a/include/v8.h +++ b/include/v8.h @@ -5414,7 +5414,7 @@ class Internals { static const int kNullValueRootIndex = 7; static const int kTrueValueRootIndex = 8; static const int kFalseValueRootIndex = 9; - static const int kEmptyStringRootIndex = 148; + static const int kEmptyStringRootIndex = 141; static const int kNodeClassIdOffset = 1 * kApiPointerSize; static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3; diff --git a/src/heap-inl.h b/src/heap-inl.h index 35bad4a..a45e3ab 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -820,6 +820,13 @@ void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) { } +void VerifySmisVisitor::VisitPointers(Object** start, Object** end) { + for (Object** current = start; current < end; current++) { + CHECK((*current)->IsSmi()); + } +} + + double GCTracer::SizeOfHeapObjects() { return (static_cast(heap_->SizeOfObjects())) / MB; } diff --git a/src/heap.cc b/src/heap.cc index c17794f..533e2f2 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -5841,6 +5841,9 @@ void Heap::Verify() { VerifyPointersVisitor visitor; IterateRoots(&visitor, VISIT_ONLY_STRONG); + VerifySmisVisitor smis_visitor; + IterateSmiRoots(&smis_visitor); + new_space_.Verify(); old_pointer_space_->Verify(&visitor); @@ -6138,6 +6141,12 @@ void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { } +void Heap::IterateSmiRoots(ObjectVisitor* v) { + v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]); + v->Synchronize(VisitorSynchronization::kSmiRootList); +} + + void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); v->Synchronize(VisitorSynchronization::kStrongRootList); diff --git a/src/heap.h b/src/heap.h index eb3afd9..c19b743 100644 --- a/src/heap.h +++ b/src/heap.h @@ -78,7 +78,6 @@ namespace internal { V(ByteArray, empty_byte_array, EmptyByteArray) \ V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \ V(ConstantPoolArray, empty_constant_pool_array, EmptyConstantPoolArray) \ - V(Smi, stack_limit, StackLimit) \ V(Oddball, arguments_marker, ArgumentsMarker) \ /* The roots above this line should be boring from a GC point of view. */ \ /* This means they are never in new space and never on a page that is */ \ @@ -186,14 +185,8 @@ namespace internal { V(Code, js_entry_code, JsEntryCode) \ V(Code, js_construct_entry_code, JsConstructEntryCode) \ V(FixedArray, natives_source_cache, NativesSourceCache) \ - V(Smi, last_script_id, LastScriptId) \ V(Script, empty_script, EmptyScript) \ - V(Smi, real_stack_limit, RealStackLimit) \ V(NameDictionary, intrinsic_function_names, IntrinsicFunctionNames) \ - V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \ - V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \ - V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \ - V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) \ V(Cell, undefined_cell, UndefineCell) \ V(JSObject, observation_state, ObservationState) \ V(Map, external_map, ExternalMap) \ @@ -206,8 +199,19 @@ namespace internal { V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad) \ V(JSObject, microtask_state, MicrotaskState) +// Entries in this list are limited to Smis and are not visited during GC. +#define SMI_ROOT_LIST(V) \ + V(Smi, stack_limit, StackLimit) \ + V(Smi, real_stack_limit, RealStackLimit) \ + V(Smi, last_script_id, LastScriptId) \ + V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \ + V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \ + V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \ + V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) + #define ROOT_LIST(V) \ STRONG_ROOT_LIST(V) \ + SMI_ROOT_LIST(V) \ V(StringTable, string_table, StringTable) // Heap roots that are known to be immortal immovable, for which we can safely @@ -1347,6 +1351,9 @@ class Heap { void IterateRoots(ObjectVisitor* v, VisitMode mode); // Iterates over all strong roots in the heap. void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); + // Iterates over entries in the smi roots list. Only interesting to the + // serializer/deserializer, since GC does not care about smis. + void IterateSmiRoots(ObjectVisitor* v); // Iterates over all the other roots in the heap. void IterateWeakRoots(ObjectVisitor* v, VisitMode mode); @@ -1582,7 +1589,7 @@ class Heap { // Implements the corresponding V8 API function. bool IdleNotification(int hint); - // Declare all the root indices. + // Declare all the root indices. This defines the root list order. enum RootListIndex { #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION) @@ -1598,8 +1605,14 @@ class Heap { #undef DECLARE_STRUCT_MAP kStringTableRootIndex, + +#define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, + SMI_ROOT_LIST(ROOT_INDEX_DECLARATION) +#undef ROOT_INDEX_DECLARATION + + kRootListLength, kStrongRootListLength = kStringTableRootIndex, - kRootListLength + kSmiRootsStart = kStringTableRootIndex + 1 }; STATIC_CHECK(kUndefinedValueRootIndex == Internals::kUndefinedValueRootIndex); @@ -2589,6 +2602,13 @@ class VerifyPointersVisitor: public ObjectVisitor { }; +// Verify that all objects are Smis. +class VerifySmisVisitor: public ObjectVisitor { + public: + inline void VisitPointers(Object** start, Object** end); +}; + + // Space iterator for iterating over all spaces of the heap. Returns each space // in turn, and null when it is done. class AllSpaces BASE_EMBEDDED { diff --git a/src/objects.h b/src/objects.h index 62251fb..1f83a38 100644 --- a/src/objects.h +++ b/src/objects.h @@ -10636,6 +10636,7 @@ class BreakPointInfo: public Struct { V(kStringTable, "string_table", "(Internalized strings)") \ V(kExternalStringsTable, "external_strings_table", "(External strings)") \ V(kStrongRootList, "strong_root_list", "(Strong roots)") \ + V(kSmiRootList, "smi_root_list", "(Smi roots)") \ V(kInternalizedString, "internalized_string", "(Internal string)") \ V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \ V(kTop, "top", "(Isolate)") \ diff --git a/src/serialize.cc b/src/serialize.cc index 5adc2b8..14b1b9c 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -789,6 +789,7 @@ void Deserializer::Deserialize(Isolate* isolate) { ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty()); ASSERT_EQ(NULL, external_reference_decoder_); external_reference_decoder_ = new ExternalReferenceDecoder(isolate); + isolate_->heap()->IterateSmiRoots(this); isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); isolate_->heap()->RepairFreeListsAfterBoot(); isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); @@ -1253,7 +1254,6 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) : isolate_(isolate), sink_(sink), - current_root_index_(0), external_reference_encoder_(new ExternalReferenceEncoder(isolate)), root_index_wave_front_(0) { // The serializer is meant to be used only to generate initial heap images @@ -1279,7 +1279,7 @@ void StartupSerializer::SerializeStrongReferences() { CHECK_EQ(0, isolate->eternal_handles()->NumberOfHandles()); // We don't support serializing installed extensions. CHECK(!isolate->has_installed_extensions()); - + isolate->heap()->IterateSmiRoots(this); isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); } diff --git a/src/serialize.h b/src/serialize.h index ee9df39..2ad9bb1 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -579,7 +579,6 @@ class Serializer : public SerializerDeserializer { // relative addresses for back references. int fullness_[LAST_SPACE + 1]; SnapshotByteSink* sink_; - int current_root_index_; ExternalReferenceEncoder* external_reference_encoder_; static bool serialization_enabled_; // Did we already make use of the fact that serialization was not enabled? -- 2.7.4