Make serializer non-static.
R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/296853007 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21430 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
e443c89206
commit
d0398c08ce
@ -124,7 +124,8 @@ AssemblerBase::AssemblerBase(Isolate* isolate, void* buffer, int buffer_size)
|
||||
enabled_cpu_features_(0),
|
||||
emit_debug_code_(FLAG_debug_code),
|
||||
predictable_code_size_(false),
|
||||
serializer_enabled_(Serializer::enabled(isolate)) {
|
||||
// We may use the assembler without an isolate.
|
||||
serializer_enabled_(isolate && isolate->serializer_enabled()) {
|
||||
if (FLAG_mask_constants_with_cookie && isolate != NULL) {
|
||||
jit_cookie_ = isolate->random_number_generator()->NextInt();
|
||||
}
|
||||
|
@ -2522,8 +2522,8 @@ void Genesis::MakeFunctionInstancePrototypeWritable() {
|
||||
class NoTrackDoubleFieldsForSerializerScope {
|
||||
public:
|
||||
explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
|
||||
: isolate_(isolate), flag_(FLAG_track_double_fields) {
|
||||
if (Serializer::enabled(isolate)) {
|
||||
: flag_(FLAG_track_double_fields) {
|
||||
if (isolate->serializer_enabled()) {
|
||||
// Disable tracking double fields because heap numbers treated as
|
||||
// immutable by the serializer.
|
||||
FLAG_track_double_fields = false;
|
||||
@ -2531,13 +2531,10 @@ class NoTrackDoubleFieldsForSerializerScope {
|
||||
}
|
||||
|
||||
~NoTrackDoubleFieldsForSerializerScope() {
|
||||
if (Serializer::enabled(isolate_)) {
|
||||
FLAG_track_double_fields = flag_;
|
||||
}
|
||||
FLAG_track_double_fields = flag_;
|
||||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
bool flag_;
|
||||
};
|
||||
|
||||
@ -2614,7 +2611,7 @@ Genesis::Genesis(Isolate* isolate,
|
||||
// We can't (de-)serialize typed arrays currently, but we are lucky: The state
|
||||
// of the random number generator needs no initialization during snapshot
|
||||
// creation time and we don't need trigonometric functions then.
|
||||
if (!Serializer::enabled(isolate)) {
|
||||
if (!isolate->serializer_enabled()) {
|
||||
// Initially seed the per-context random number generator using the
|
||||
// per-isolate random number generator.
|
||||
const int num_elems = 2;
|
||||
|
@ -518,7 +518,7 @@ void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
|
||||
// TODO(yangguo): check whether those heuristics are still up-to-date.
|
||||
// We do not shrink objects that go into a snapshot (yet), so we adjust
|
||||
// the estimate conservatively.
|
||||
if (Serializer::enabled(shared->GetIsolate())) {
|
||||
if (shared->GetIsolate()->serializer_enabled()) {
|
||||
estimate += 2;
|
||||
} else if (FLAG_clever_optimizations) {
|
||||
// Inobject slack tracking will reclaim redundant inobject space later,
|
||||
|
@ -1990,7 +1990,7 @@ void Factory::SetNumberStringCache(Handle<Object> number,
|
||||
// cache in the snapshot to keep boot-time memory usage down.
|
||||
// If we expand the number string cache already while creating
|
||||
// the snapshot then that didn't work out.
|
||||
ASSERT(!Serializer::enabled(isolate()) || FLAG_extra_code != NULL);
|
||||
ASSERT(!isolate()->serializer_enabled() || FLAG_extra_code != NULL);
|
||||
Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
|
||||
isolate()->heap()->set_number_string_cache(*new_cache);
|
||||
return;
|
||||
|
@ -640,7 +640,7 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
|
||||
// Skip saved double registers.
|
||||
if (safepoint_entry.has_doubles()) {
|
||||
// Number of doubles not known at snapshot time.
|
||||
ASSERT(!Serializer::enabled(isolate()));
|
||||
ASSERT(!isolate()->serializer_enabled());
|
||||
parameters_base += DoubleRegister::NumAllocatableRegisters() *
|
||||
kDoubleSize / kPointerSize;
|
||||
}
|
||||
|
@ -4389,7 +4389,7 @@ bool Heap::IdleNotification(int hint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FLAG_incremental_marking || Serializer::enabled(isolate_)) {
|
||||
if (!FLAG_incremental_marking || isolate_->serializer_enabled()) {
|
||||
return IdleGlobalGC();
|
||||
}
|
||||
|
||||
|
@ -8034,7 +8034,7 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
|
||||
if (call_type == kCallApiFunction) {
|
||||
// Cannot embed a direct reference to the global proxy map
|
||||
// as it maybe dropped on deserialization.
|
||||
CHECK(!Serializer::enabled(isolate()));
|
||||
CHECK(!isolate()->serializer_enabled());
|
||||
ASSERT_EQ(0, receiver_maps->length());
|
||||
receiver_maps->Add(handle(
|
||||
function->context()->global_object()->global_receiver()->map()),
|
||||
@ -8221,7 +8221,7 @@ HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
|
||||
if (shared->strict_mode() == SLOPPY && !shared->native()) {
|
||||
// Cannot embed a direct reference to the global proxy
|
||||
// as is it dropped on deserialization.
|
||||
CHECK(!Serializer::enabled(isolate()));
|
||||
CHECK(!isolate()->serializer_enabled());
|
||||
Handle<JSObject> global_receiver(
|
||||
target->context()->global_object()->global_receiver());
|
||||
return Add<HConstant>(global_receiver);
|
||||
|
@ -463,7 +463,7 @@ bool IncrementalMarking::WorthActivating() {
|
||||
return FLAG_incremental_marking &&
|
||||
FLAG_incremental_marking_steps &&
|
||||
heap_->gc_state() == Heap::NOT_IN_GC &&
|
||||
!Serializer::enabled(heap_->isolate()) &&
|
||||
!heap_->isolate()->serializer_enabled() &&
|
||||
heap_->isolate()->IsInitialized() &&
|
||||
heap_->PromotedSpaceSizeOfObjects() > kActivationThreshold;
|
||||
}
|
||||
@ -541,7 +541,7 @@ void IncrementalMarking::Start(CompactionFlag flag) {
|
||||
ASSERT(FLAG_incremental_marking_steps);
|
||||
ASSERT(state_ == STOPPED);
|
||||
ASSERT(heap_->gc_state() == Heap::NOT_IN_GC);
|
||||
ASSERT(!Serializer::enabled(heap_->isolate()));
|
||||
ASSERT(!heap_->isolate()->serializer_enabled());
|
||||
ASSERT(heap_->isolate()->IsInitialized());
|
||||
|
||||
ResetStepCounters();
|
||||
|
@ -1457,8 +1457,8 @@ Isolate::Isolate()
|
||||
// TODO(bmeurer) Initialized lazily because it depends on flags; can
|
||||
// be fixed once the default isolate cleanup is done.
|
||||
random_number_generator_(NULL),
|
||||
serializer_enabled_(false),
|
||||
has_fatal_error_(false),
|
||||
use_crankshaft_(true),
|
||||
initialized_from_snapshot_(false),
|
||||
cpu_profiler_(NULL),
|
||||
heap_profiler_(NULL),
|
||||
@ -1776,10 +1776,6 @@ bool Isolate::Init(Deserializer* des) {
|
||||
|
||||
has_fatal_error_ = false;
|
||||
|
||||
use_crankshaft_ = FLAG_crankshaft
|
||||
&& !Serializer::enabled(this)
|
||||
&& CpuFeatures::SupportsCrankshaft();
|
||||
|
||||
if (function_entry_hook() != NULL) {
|
||||
// When function entry hooking is in effect, we have to create the code
|
||||
// stubs from scratch to get entry hooks, rather than loading the previously
|
||||
@ -1965,7 +1961,7 @@ bool Isolate::Init(Deserializer* des) {
|
||||
kDeoptTableSerializeEntryCount - 1);
|
||||
}
|
||||
|
||||
if (!Serializer::enabled(this)) {
|
||||
if (!serializer_enabled()) {
|
||||
// Ensure that all stubs which need to be generated ahead of time, but
|
||||
// cannot be serialized into the snapshot have been generated.
|
||||
HandleScope scope(this);
|
||||
@ -2138,6 +2134,13 @@ Map* Isolate::get_initial_js_array_map(ElementsKind kind) {
|
||||
}
|
||||
|
||||
|
||||
bool Isolate::use_crankshaft() const {
|
||||
return FLAG_crankshaft &&
|
||||
!serializer_enabled_ &&
|
||||
CpuFeatures::SupportsCrankshaft();
|
||||
}
|
||||
|
||||
|
||||
bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
|
||||
Map* root_array_map =
|
||||
get_initial_js_array_map(GetInitialFastElementsKind());
|
||||
|
@ -963,10 +963,18 @@ class Isolate {
|
||||
|
||||
THREAD_LOCAL_TOP_ACCESSOR(LookupResult*, top_lookup_result)
|
||||
|
||||
void enable_serializer() {
|
||||
// The serializer can only be enabled before the isolate init.
|
||||
ASSERT(state_ != INITIALIZED);
|
||||
serializer_enabled_ = true;
|
||||
}
|
||||
|
||||
bool serializer_enabled() const { return serializer_enabled_; }
|
||||
|
||||
bool IsDead() { return has_fatal_error_; }
|
||||
void SignalFatalError() { has_fatal_error_ = true; }
|
||||
|
||||
bool use_crankshaft() const { return use_crankshaft_; }
|
||||
bool use_crankshaft() const;
|
||||
|
||||
bool initialized_from_snapshot() { return initialized_from_snapshot_; }
|
||||
|
||||
@ -1232,12 +1240,12 @@ class Isolate {
|
||||
CallInterfaceDescriptor* call_descriptors_;
|
||||
RandomNumberGenerator* random_number_generator_;
|
||||
|
||||
// Whether the isolate has been created for snapshotting.
|
||||
bool serializer_enabled_;
|
||||
|
||||
// True if fatal error has been signaled for this isolate.
|
||||
bool has_fatal_error_;
|
||||
|
||||
// True if we are using the Crankshaft optimizing compiler.
|
||||
bool use_crankshaft_;
|
||||
|
||||
// True if this isolate was initialized from a snapshot.
|
||||
bool initialized_from_snapshot_;
|
||||
|
||||
|
@ -450,7 +450,7 @@ Handle<Code> LChunk::Codegen() {
|
||||
CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
|
||||
|
||||
CodeGenerator::PrintCode(code, info());
|
||||
ASSERT(!(Serializer::enabled(info()->isolate()) &&
|
||||
ASSERT(!(info()->isolate()->serializer_enabled() &&
|
||||
info()->GetMustNotHaveEagerFrame() &&
|
||||
generator.NeedsEagerFrame()));
|
||||
return code;
|
||||
|
@ -296,106 +296,103 @@ int main(int argc, char** argv) {
|
||||
i::FLAG_logfile_per_isolate = false;
|
||||
|
||||
Isolate* isolate = v8::Isolate::New();
|
||||
isolate->Enter();
|
||||
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i::Serializer::RequestEnable(internal_isolate);
|
||||
Persistent<Context> context;
|
||||
{
|
||||
HandleScope handle_scope(isolate);
|
||||
context.Reset(isolate, Context::New(isolate));
|
||||
}
|
||||
{ Isolate::Scope isolate_scope(isolate);
|
||||
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
internal_isolate->enable_serializer();
|
||||
|
||||
if (context.IsEmpty()) {
|
||||
fprintf(stderr,
|
||||
"\nException thrown while compiling natives - see above.\n\n");
|
||||
exit(1);
|
||||
}
|
||||
if (i::FLAG_extra_code != NULL) {
|
||||
// Capture 100 frames if anything happens.
|
||||
V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
|
||||
HandleScope scope(isolate);
|
||||
v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
|
||||
const char* name = i::FLAG_extra_code;
|
||||
FILE* file = i::OS::FOpen(name, "rb");
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
|
||||
exit(1);
|
||||
Persistent<Context> context;
|
||||
{
|
||||
HandleScope handle_scope(isolate);
|
||||
context.Reset(isolate, Context::New(isolate));
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
char* chars = new char[size + 1];
|
||||
chars[size] = '\0';
|
||||
for (int i = 0; i < size;) {
|
||||
int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
|
||||
if (read < 0) {
|
||||
fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
|
||||
if (context.IsEmpty()) {
|
||||
fprintf(stderr,
|
||||
"\nException thrown while compiling natives - see above.\n\n");
|
||||
exit(1);
|
||||
}
|
||||
if (i::FLAG_extra_code != NULL) {
|
||||
// Capture 100 frames if anything happens.
|
||||
V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
|
||||
HandleScope scope(isolate);
|
||||
v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
|
||||
const char* name = i::FLAG_extra_code;
|
||||
FILE* file = i::OS::FOpen(name, "rb");
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
char* chars = new char[size + 1];
|
||||
chars[size] = '\0';
|
||||
for (int i = 0; i < size;) {
|
||||
int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
|
||||
if (read < 0) {
|
||||
fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
|
||||
exit(1);
|
||||
}
|
||||
i += read;
|
||||
}
|
||||
fclose(file);
|
||||
Local<String> source = String::NewFromUtf8(isolate, chars);
|
||||
TryCatch try_catch;
|
||||
Local<Script> script = Script::Compile(source);
|
||||
if (try_catch.HasCaught()) {
|
||||
fprintf(stderr, "Failure compiling '%s'\n", name);
|
||||
DumpException(try_catch.Message());
|
||||
exit(1);
|
||||
}
|
||||
script->Run();
|
||||
if (try_catch.HasCaught()) {
|
||||
fprintf(stderr, "Failure running '%s'\n", name);
|
||||
DumpException(try_catch.Message());
|
||||
exit(1);
|
||||
}
|
||||
i += read;
|
||||
}
|
||||
fclose(file);
|
||||
Local<String> source = String::NewFromUtf8(isolate, chars);
|
||||
TryCatch try_catch;
|
||||
Local<Script> script = Script::Compile(source);
|
||||
if (try_catch.HasCaught()) {
|
||||
fprintf(stderr, "Failure compiling '%s'\n", name);
|
||||
DumpException(try_catch.Message());
|
||||
exit(1);
|
||||
// Make sure all builtin scripts are cached.
|
||||
{ HandleScope scope(isolate);
|
||||
for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
|
||||
internal_isolate->bootstrapper()->NativesSourceLookup(i);
|
||||
}
|
||||
}
|
||||
script->Run();
|
||||
if (try_catch.HasCaught()) {
|
||||
fprintf(stderr, "Failure running '%s'\n", name);
|
||||
DumpException(try_catch.Message());
|
||||
exit(1);
|
||||
// If we don't do this then we end up with a stray root pointing at the
|
||||
// context even after we have disposed of the context.
|
||||
internal_isolate->heap()->CollectAllGarbage(
|
||||
i::Heap::kNoGCFlags, "mksnapshot");
|
||||
i::Object* raw_context = *v8::Utils::OpenPersistent(context);
|
||||
context.Reset();
|
||||
|
||||
// This results in a somewhat smaller snapshot, probably because it gets
|
||||
// rid of some things that are cached between garbage collections.
|
||||
i::List<char> snapshot_data;
|
||||
ListSnapshotSink snapshot_sink(&snapshot_data);
|
||||
i::StartupSerializer ser(internal_isolate, &snapshot_sink);
|
||||
ser.SerializeStrongReferences();
|
||||
|
||||
i::List<char> context_data;
|
||||
ListSnapshotSink contex_sink(&context_data);
|
||||
i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
|
||||
context_ser.Serialize(&raw_context);
|
||||
ser.SerializeWeakReferences();
|
||||
|
||||
{
|
||||
SnapshotWriter writer(argv[1]);
|
||||
writer.SetOmit(i::FLAG_omit);
|
||||
if (i::FLAG_raw_file && i::FLAG_raw_context_file)
|
||||
writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
|
||||
#ifdef COMPRESS_STARTUP_DATA_BZ2
|
||||
BZip2Compressor bzip2;
|
||||
writer.SetCompressor(&bzip2);
|
||||
#endif
|
||||
writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
|
||||
}
|
||||
}
|
||||
// Make sure all builtin scripts are cached.
|
||||
{ HandleScope scope(isolate);
|
||||
for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
|
||||
internal_isolate->bootstrapper()->NativesSourceLookup(i);
|
||||
}
|
||||
}
|
||||
// If we don't do this then we end up with a stray root pointing at the
|
||||
// context even after we have disposed of the context.
|
||||
internal_isolate->heap()->CollectAllGarbage(
|
||||
i::Heap::kNoGCFlags, "mksnapshot");
|
||||
i::Object* raw_context = *v8::Utils::OpenPersistent(context);
|
||||
context.Reset();
|
||||
|
||||
// This results in a somewhat smaller snapshot, probably because it gets rid
|
||||
// of some things that are cached between garbage collections.
|
||||
i::List<char> snapshot_data;
|
||||
ListSnapshotSink snapshot_sink(&snapshot_data);
|
||||
i::StartupSerializer ser(internal_isolate, &snapshot_sink);
|
||||
ser.SerializeStrongReferences();
|
||||
|
||||
i::List<char> context_data;
|
||||
ListSnapshotSink contex_sink(&context_data);
|
||||
i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
|
||||
context_ser.Serialize(&raw_context);
|
||||
ser.SerializeWeakReferences();
|
||||
|
||||
{
|
||||
SnapshotWriter writer(argv[1]);
|
||||
writer.SetOmit(i::FLAG_omit);
|
||||
if (i::FLAG_raw_file && i::FLAG_raw_context_file)
|
||||
writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
|
||||
#ifdef COMPRESS_STARTUP_DATA_BZ2
|
||||
BZip2Compressor bzip2;
|
||||
writer.SetCompressor(&bzip2);
|
||||
#endif
|
||||
writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
|
||||
}
|
||||
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
// TODO(svenpanne) Alas, we can't cleanly dispose V8 here, because
|
||||
// Serializer::code_address_map_ is static (a.k.a. a global variable), and
|
||||
// disposing that would involve accessing the Isolate just disposed.
|
||||
// code_address_map_ really has to be an instance variable...
|
||||
// V8::Dispose();
|
||||
V8::Dispose();
|
||||
return 0;
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(
|
||||
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() ||
|
||||
Serializer::enabled(heap->isolate()) ||
|
||||
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());
|
||||
@ -406,7 +406,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCode(
|
||||
Map* map, HeapObject* object) {
|
||||
Heap* heap = map->GetHeap();
|
||||
Code* code = Code::cast(object);
|
||||
if (FLAG_age_code && !Serializer::enabled(heap->isolate())) {
|
||||
if (FLAG_age_code && !heap->isolate()->serializer_enabled()) {
|
||||
code->MakeOlder(heap->mark_compact_collector()->marking_parity());
|
||||
}
|
||||
code->CodeIterateBody<StaticVisitor>(heap);
|
||||
|
@ -10737,7 +10737,7 @@ void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) {
|
||||
|
||||
// No tracking during the snapshot construction phase.
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (Serializer::enabled(isolate)) return;
|
||||
if (isolate->serializer_enabled()) return;
|
||||
|
||||
if (map->unused_property_fields() == 0) return;
|
||||
|
||||
|
@ -615,7 +615,6 @@ ExternalReferenceDecoder::~ExternalReferenceDecoder() {
|
||||
DeleteArray(encodings_);
|
||||
}
|
||||
|
||||
AtomicWord Serializer::serialization_state_ = SERIALIZER_STATE_UNINITIALIZED;
|
||||
|
||||
class CodeAddressMap: public CodeEventLogger {
|
||||
public:
|
||||
@ -728,48 +727,6 @@ class CodeAddressMap: public CodeEventLogger {
|
||||
};
|
||||
|
||||
|
||||
CodeAddressMap* Serializer::code_address_map_ = NULL;
|
||||
|
||||
|
||||
void Serializer::RequestEnable(Isolate* isolate) {
|
||||
isolate->InitializeLoggingAndCounters();
|
||||
code_address_map_ = new CodeAddressMap(isolate);
|
||||
}
|
||||
|
||||
|
||||
void Serializer::InitializeOncePerProcess() {
|
||||
// InitializeOncePerProcess is called by V8::InitializeOncePerProcess, a
|
||||
// method guaranteed to be called only once in a process lifetime.
|
||||
// serialization_state_ is read by many threads, hence the use of
|
||||
// Atomic primitives. Here, we don't need a barrier or mutex to
|
||||
// write it because V8 initialization is done by one thread, and gates
|
||||
// all reads of serialization_state_.
|
||||
ASSERT(NoBarrier_Load(&serialization_state_) ==
|
||||
SERIALIZER_STATE_UNINITIALIZED);
|
||||
SerializationState state = code_address_map_
|
||||
? SERIALIZER_STATE_ENABLED
|
||||
: SERIALIZER_STATE_DISABLED;
|
||||
NoBarrier_Store(&serialization_state_, state);
|
||||
}
|
||||
|
||||
|
||||
void Serializer::TearDown() {
|
||||
// TearDown is called by V8::TearDown() for the default isolate. It's safe
|
||||
// to shut down the serializer by that point. Just to be safe, we restore
|
||||
// serialization_state_ to uninitialized.
|
||||
ASSERT(NoBarrier_Load(&serialization_state_) !=
|
||||
SERIALIZER_STATE_UNINITIALIZED);
|
||||
if (code_address_map_) {
|
||||
ASSERT(NoBarrier_Load(&serialization_state_) ==
|
||||
SERIALIZER_STATE_ENABLED);
|
||||
delete code_address_map_;
|
||||
code_address_map_ = NULL;
|
||||
}
|
||||
|
||||
NoBarrier_Store(&serialization_state_, SERIALIZER_STATE_UNINITIALIZED);
|
||||
}
|
||||
|
||||
|
||||
Deserializer::Deserializer(SnapshotByteSource* source)
|
||||
: isolate_(NULL),
|
||||
source_(source),
|
||||
@ -1267,7 +1224,8 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
|
||||
: isolate_(isolate),
|
||||
sink_(sink),
|
||||
external_reference_encoder_(new ExternalReferenceEncoder(isolate)),
|
||||
root_index_wave_front_(0) {
|
||||
root_index_wave_front_(0),
|
||||
code_address_map_(NULL) {
|
||||
// The serializer is meant to be used only to generate initial heap images
|
||||
// from a context in which there is only one isolate.
|
||||
for (int i = 0; i <= LAST_SPACE; i++) {
|
||||
@ -1278,6 +1236,7 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
|
||||
|
||||
Serializer::~Serializer() {
|
||||
delete external_reference_encoder_;
|
||||
if (code_address_map_ != NULL) delete code_address_map_;
|
||||
}
|
||||
|
||||
|
||||
@ -1343,7 +1302,7 @@ void Serializer::VisitPointers(Object** start, Object** end) {
|
||||
// deserialized objects.
|
||||
void SerializerDeserializer::Iterate(Isolate* isolate,
|
||||
ObjectVisitor* visitor) {
|
||||
if (Serializer::enabled(isolate)) return;
|
||||
if (isolate->serializer_enabled()) return;
|
||||
for (int i = 0; ; i++) {
|
||||
if (isolate->serialize_partial_snapshot_cache_length() <= i) {
|
||||
// Extend the array ready to get a value from the visitor when
|
||||
@ -1583,12 +1542,14 @@ void Serializer::ObjectSerializer::Serialize() {
|
||||
"ObjectSerialization");
|
||||
sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
|
||||
|
||||
ASSERT(code_address_map_);
|
||||
const char* code_name = code_address_map_->Lookup(object_->address());
|
||||
LOG(serializer_->isolate_,
|
||||
CodeNameEvent(object_->address(), sink_->Position(), code_name));
|
||||
LOG(serializer_->isolate_,
|
||||
SnapshotPositionEvent(object_->address(), sink_->Position()));
|
||||
if (serializer_->code_address_map_) {
|
||||
const char* code_name =
|
||||
serializer_->code_address_map_->Lookup(object_->address());
|
||||
LOG(serializer_->isolate_,
|
||||
CodeNameEvent(object_->address(), sink_->Position(), code_name));
|
||||
LOG(serializer_->isolate_,
|
||||
SnapshotPositionEvent(object_->address(), sink_->Position()));
|
||||
}
|
||||
|
||||
// Mark this object as already serialized.
|
||||
int offset = serializer_->Allocate(space, size);
|
||||
@ -1868,6 +1829,12 @@ void Serializer::Pad() {
|
||||
}
|
||||
|
||||
|
||||
void Serializer::InitializeCodeAddressMap() {
|
||||
isolate_->InitializeLoggingAndCounters();
|
||||
code_address_map_ = new CodeAddressMap(isolate_);
|
||||
}
|
||||
|
||||
|
||||
bool SnapshotByteSource::AtEOF() {
|
||||
if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false;
|
||||
for (int x = position_; x < length_; x++) {
|
||||
|
@ -57,7 +57,7 @@ class ExternalReferenceTable {
|
||||
|
||||
private:
|
||||
explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
|
||||
PopulateTable(isolate);
|
||||
PopulateTable(isolate);
|
||||
}
|
||||
|
||||
struct ExternalReferenceEntry {
|
||||
@ -444,16 +444,7 @@ class Serializer : public SerializerDeserializer {
|
||||
}
|
||||
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
static void RequestEnable(Isolate* isolate);
|
||||
static void InitializeOncePerProcess();
|
||||
static void TearDown();
|
||||
|
||||
static bool enabled(Isolate* isolate) {
|
||||
SerializationState state = static_cast<SerializationState>(
|
||||
NoBarrier_Load(&serialization_state_));
|
||||
ASSERT(state != SERIALIZER_STATE_UNINITIALIZED);
|
||||
return state == SERIALIZER_STATE_ENABLED;
|
||||
}
|
||||
SerializationAddressMapper* address_mapper() { return &address_mapper_; }
|
||||
void PutRoot(int index,
|
||||
HeapObject* object,
|
||||
@ -552,14 +543,6 @@ class Serializer : public SerializerDeserializer {
|
||||
SnapshotByteSink* sink_;
|
||||
ExternalReferenceEncoder* external_reference_encoder_;
|
||||
|
||||
enum SerializationState {
|
||||
SERIALIZER_STATE_UNINITIALIZED = 0,
|
||||
SERIALIZER_STATE_DISABLED = 1,
|
||||
SERIALIZER_STATE_ENABLED = 2
|
||||
};
|
||||
|
||||
static AtomicWord serialization_state_;
|
||||
|
||||
SerializationAddressMapper address_mapper_;
|
||||
intptr_t root_index_wave_front_;
|
||||
void Pad();
|
||||
@ -567,8 +550,12 @@ class Serializer : public SerializerDeserializer {
|
||||
friend class ObjectSerializer;
|
||||
friend class Deserializer;
|
||||
|
||||
// We may not need the code address map for logging for every instance
|
||||
// of the serializer. Initialize it on demand.
|
||||
void InitializeCodeAddressMap();
|
||||
|
||||
private:
|
||||
static CodeAddressMap* code_address_map_;
|
||||
CodeAddressMap* code_address_map_;
|
||||
DISALLOW_COPY_AND_ASSIGN(Serializer);
|
||||
};
|
||||
|
||||
@ -581,6 +568,7 @@ class PartialSerializer : public Serializer {
|
||||
: Serializer(isolate, sink),
|
||||
startup_serializer_(startup_snapshot_serializer) {
|
||||
set_root_index_wave_front(Heap::kStrongRootListLength);
|
||||
InitializeCodeAddressMap();
|
||||
}
|
||||
|
||||
// Serialize the objects reachable from a single object pointer.
|
||||
@ -620,6 +608,7 @@ class StartupSerializer : public Serializer {
|
||||
// which will repopulate the cache with objects needed by that partial
|
||||
// snapshot.
|
||||
isolate->set_serialize_partial_snapshot_cache_length(0);
|
||||
InitializeCodeAddressMap();
|
||||
}
|
||||
// Serialize the current state of the heap. The order is:
|
||||
// 1) Strong references.
|
||||
|
@ -61,7 +61,6 @@ void V8::TearDown() {
|
||||
Isolate::GlobalTearDown();
|
||||
|
||||
Sampler::TearDown();
|
||||
Serializer::TearDown();
|
||||
|
||||
#ifdef V8_USE_DEFAULT_PLATFORM
|
||||
DefaultPlatform* platform = static_cast<DefaultPlatform*>(platform_);
|
||||
@ -79,7 +78,6 @@ void V8::SetReturnAddressLocationResolver(
|
||||
|
||||
void V8::InitializeOncePerProcessImpl() {
|
||||
FlagList::EnforceFlagImplications();
|
||||
Serializer::InitializeOncePerProcess();
|
||||
|
||||
if (FLAG_predictable && FLAG_random_seed == 0) {
|
||||
// Avoid random seeds in predictable mode.
|
||||
|
@ -262,7 +262,7 @@ static void Serialize() {
|
||||
// Test that the whole heap can be serialized.
|
||||
TEST(Serialize) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
Serializer::RequestEnable(CcTest::i_isolate());
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
Serialize();
|
||||
}
|
||||
@ -272,7 +272,7 @@ TEST(Serialize) {
|
||||
// Test that heap serialization is non-destructive.
|
||||
TEST(SerializeTwice) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
Serializer::RequestEnable(CcTest::i_isolate());
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
Serialize();
|
||||
Serialize();
|
||||
@ -370,7 +370,7 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
|
||||
TEST(PartialSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Serializer::RequestEnable(isolate);
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
Heap* heap = isolate->heap();
|
||||
@ -521,7 +521,7 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
|
||||
TEST(ContextSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Serializer::RequestEnable(isolate);
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
Heap* heap = isolate->heap();
|
||||
|
Loading…
Reference in New Issue
Block a user