From 525ed1130ea83c891074c7555fc88fe8b2d1b33e Mon Sep 17 00:00:00 2001 From: "jochen@chromium.org" Date: Thu, 18 Sep 2014 21:57:10 +0000 Subject: [PATCH] Revert "Require V8 to be explicitly initialized before an Isolate is created" LOG=n TBR=svenpanne@chromium.org BUG=none Review URL: https://codereview.chromium.org/582953002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24055 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 30 +- samples/lineprocessor.cc | 1 - samples/process.cc | 1 - samples/shell.cc | 1 - src/api.cc | 74 +++- src/base/utils/random-number-generator.cc | 1 - src/base/utils/random-number-generator.h | 3 - src/bootstrapper.cc | 3 + src/d8.cc | 1 - src/isolate.cc | 35 +- src/isolate.h | 14 +- src/mksnapshot.cc | 17 +- src/snapshot-common.cc | 4 +- src/snapshot-external.cc | 4 +- src/snapshot.h | 6 +- src/v8.cc | 11 +- src/v8.h | 8 +- test/cctest/cctest.cc | 6 +- test/cctest/cctest.h | 7 - test/cctest/test-api.cc | 22 +- test/cctest/test-ast.cc | 1 + test/cctest/test-dataflow.cc | 1 + test/cctest/test-debug.cc | 132 +++--- test/cctest/test-deoptimization.cc | 622 ++++++++++++---------------- test/cctest/test-heap.cc | 331 +++++++-------- test/cctest/test-liveedit.cc | 1 + test/cctest/test-log.cc | 275 ++++++------ test/cctest/test-macro-assembler-arm.cc | 2 + test/cctest/test-macro-assembler-ia32.cc | 2 + test/cctest/test-macro-assembler-x64.cc | 24 ++ test/cctest/test-macro-assembler-x87.cc | 2 + test/cctest/test-random-number-generator.cc | 20 +- test/cctest/test-regexp.cc | 18 + test/cctest/test-serialize.cc | 567 ++++++++++++------------- test/cctest/test-spaces.cc | 10 + test/mjsunit/mjsunit.status | 2 - tools/lexer-shell.cc | 3 +- tools/parser-shell.cc | 3 +- 38 files changed, 1127 insertions(+), 1138 deletions(-) diff --git a/include/v8.h b/include/v8.h index 26d8710..e4c7087 100644 --- a/include/v8.h +++ b/include/v8.h @@ -4344,12 +4344,13 @@ typedef void (*JitCodeEventHandler)(const JitCodeEvent* event); /** - * Isolate represents an isolated instance of the V8 engine. V8 isolates have - * completely separate states. Objects from one isolate must not be used in - * other isolates. The embedder can create multiple isolates and use them in - * parallel in multiple threads. An isolate can be entered by at most one - * thread at any given time. The Locker/Unlocker API must be used to - * synchronize. + * Isolate represents an isolated instance of the V8 engine. V8 + * isolates have completely separate states. Objects from one isolate + * must not be used in other isolates. When V8 is initialized a + * default isolate is implicitly created and entered. The embedder + * can create additional isolates and use them in parallel in multiple + * threads. An isolate can be entered by at most one thread at any + * given time. The Locker/Unlocker API must be used to synchronize. */ class V8_EXPORT Isolate { public: @@ -4357,10 +4358,7 @@ class V8_EXPORT Isolate { * Initial configuration parameters for a new Isolate. */ struct CreateParams { - CreateParams() - : entry_hook(NULL), - code_event_handler(NULL), - enable_serializer(false) {} + CreateParams() : entry_hook(NULL), code_event_handler(NULL) {} /** * The optional entry_hook allows the host application to provide the @@ -4381,11 +4379,6 @@ class V8_EXPORT Isolate { * ResourceConstraints to use for the new Isolate. */ ResourceConstraints constraints; - - /** - * This flag currently renders the Isolate unusable. - */ - bool enable_serializer; }; @@ -4496,8 +4489,6 @@ class V8_EXPORT Isolate { * * When an isolate is no longer used its resources should be freed * by calling Dispose(). Using the delete operator is not allowed. - * - * V8::Initialize() must have run prior to this. */ static Isolate* New(const CreateParams& params = CreateParams()); @@ -5111,8 +5102,9 @@ class V8_EXPORT V8 { static void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback); /** - * Initializes V8. This function needs to be called before the first Isolate - * is created. It always returns true. + * Initializes from snapshot if possible. Otherwise, attempts to + * initialize from scratch. This function is called implicitly if + * you use the API without calling it first. */ static bool Initialize(); diff --git a/samples/lineprocessor.cc b/samples/lineprocessor.cc index 69bfab4..9b627f3 100644 --- a/samples/lineprocessor.cc +++ b/samples/lineprocessor.cc @@ -257,7 +257,6 @@ int main(int argc, char* argv[]) { v8::V8::InitializeICU(); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); int result = RunMain(argc, argv); v8::V8::Dispose(); v8::V8::ShutdownPlatform(); diff --git a/samples/process.cc b/samples/process.cc index e5c9b7a..4db7eeb 100644 --- a/samples/process.cc +++ b/samples/process.cc @@ -648,7 +648,6 @@ int main(int argc, char* argv[]) { v8::V8::InitializeICU(); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); map options; string file; ParseOptions(argc, argv, &options, &file); diff --git a/samples/shell.cc b/samples/shell.cc index b66e8f7..ef61426 100644 --- a/samples/shell.cc +++ b/samples/shell.cc @@ -83,7 +83,6 @@ int main(int argc, char* argv[]) { v8::V8::InitializeICU(); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); v8::V8::SetFlagsFromCommandLine(&argc, argv, true); ShellArrayBufferAllocator array_buffer_allocator; v8::V8::SetArrayBufferAllocator(&array_buffer_allocator); diff --git a/src/api.cc b/src/api.cc index 107c7e8..3c042d7 100644 --- a/src/api.cc +++ b/src/api.cc @@ -202,6 +202,29 @@ static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) { } +// --- S t a t i c s --- + + +static bool InitializeHelper(i::Isolate* isolate) { + // If the isolate has a function entry hook, it needs to re-build all its + // code stubs with entry hooks embedded, so let's deserialize a snapshot. + if (isolate == NULL || isolate->function_entry_hook() == NULL) { + if (i::Snapshot::Initialize()) + return true; + } + return i::V8::Initialize(NULL); +} + + +static inline bool EnsureInitializedForIsolate(i::Isolate* isolate, + const char* location) { + return (isolate != NULL && isolate->IsInitialized()) || + Utils::ApiCheck(InitializeHelper(isolate), + location, + "Error initializing V8"); +} + + StartupDataDecompressor::StartupDataDecompressor() : raw_data(i::NewArray(V8::GetCompressedStartupDataCount())) { for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) { @@ -723,6 +746,7 @@ void Context::SetAlignedPointerInEmbedderData(int index, void* value) { // NeanderObject constructor. When you add one to the site calling the // constructor you should check that you ensured the VM was not dead first. NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) { + EnsureInitializedForIsolate(isolate, "v8::Nowhere"); ENTER_V8(isolate); value_ = isolate->factory()->NewNeanderObject(); i::Handle elements = isolate->factory()->NewFixedArray(size); @@ -915,6 +939,7 @@ Local FunctionTemplate::New( v8::Handle signature, int length) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::FunctionTemplate::New()"); LOG_API(i_isolate, "FunctionTemplate::New"); ENTER_V8(i_isolate); return FunctionTemplateNew( @@ -926,6 +951,7 @@ Local Signature::New(Isolate* isolate, Handle receiver, int argc, Handle argv[]) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::Signature::New()"); LOG_API(i_isolate, "Signature::New"); ENTER_V8(i_isolate); i::Handle struct_obj = @@ -1076,6 +1102,7 @@ Local TypeSwitch::New(Handle type) { Local TypeSwitch::New(int argc, Handle types[]) { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()"); LOG_API(isolate, "TypeSwitch::New"); ENTER_V8(isolate); i::Handle vector = isolate->factory()->NewFixedArray(argc); @@ -1256,6 +1283,7 @@ Local ObjectTemplate::New() { Local ObjectTemplate::New( i::Isolate* isolate, v8::Handle constructor) { + EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()"); LOG_API(isolate, "ObjectTemplate::New"); ENTER_V8(isolate); i::Handle struct_obj = @@ -2372,6 +2400,7 @@ bool StackFrame::IsConstructor() const { Local JSON::Parse(Local json_string) { i::Handle string = Utils::OpenHandle(*json_string); i::Isolate* isolate = string->GetIsolate(); + EnsureInitializedForIsolate(isolate, "v8::JSON::Parse"); ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle source = i::String::Flatten(string); @@ -4862,6 +4891,7 @@ int String::Write(uint16_t* buffer, bool v8::String::IsExternal() const { i::Handle str = Utils::OpenHandle(this); + EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()"); return i::StringShape(*str).IsExternalTwoByte(); } @@ -5050,8 +5080,11 @@ void v8::V8::ShutdownPlatform() { bool v8::V8::Initialize() { - i::V8::Initialize(); - return true; + i::Isolate* isolate = i::Isolate::UncheckedCurrent(); + if (isolate != NULL && isolate->IsInitialized()) { + return true; + } + return InitializeHelper(isolate); } @@ -5246,6 +5279,7 @@ Local v8::Context::New( v8::Handle global_template, v8::Handle global_object) { i::Isolate* isolate = reinterpret_cast(external_isolate); + EnsureInitializedForIsolate(isolate, "v8::Context::New()"); LOG_API(isolate, "Context::New"); ON_BAILOUT(isolate, "v8::Context::New()", return Local()); i::HandleScope scope(isolate); @@ -5376,6 +5410,7 @@ bool FunctionTemplate::HasInstance(v8::Handle value) { Local v8::External::New(Isolate* isolate, void* value) { STATIC_ASSERT(sizeof(value) == sizeof(i::Address)); i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::External::New()"); LOG_API(i_isolate, "External::New"); ENTER_V8(i_isolate); i::Handle external = i_isolate->factory()->NewExternal(value); @@ -5450,6 +5485,7 @@ inline Local NewString(Isolate* v8_isolate, String::NewStringType type, int length) { i::Isolate* isolate = reinterpret_cast(v8_isolate); + EnsureInitializedForIsolate(isolate, location); LOG_API(isolate, env); if (length == 0 && type != String::kUndetectableString) { return String::Empty(v8_isolate); @@ -5512,6 +5548,7 @@ Local String::NewFromTwoByte(Isolate* isolate, Local v8::String::Concat(Handle left, Handle right) { i::Handle left_string = Utils::OpenHandle(*left); i::Isolate* isolate = left_string->GetIsolate(); + EnsureInitializedForIsolate(isolate, "v8::String::New()"); LOG_API(isolate, "String::New(char)"); ENTER_V8(isolate); i::Handle right_string = Utils::OpenHandle(*right); @@ -5544,6 +5581,7 @@ Local v8::String::NewExternal( Isolate* isolate, v8::String::ExternalStringResource* resource) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); LOG_API(i_isolate, "String::NewExternal"); ENTER_V8(i_isolate); CHECK(resource && resource->data()); @@ -5582,6 +5620,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { Local v8::String::NewExternal( Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); LOG_API(i_isolate, "String::NewExternal"); ENTER_V8(i_isolate); CHECK(resource && resource->data()); @@ -5634,6 +5673,7 @@ bool v8::String::CanMakeExternal() { Local v8::Object::New(Isolate* isolate) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::Object::New()"); LOG_API(i_isolate, "Object::New"); ENTER_V8(i_isolate); i::Handle obj = @@ -5644,6 +5684,7 @@ Local v8::Object::New(Isolate* isolate) { Local v8::NumberObject::New(Isolate* isolate, double value) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::NumberObject::New()"); LOG_API(i_isolate, "NumberObject::New"); ENTER_V8(i_isolate); i::Handle number = i_isolate->factory()->NewNumber(value); @@ -5664,6 +5705,7 @@ double v8::NumberObject::ValueOf() const { Local v8::BooleanObject::New(bool value) { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()"); LOG_API(isolate, "BooleanObject::New"); ENTER_V8(isolate); i::Handle boolean(value @@ -5688,6 +5730,7 @@ bool v8::BooleanObject::ValueOf() const { Local v8::StringObject::New(Handle value) { i::Handle string = Utils::OpenHandle(*value); i::Isolate* isolate = string->GetIsolate(); + EnsureInitializedForIsolate(isolate, "v8::StringObject::New()"); LOG_API(isolate, "StringObject::New"); ENTER_V8(isolate); i::Handle obj = @@ -5708,6 +5751,7 @@ Local v8::StringObject::ValueOf() const { Local v8::SymbolObject::New(Isolate* isolate, Handle value) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::SymbolObject::New()"); LOG_API(i_isolate, "SymbolObject::New"); ENTER_V8(i_isolate); i::Handle obj = i::Object::ToObject( @@ -5728,6 +5772,7 @@ Local v8::SymbolObject::ValueOf() const { Local v8::Date::New(Isolate* isolate, double time) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::Date::New()"); LOG_API(i_isolate, "Date::New"); if (std::isnan(time)) { // Introduce only canonical NaN value into the VM, to avoid signaling NaNs. @@ -5793,6 +5838,7 @@ static i::Handle RegExpFlagsToString(RegExp::Flags flags) { Local v8::RegExp::New(Handle pattern, Flags flags) { i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate(); + EnsureInitializedForIsolate(isolate, "v8::RegExp::New()"); LOG_API(isolate, "RegExp::New"); ENTER_V8(isolate); EXCEPTION_PREAMBLE(isolate); @@ -5829,6 +5875,7 @@ v8::RegExp::Flags v8::RegExp::GetFlags() const { Local v8::Array::New(Isolate* isolate, int length) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::Array::New()"); LOG_API(i_isolate, "Array::New"); ENTER_V8(i_isolate); int real_length = length > 0 ? length : 0; @@ -6048,6 +6095,7 @@ size_t v8::ArrayBuffer::ByteLength() const { Local v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(size_t)"); LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)"); ENTER_V8(i_isolate); i::Handle obj = @@ -6060,6 +6108,7 @@ Local v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) { Local v8::ArrayBuffer::New(Isolate* isolate, void* data, size_t byte_length) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(void*, size_t)"); LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)"); ENTER_V8(i_isolate); i::Handle obj = @@ -6162,6 +6211,8 @@ i::Handle NewTypedArray( Local Type##Array::New(Handle array_buffer, \ size_t byte_offset, size_t length) { \ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \ + EnsureInitializedForIsolate(isolate, \ + "v8::" #Type "Array::New(Handle, size_t, size_t)"); \ LOG_API(isolate, \ "v8::" #Type "Array::New(Handle, size_t, size_t)"); \ ENTER_V8(isolate); \ @@ -6185,6 +6236,8 @@ Local DataView::New(Handle array_buffer, size_t byte_offset, size_t byte_length) { i::Handle buffer = Utils::OpenHandle(*array_buffer); i::Isolate* isolate = buffer->GetIsolate(); + EnsureInitializedForIsolate( + isolate, "v8::DataView::New(void*, size_t, size_t)"); LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)"); ENTER_V8(isolate); i::Handle obj = isolate->factory()->NewJSDataView(); @@ -6196,6 +6249,7 @@ Local DataView::New(Handle array_buffer, Local v8::Symbol::New(Isolate* isolate, Local name) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()"); LOG_API(i_isolate, "Symbol::New()"); ENTER_V8(i_isolate); i::Handle result = i_isolate->factory()->NewSymbol(); @@ -6260,6 +6314,7 @@ Local v8::Symbol::GetUnscopables(Isolate* isolate) { Local v8::Private::New(Isolate* isolate, Local name) { i::Isolate* i_isolate = reinterpret_cast(isolate); + EnsureInitializedForIsolate(i_isolate, "v8::Private::New()"); LOG_API(i_isolate, "Private::New()"); ENTER_V8(i_isolate); i::Handle symbol = i_isolate->factory()->NewPrivateSymbol(); @@ -6331,6 +6386,7 @@ Local v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) { bool V8::AddMessageListener(MessageCallback that, Handle data) { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()"); ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false); ENTER_V8(isolate); i::HandleScope scope(isolate); @@ -6346,6 +6402,7 @@ bool V8::AddMessageListener(MessageCallback that, Handle data) { void V8::RemoveMessageListeners(MessageCallback that) { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()"); ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return); ENTER_V8(isolate); i::HandleScope scope(isolate); @@ -6618,16 +6675,6 @@ Isolate* Isolate::New(const Isolate::CreateParams& params) { } SetResourceConstraints(v8_isolate, const_cast(¶ms.constraints)); - if (params.enable_serializer) { - isolate->enable_serializer(); - } - // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this. - Isolate::Scope isolate_scope(v8_isolate); - if (params.entry_hook || !i::Snapshot::Initialize(isolate)) { - // If the isolate has a function entry hook, it needs to re-build all its - // code stubs with entry hooks embedded, so don't deserialize a snapshot. - isolate->Init(NULL); - } return v8_isolate; } @@ -6930,6 +6977,7 @@ DEFINE_ERROR(Error) bool Debug::SetDebugEventListener(EventCallback that, Handle data) { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()"); ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false); ENTER_V8(isolate); i::HandleScope scope(isolate); @@ -6968,6 +7016,7 @@ void Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) { void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler"); ENTER_V8(isolate); isolate->debug()->SetMessageHandler(handler); } @@ -7041,6 +7090,7 @@ void Debug::ProcessDebugMessages() { Local Debug::GetDebugContext() { i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()"); ENTER_V8(isolate); return Utils::ToLocal(i::Isolate::Current()->debug()->GetDebugContext()); } diff --git a/src/base/utils/random-number-generator.cc b/src/base/utils/random-number-generator.cc index 9454936..be79811 100644 --- a/src/base/utils/random-number-generator.cc +++ b/src/base/utils/random-number-generator.cc @@ -125,7 +125,6 @@ int RandomNumberGenerator::Next(int bits) { void RandomNumberGenerator::SetSeed(int64_t seed) { - initial_seed_ = seed; seed_ = (seed ^ kMultiplier) & kMask; } diff --git a/src/base/utils/random-number-generator.h b/src/base/utils/random-number-generator.h index 479423d..a9107a6 100644 --- a/src/base/utils/random-number-generator.h +++ b/src/base/utils/random-number-generator.h @@ -74,8 +74,6 @@ class RandomNumberGenerator FINAL { // Override the current ssed. void SetSeed(int64_t seed); - int64_t initial_seed() const { return initial_seed_; } - private: static const int64_t kMultiplier = V8_2PART_UINT64_C(0x5, deece66d); static const int64_t kAddend = 0xb; @@ -83,7 +81,6 @@ class RandomNumberGenerator FINAL { int Next(int bits) WARN_UNUSED_RESULT; - int64_t initial_seed_; int64_t seed_; }; diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index e6f8a13..855080c 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -2594,6 +2594,9 @@ Genesis::Genesis(Isolate* isolate, active_(isolate->bootstrapper()) { NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); result_ = Handle::null(); + // If V8 cannot be initialized, just return. + if (!V8::Initialize(NULL)) return; + // Before creating the roots we must save the context and restore it // on all function exits. SaveContext saved_context(isolate); diff --git a/src/d8.cc b/src/d8.cc index 9db7744..c1d66b4 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -1619,7 +1619,6 @@ int Shell::Main(int argc, char* argv[]) { v8::V8::InitializeICU(options.icu_data_file); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); #ifdef V8_USE_EXTERNAL_STARTUP_DATA StartupDataHandler startup_data(options.natives_blob, options.snapshot_blob); #endif diff --git a/src/isolate.cc b/src/isolate.cc index e960445..66733cb 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -48,6 +48,7 @@ int ThreadId::AllocateThreadId() { int ThreadId::GetCurrentThreadId() { + Isolate::EnsureInitialized(); int thread_id = base::Thread::GetThreadLocalInt(Isolate::thread_id_key_); if (thread_id == 0) { thread_id = AllocateThreadId(); @@ -113,16 +114,17 @@ base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; #ifdef DEBUG base::Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key; #endif // DEBUG -base::LazyMutex Isolate::thread_data_table_mutex_ = LAZY_MUTEX_INITIALIZER; +base::LazyMutex Isolate::process_wide_mutex_ = LAZY_MUTEX_INITIALIZER; Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; base::Atomic32 Isolate::isolate_counter_ = 0; Isolate::PerIsolateThreadData* Isolate::FindOrAllocatePerThreadDataForThisThread() { + EnsureInitialized(); ThreadId thread_id = ThreadId::Current(); PerIsolateThreadData* per_thread = NULL; { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); per_thread = thread_data_table_->Lookup(this, thread_id); if (per_thread == NULL) { per_thread = new PerIsolateThreadData(this, thread_id); @@ -142,26 +144,28 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread( ThreadId thread_id) { + EnsureInitialized(); PerIsolateThreadData* per_thread = NULL; { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); per_thread = thread_data_table_->Lookup(this, thread_id); } return per_thread; } -void Isolate::InitializeOncePerProcess() { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - CHECK(thread_data_table_ == NULL); - isolate_key_ = base::Thread::CreateThreadLocalKey(); - thread_id_key_ = base::Thread::CreateThreadLocalKey(); - per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey(); +void Isolate::EnsureInitialized() { + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); + if (thread_data_table_ == NULL) { + isolate_key_ = base::Thread::CreateThreadLocalKey(); + thread_id_key_ = base::Thread::CreateThreadLocalKey(); + per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey(); #ifdef DEBUG - PerThreadAssertScopeBase::thread_local_key = - base::Thread::CreateThreadLocalKey(); + PerThreadAssertScopeBase::thread_local_key = + base::Thread::CreateThreadLocalKey(); #endif // DEBUG - thread_data_table_ = new Isolate::ThreadDataTable(); + thread_data_table_ = new Isolate::ThreadDataTable(); + } } @@ -1517,10 +1521,6 @@ Isolate::Isolate() stress_deopt_count_(0), next_optimization_id_(0), use_counter_callback_(NULL) { - { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - CHECK(thread_data_table_); - } id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1); TRACE_ISOLATE(constructor); @@ -1571,7 +1571,7 @@ void Isolate::TearDown() { Deinit(); { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); thread_data_table_->RemoveAllThreads(this); } @@ -1676,6 +1676,7 @@ void Isolate::PushToPartialSnapshotCache(Object* obj) { void Isolate::SetIsolateThreadLocals(Isolate* isolate, PerIsolateThreadData* data) { + EnsureInitialized(); base::Thread::SetThreadLocal(isolate_key_, isolate); base::Thread::SetThreadLocal(per_isolate_thread_data_key_, data); } diff --git a/src/isolate.h b/src/isolate.h index 24d4b08..28a45da 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -466,17 +466,17 @@ class Isolate { kIsolateAddressCount }; - static void InitializeOncePerProcess(); - // Returns the PerIsolateThreadData for the current thread (or NULL if one is // not currently set). static PerIsolateThreadData* CurrentPerIsolateThreadData() { + EnsureInitialized(); return reinterpret_cast( base::Thread::GetThreadLocal(per_isolate_thread_data_key_)); } // Returns the isolate inside which the current thread is running. INLINE(static Isolate* Current()) { + EnsureInitialized(); Isolate* isolate = reinterpret_cast( base::Thread::GetExistingThreadLocal(isolate_key_)); DCHECK(isolate != NULL); @@ -484,6 +484,7 @@ class Isolate { } INLINE(static Isolate* UncheckedCurrent()) { + EnsureInitialized(); return reinterpret_cast( base::Thread::GetThreadLocal(isolate_key_)); } @@ -528,11 +529,13 @@ class Isolate { // Used internally for V8 threads that do not execute JavaScript but still // are part of the domain of an isolate (like the context switcher). static base::Thread::LocalStorageKey isolate_key() { + EnsureInitialized(); return isolate_key_; } // Returns the key used to store process-wide thread IDs. static base::Thread::LocalStorageKey thread_id_key() { + EnsureInitialized(); return thread_id_key_; } @@ -1107,9 +1110,9 @@ class Isolate { void SetUseCounterCallback(v8::Isolate::UseCounterCallback callback); void CountUsage(v8::Isolate::UseCounterFeature feature); - static Isolate* NewForTesting() { return new Isolate(); } - private: + static void EnsureInitialized(); + Isolate(); friend struct GlobalState; @@ -1168,7 +1171,8 @@ class Isolate { DISALLOW_COPY_AND_ASSIGN(EntryStackItem); }; - static base::LazyMutex thread_data_table_mutex_; + // This mutex protects highest_thread_id_ and thread_data_table_. + static base::LazyMutex process_wide_mutex_; static base::Thread::LocalStorageKey per_isolate_thread_data_key_; static base::Thread::LocalStorageKey isolate_key_; diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc index 4794d44..71a78a9 100644 --- a/src/mksnapshot.cc +++ b/src/mksnapshot.cc @@ -303,6 +303,11 @@ void DumpException(Handle message) { int main(int argc, char** argv) { + V8::InitializeICU(); + v8::Platform* platform = v8::platform::CreateDefaultPlatform(); + v8::V8::InitializePlatform(platform); + i::CpuFeatures::Probe(true); + // By default, log code create information in the snapshot. i::FLAG_log_code = true; @@ -314,13 +319,6 @@ int main(int argc, char** argv) { i::FlagList::PrintHelp(); return !i::FLAG_help; } - - V8::InitializeICU(); - v8::Platform* platform = v8::platform::CreateDefaultPlatform(); - v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); - i::CpuFeatures::Probe(true); - #ifdef COMPRESS_STARTUP_DATA_BZ2 BZip2Decompressor natives_decompressor; int bz2_result = natives_decompressor.Decompress(); @@ -331,11 +329,10 @@ int main(int argc, char** argv) { #endif i::FLAG_logfile_per_isolate = false; - Isolate::CreateParams params; - params.enable_serializer = true; - Isolate* isolate = v8::Isolate::New(params); + Isolate* isolate = v8::Isolate::New(); { Isolate::Scope isolate_scope(isolate); i::Isolate* internal_isolate = reinterpret_cast(isolate); + internal_isolate->enable_serializer(); Persistent context; { diff --git a/src/snapshot-common.cc b/src/snapshot-common.cc index a2d5213..25193b2 100644 --- a/src/snapshot-common.cc +++ b/src/snapshot-common.cc @@ -26,7 +26,7 @@ void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) { } -bool Snapshot::Initialize(Isolate* isolate) { +bool Snapshot::Initialize() { if (size_ > 0) { base::ElapsedTimer timer; if (FLAG_profile_deserialization) { @@ -35,7 +35,7 @@ bool Snapshot::Initialize(Isolate* isolate) { SnapshotByteSource source(raw_data_, raw_size_); Deserializer deserializer(&source); ReserveSpaceForLinkedInSnapshot(&deserializer); - bool success = isolate->Init(&deserializer); + bool success = V8::Initialize(&deserializer); if (FLAG_profile_deserialization) { double ms = timer.Elapsed().InMillisecondsF(); PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms); diff --git a/src/snapshot-external.cc b/src/snapshot-external.cc index ee1a8f4..38b7cf4 100644 --- a/src/snapshot-external.cc +++ b/src/snapshot-external.cc @@ -46,7 +46,7 @@ bool Snapshot::HaveASnapshotToStartFrom() { } -bool Snapshot::Initialize(Isolate* isolate) { +bool Snapshot::Initialize() { if (!HaveASnapshotToStartFrom()) return false; @@ -66,7 +66,7 @@ bool Snapshot::Initialize(Isolate* isolate) { deserializer.set_reservation(CELL_SPACE, snapshot_impl_->cell_space_used); deserializer.set_reservation(PROPERTY_CELL_SPACE, snapshot_impl_->property_cell_space_used); - bool success = isolate->Init(&deserializer); + bool success = V8::Initialize(&deserializer); if (FLAG_profile_deserialization) { double ms = timer.Elapsed().InMillisecondsF(); PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms); diff --git a/src/snapshot.h b/src/snapshot.h index 3d752a7..b785cf5 100644 --- a/src/snapshot.h +++ b/src/snapshot.h @@ -12,9 +12,9 @@ namespace internal { class Snapshot { public: - // Initialize the Isolate from the internal snapshot. Returns false if no - // snapshot could be found. - static bool Initialize(Isolate* isolate); + // Initialize the VM from the internal snapshot. Returns false if no snapshot + // could be found. + static bool Initialize(); static bool HaveASnapshotToStartFrom(); diff --git a/src/v8.cc b/src/v8.cc index 62c3da4..d4f59a1 100644 --- a/src/v8.cc +++ b/src/v8.cc @@ -33,9 +33,14 @@ v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL; v8::Platform* V8::platform_ = NULL; -bool V8::Initialize() { +bool V8::Initialize(Deserializer* des) { InitializeOncePerProcess(); - return true; + Isolate* isolate = Isolate::UncheckedCurrent(); + if (isolate == NULL) return true; + if (isolate->IsDead()) return false; + if (isolate->IsInitialized()) return true; + + return isolate->Init(des); } @@ -74,8 +79,6 @@ void V8::InitializeOncePerProcessImpl() { base::OS::Initialize(FLAG_random_seed, FLAG_hard_abort, FLAG_gc_fake_mmap); - Isolate::InitializeOncePerProcess(); - Sampler::SetUp(); CpuFeatures::Probe(false); init_memcopy_functions(); diff --git a/src/v8.h b/src/v8.h index 13c33e1..8ae75fb 100644 --- a/src/v8.h +++ b/src/v8.h @@ -49,11 +49,17 @@ namespace v8 { namespace internal { +class Deserializer; + class V8 : public AllStatic { public: // Global actions. - static bool Initialize(); + // If Initialize is called with des == NULL, the initial state is + // created from scratch. If a non-null Deserializer is given, the + // initial state is created by reading the deserialized data into an + // empty heap. + static bool Initialize(Deserializer* des); static void TearDown(); // Report process out of memory. Implementation found in api.cc. diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc index f03710a..3eb189f 100644 --- a/test/cctest/cctest.cc +++ b/test/cctest/cctest.cc @@ -164,8 +164,8 @@ int main(int argc, char* argv[]) { v8::V8::InitializeICU(); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); + v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true); - v8::V8::Initialize(); CcTestArrayBufferAllocator array_buffer_allocator; v8::V8::SetArrayBufferAllocator(&array_buffer_allocator); @@ -182,6 +182,10 @@ int main(int argc, char* argv[]) { for (int i = 1; i < argc; i++) { char* arg = argv[i]; if (strcmp(arg, "--list") == 0) { + // TODO(svenpanne) Serializer::enabled() and Serializer::code_address_map_ + // are fundamentally broken, so we can't unconditionally initialize and + // dispose V8. + v8::V8::Initialize(); PrintTestList(CcTest::last()); print_run_count = false; diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h index 6d27074..2ab973c 100644 --- a/test/cctest/cctest.h +++ b/test/cctest/cctest.h @@ -53,13 +53,6 @@ static void Test##Name() #endif -#ifndef UNINITIALIZED_DEPENDENT_TEST -#define UNINITIALIZED_DEPENDENT_TEST(Name, Dep) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true, false); \ - static void Test##Name() -#endif - #ifndef DISABLED_TEST #define DISABLED_TEST(Name) \ static void Test##Name(); \ diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 51ad973..d065ada 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -19486,26 +19486,31 @@ static int CalcFibonacci(v8::Isolate* isolate, int limit) { class IsolateThread : public v8::base::Thread { public: - explicit IsolateThread(int fib_limit) - : Thread(Options("IsolateThread")), fib_limit_(fib_limit), result_(0) {} + IsolateThread(v8::Isolate* isolate, int fib_limit) + : Thread(Options("IsolateThread")), + isolate_(isolate), + fib_limit_(fib_limit), + result_(0) {} void Run() { - v8::Isolate* isolate = v8::Isolate::New(); - result_ = CalcFibonacci(isolate, fib_limit_); - isolate->Dispose(); + result_ = CalcFibonacci(isolate_, fib_limit_); } int result() { return result_; } private: + v8::Isolate* isolate_; int fib_limit_; int result_; }; TEST(MultipleIsolatesOnIndividualThreads) { - IsolateThread thread1(21); - IsolateThread thread2(12); + v8::Isolate* isolate1 = v8::Isolate::New(); + v8::Isolate* isolate2 = v8::Isolate::New(); + + IsolateThread thread1(isolate1, 21); + IsolateThread thread2(isolate2, 12); // Compute some fibonacci numbers on 3 threads in 3 isolates. thread1.Start(); @@ -19523,6 +19528,9 @@ TEST(MultipleIsolatesOnIndividualThreads) { CHECK_EQ(result2, 144); CHECK_EQ(result1, thread1.result()); CHECK_EQ(result2, thread2.result()); + + isolate1->Dispose(); + isolate2->Dispose(); } diff --git a/test/cctest/test-ast.cc b/test/cctest/test-ast.cc index 24819df..da090c6 100644 --- a/test/cctest/test-ast.cc +++ b/test/cctest/test-ast.cc @@ -35,6 +35,7 @@ using namespace v8::internal; TEST(List) { + v8::internal::V8::Initialize(NULL); List* list = new List(0); CHECK_EQ(0, list->length()); diff --git a/test/cctest/test-dataflow.cc b/test/cctest/test-dataflow.cc index 43d950d..fc1a7fa 100644 --- a/test/cctest/test-dataflow.cc +++ b/test/cctest/test-dataflow.cc @@ -35,6 +35,7 @@ using namespace v8::internal; TEST(BitVector) { + v8::internal::V8::Initialize(NULL); Zone zone(CcTest::i_isolate()); { BitVector v(15, &zone); diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index 69c10c2..0adcc0a 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -73,23 +73,16 @@ using ::v8::internal::StrLength; class DebugLocalContext { public: inline DebugLocalContext( - v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0, - v8::Handle global_template = - v8::Handle(), - v8::Handle global_object = v8::Handle()) - : scope_(isolate), - context_(v8::Context::New(isolate, extensions, global_template, - global_object)) { - context_->Enter(); - } - inline DebugLocalContext( v8::ExtensionConfiguration* extensions = 0, v8::Handle global_template = v8::Handle(), v8::Handle global_object = v8::Handle()) : scope_(CcTest::isolate()), - context_(v8::Context::New(CcTest::isolate(), extensions, - global_template, global_object)) { + context_( + v8::Context::New(CcTest::isolate(), + extensions, + global_template, + global_object)) { context_->Enter(); } inline ~DebugLocalContext() { @@ -144,7 +137,8 @@ static v8::Local CompileFunction(v8::Isolate* isolate, const char* source, const char* function_name) { v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); - v8::Local global = isolate->GetCurrentContext()->Global(); + v8::Local global = + CcTest::isolate()->GetCurrentContext()->Global(); return v8::Local::Cast( global->Get(v8::String::NewFromUtf8(isolate, function_name))); } @@ -5161,20 +5155,12 @@ class V8Thread : public v8::base::Thread { public: V8Thread() : Thread(Options("V8Thread")) {} void Run(); - v8::Isolate* isolate() { return isolate_; } - - private: - v8::Isolate* isolate_; }; class DebuggerThread : public v8::base::Thread { public: - explicit DebuggerThread(v8::Isolate* isolate) - : Thread(Options("DebuggerThread")), isolate_(isolate) {} + DebuggerThread() : Thread(Options("DebuggerThread")) {} void Run(); - - private: - v8::Isolate* isolate_; }; @@ -5217,25 +5203,22 @@ void V8Thread::Run() { "\n" "foo();\n"; - isolate_ = v8::Isolate::New(); - threaded_debugging_barriers.barrier_3.Wait(); - { - v8::Isolate::Scope isolate_scope(isolate_); - DebugLocalContext env(isolate_); - v8::HandleScope scope(isolate_); - v8::Debug::SetMessageHandler(&ThreadedMessageHandler); - v8::Handle global_template = - v8::ObjectTemplate::New(env->GetIsolate()); - global_template->Set( - v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), - v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1)); - v8::Handle context = - v8::Context::New(isolate_, NULL, global_template); - v8::Context::Scope context_scope(context); - - CompileRun(source); - } - isolate_->Dispose(); + v8::Isolate* isolate = CcTest::isolate(); + v8::Isolate::Scope isolate_scope(isolate); + DebugLocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::Debug::SetMessageHandler(&ThreadedMessageHandler); + v8::Handle global_template = + v8::ObjectTemplate::New(env->GetIsolate()); + global_template->Set( + v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), + v8::FunctionTemplate::New(isolate, ThreadedAtBarrier1)); + v8::Handle context = v8::Context::New(isolate, + NULL, + global_template); + v8::Context::Scope context_scope(context); + + CompileRun(source); } @@ -5251,21 +5234,21 @@ void DebuggerThread::Run() { "\"type\":\"request\"," "\"command\":\"continue\"}"; + v8::Isolate* isolate = CcTest::isolate(); threaded_debugging_barriers.barrier_1.Wait(); - v8::Debug::DebugBreak(isolate_); + v8::Debug::DebugBreak(isolate); threaded_debugging_barriers.barrier_2.Wait(); - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer)); - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer)); } TEST(ThreadedDebugging) { + DebuggerThread debugger_thread; V8Thread v8_thread; // Create a V8 environment v8_thread.Start(); - threaded_debugging_barriers.barrier_3.Wait(); - DebuggerThread debugger_thread(v8_thread.isolate()); debugger_thread.Start(); v8_thread.Join(); @@ -5284,24 +5267,17 @@ class BreakpointsV8Thread : public v8::base::Thread { public: BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {} void Run(); - - v8::Isolate* isolate() { return isolate_; } - - private: - v8::Isolate* isolate_; }; class BreakpointsDebuggerThread : public v8::base::Thread { public: - BreakpointsDebuggerThread(bool global_evaluate, v8::Isolate* isolate) + explicit BreakpointsDebuggerThread(bool global_evaluate) : Thread(Options("BreakpointsDebuggerThread")), - global_evaluate_(global_evaluate), - isolate_(isolate) {} + global_evaluate_(global_evaluate) {} void Run(); private: bool global_evaluate_; - v8::Isolate* isolate_; }; @@ -5346,20 +5322,16 @@ void BreakpointsV8Thread::Run() { const char* source_2 = "cat(17);\n" "cat(19);\n"; - isolate_ = v8::Isolate::New(); - breakpoints_barriers->barrier_3.Wait(); - { - v8::Isolate::Scope isolate_scope(isolate_); - DebugLocalContext env(isolate_); - v8::HandleScope scope(isolate_); - v8::Debug::SetMessageHandler(&BreakpointsMessageHandler); - - CompileRun(source_1); - breakpoints_barriers->barrier_1.Wait(); - breakpoints_barriers->barrier_2.Wait(); - CompileRun(source_2); - } - isolate_->Dispose(); + v8::Isolate* isolate = CcTest::isolate(); + v8::Isolate::Scope isolate_scope(isolate); + DebugLocalContext env; + v8::HandleScope scope(isolate); + v8::Debug::SetMessageHandler(&BreakpointsMessageHandler); + + CompileRun(source_1); + breakpoints_barriers->barrier_1.Wait(); + breakpoints_barriers->barrier_2.Wait(); + CompileRun(source_2); } @@ -5425,12 +5397,14 @@ void BreakpointsDebuggerThread::Run() { "\"command\":\"continue\"}"; + v8::Isolate* isolate = CcTest::isolate(); + v8::Isolate::Scope isolate_scope(isolate); // v8 thread initializes, runs source_1 breakpoints_barriers->barrier_1.Wait(); // 1:Set breakpoint in cat() (will get id 1). - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer)); // 2:Set breakpoint in dog() (will get id 2). - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer)); breakpoints_barriers->barrier_2.Wait(); // V8 thread starts compiling source_2. // Automatic break happens, to run queued commands @@ -5442,42 +5416,43 @@ void BreakpointsDebuggerThread::Run() { // Must have hit breakpoint #1. CHECK_EQ(1, break_event_breakpoint_id); // 4:Evaluate dog() (which has a breakpoint). - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_3, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_3, buffer)); // V8 thread hits breakpoint in dog(). breakpoints_barriers->semaphore_1.Wait(); // wait for break event // Must have hit breakpoint #2. CHECK_EQ(2, break_event_breakpoint_id); // 5:Evaluate (x + 1). - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_4, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_4, buffer)); // Evaluate (x + 1) finishes. breakpoints_barriers->semaphore_1.Wait(); // Must have result 108. CHECK_EQ(108, evaluate_int_result); // 6:Continue evaluation of dog(). - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_5, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_5, buffer)); // Evaluate dog() finishes. breakpoints_barriers->semaphore_1.Wait(); // Must have result 107. CHECK_EQ(107, evaluate_int_result); // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint // in cat(19). - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_6, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_6, buffer)); // Message callback gets break event. breakpoints_barriers->semaphore_1.Wait(); // wait for break event // Must have hit breakpoint #1. CHECK_EQ(1, break_event_breakpoint_id); // 8: Evaluate dog() with breaks disabled. - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_7, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_7, buffer)); // Evaluate dog() finishes. breakpoints_barriers->semaphore_1.Wait(); // Must have result 116. CHECK_EQ(116, evaluate_int_result); // 9: Continue evaluation of source2, reach end. - v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_8, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_8, buffer)); } void TestRecursiveBreakpointsGeneric(bool global_evaluate) { + BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); BreakpointsV8Thread breakpoints_v8_thread; // Create a V8 environment @@ -5485,9 +5460,6 @@ void TestRecursiveBreakpointsGeneric(bool global_evaluate) { breakpoints_barriers = &stack_allocated_breakpoints_barriers; breakpoints_v8_thread.Start(); - breakpoints_barriers->barrier_3.Wait(); - BreakpointsDebuggerThread breakpoints_debugger_thread( - global_evaluate, breakpoints_v8_thread.isolate()); breakpoints_debugger_thread.Start(); breakpoints_v8_thread.Join(); diff --git a/test/cctest/test-deoptimization.cc b/test/cctest/test-deoptimization.cc index a201ccd..262ffc1 100644 --- a/test/cctest/test-deoptimization.cc +++ b/test/cctest/test-deoptimization.cc @@ -98,8 +98,8 @@ class AllowNativesSyntaxNoInlining { // Abort any ongoing incremental marking to make sure that all weak global // handle callbacks are processed. -static void NonIncrementalGC(i::Isolate* isolate) { - isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); +static void NonIncrementalGC() { + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); } @@ -127,7 +127,7 @@ TEST(DeoptimizeSimple) { "function f() { g(); };" "f();"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -143,7 +143,7 @@ TEST(DeoptimizeSimple) { "function f(x) { if (x) { g(); } else { return } };" "f(true);"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -167,7 +167,7 @@ TEST(DeoptimizeSimpleWithArguments) { "function f(x, y, z) { g(1,x); y+z; };" "f(1, \"2\", false);"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -184,7 +184,7 @@ TEST(DeoptimizeSimpleWithArguments) { "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" "f(true, 1, \"2\");"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -209,7 +209,7 @@ TEST(DeoptimizeSimpleNested) { "function g(z) { count++; %DeoptimizeFunction(f); return z;}" "function f(x,y,z) { return h(x, y, g(z)); };" "result = f(1, 2, 3);"); - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -235,7 +235,7 @@ TEST(DeoptimizeRecursive) { "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" "f(10);"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); @@ -268,7 +268,7 @@ TEST(DeoptimizeMultiple) { "function f1(x) { return f2(x + 1, x + 1) + x; };" "result = f1(1);"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -290,7 +290,7 @@ TEST(DeoptimizeConstructor) { "function f() { g(); };" "result = new f() instanceof f;"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); @@ -307,7 +307,7 @@ TEST(DeoptimizeConstructor) { "result = new f(1, 2);" "result = result.x + result.y;"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -337,7 +337,7 @@ TEST(DeoptimizeConstructorMultiple) { "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" "result = new f1(1).result;"); } - NonIncrementalGC(CcTest::i_isolate()); + NonIncrementalGC(); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -345,61 +345,51 @@ TEST(DeoptimizeConstructorMultiple) { } -UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) { +TEST(DeoptimizeBinaryOperationADDString) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; AllowNativesSyntaxNoInlining options; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); - - const char* f_source = "function f(x, y) { return x + y; };"; - - { - // Compile function f and collect to type feedback to insert binary op - // stub call in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun( - "var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.toString = function () {" - " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" - "};"); - CompileRun(f_source); - CompileRun( - "for (var i = 0; i < 5; i++) {" - " f('a+', new X());" - "};"); - - // Compile an optimized version of f. - i::FLAG_always_opt = true; - CompileRun(f_source); - CompileRun("f('a+', new X());"); - CHECK(!i_isolate->use_crankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); - - // Call f and force deoptimization while processing the binary operation. - CompileRun( - "deopt = true;" - "var result = f('a+', new X());"); - } - NonIncrementalGC(i_isolate); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - v8::Handle result = env->Global()->Get(v8_str("result")); - CHECK(result->IsString()); - v8::String::Utf8Value utf8(result); - CHECK_EQ("a+an X", *utf8); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + const char* f_source = "function f(x, y) { return x + y; };"; + + { + // Compile function f and collect to type feedback to insert binary op stub + // call in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun("var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.toString = function () {" + " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" + "};"); + CompileRun(f_source); + CompileRun("for (var i = 0; i < 5; i++) {" + " f('a+', new X());" + "};"); + + // Compile an optimized version of f. + i::FLAG_always_opt = true; + CompileRun(f_source); + CompileRun("f('a+', new X());"); + CHECK(!CcTest::i_isolate()->use_crankshaft() || + GetJSFunction(env->Global(), "f")->IsOptimized()); + + // Call f and force deoptimization while processing the binary operation. + CompileRun("deopt = true;" + "var result = f('a+', new X());"); } - isolate->Exit(); - isolate->Dispose(); + NonIncrementalGC(); + + CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + v8::Handle result = env->Global()->Get(v8_str("result")); + CHECK(result->IsString()); + v8::String::Utf8Value utf8(result); + CHECK_EQ("a+an X", *utf8); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -416,7 +406,6 @@ static void CompileConstructorWithDeoptimizingValueOf() { static void TestDeoptimizeBinaryOpHelper(LocalContext* env, const char* binary_op) { - i::Isolate* i_isolate = reinterpret_cast((*env)->GetIsolate()); EmbeddedVector f_source_buffer; SNPrintF(f_source_buffer, "function f(x, y) { return x %s y; };", @@ -437,355 +426,290 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env, i::FLAG_always_opt = true; CompileRun(f_source); CompileRun("f(7, new X());"); - CHECK(!i_isolate->use_crankshaft() || + CHECK(!CcTest::i_isolate()->use_crankshaft() || GetJSFunction((*env)->Global(), "f")->IsOptimized()); // Call f and force deoptimization while processing the binary operation. CompileRun("deopt = true;" "var result = f(7, new X());"); - NonIncrementalGC(i_isolate); + NonIncrementalGC(); CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); } -UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) { +TEST(DeoptimizeBinaryOperationADD) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "+"); + TestDeoptimizeBinaryOpHelper(&env, "+"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); - } - isolate->Exit(); - isolate->Dispose(); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } -UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) { +TEST(DeoptimizeBinaryOperationSUB) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "-"); + TestDeoptimizeBinaryOpHelper(&env, "-"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); - } - isolate->Exit(); - isolate->Dispose(); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } -UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) { +TEST(DeoptimizeBinaryOperationMUL) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "*"); + TestDeoptimizeBinaryOpHelper(&env, "*"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); - } - isolate->Exit(); - isolate->Dispose(); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } -UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) { +TEST(DeoptimizeBinaryOperationDIV) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "/"); + TestDeoptimizeBinaryOpHelper(&env, "/"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); - } - isolate->Exit(); - isolate->Dispose(); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } -UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) { +TEST(DeoptimizeBinaryOperationMOD) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "%"); + TestDeoptimizeBinaryOpHelper(&env, "%"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); - } - isolate->Exit(); - isolate->Dispose(); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } -UNINITIALIZED_TEST(DeoptimizeCompare) { +TEST(DeoptimizeCompare) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); - - const char* f_source = "function f(x, y) { return x < y; };"; - - { - AllowNativesSyntaxNoInlining options; - // Compile function f and collect to type feedback to insert compare ic - // call in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun( - "var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.toString = function () {" - " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" - "};"); - CompileRun(f_source); - CompileRun( - "for (var i = 0; i < 5; i++) {" - " f('a', new X());" - "};"); - - // Compile an optimized version of f. - i::FLAG_always_opt = true; - CompileRun(f_source); - CompileRun("f('a', new X());"); - CHECK(!i_isolate->use_crankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); - - // Call f and force deoptimization while processing the comparison. - CompileRun( - "deopt = true;" - "var result = f('a', new X());"); - } - NonIncrementalGC(i_isolate); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + const char* f_source = "function f(x, y) { return x < y; };"; + + { + AllowNativesSyntaxNoInlining options; + // Compile function f and collect to type feedback to insert compare ic + // call in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun("var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.toString = function () {" + " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" + "};"); + CompileRun(f_source); + CompileRun("for (var i = 0; i < 5; i++) {" + " f('a', new X());" + "};"); + + // Compile an optimized version of f. + i::FLAG_always_opt = true; + CompileRun(f_source); + CompileRun("f('a', new X());"); + CHECK(!CcTest::i_isolate()->use_crankshaft() || + GetJSFunction(env->Global(), "f")->IsOptimized()); + + // Call f and force deoptimization while processing the comparison. + CompileRun("deopt = true;" + "var result = f('a', new X());"); } - isolate->Exit(); - isolate->Dispose(); + NonIncrementalGC(); + + CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } -UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) { +TEST(DeoptimizeLoadICStoreIC) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + + // Functions to generate load/store/keyed load/keyed store IC calls. + const char* f1_source = "function f1(x) { return x.y; };"; + const char* g1_source = "function g1(x) { x.y = 1; };"; + const char* f2_source = "function f2(x, y) { return x[y]; };"; + const char* g2_source = "function g2(x, y) { x[y] = 1; };"; + { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); - - // Functions to generate load/store/keyed load/keyed store IC calls. - const char* f1_source = "function f1(x) { return x.y; };"; - const char* g1_source = "function g1(x) { x.y = 1; };"; - const char* f2_source = "function f2(x, y) { return x[y]; };"; - const char* g2_source = "function g2(x, y) { x[y] = 1; };"; - - { - AllowNativesSyntaxNoInlining options; - // Compile functions and collect to type feedback to insert ic - // calls in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun( - "var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.__defineGetter__('y', function () {" - " if (deopt) { count++; %DeoptimizeFunction(f1); };" - " return 13;" - "});" - "X.prototype.__defineSetter__('y', function () {" - " if (deopt) { count++; %DeoptimizeFunction(g1); };" - "});" - "X.prototype.__defineGetter__('z', function () {" - " if (deopt) { count++; %DeoptimizeFunction(f2); };" - " return 13;" - "});" - "X.prototype.__defineSetter__('z', function () {" - " if (deopt) { count++; %DeoptimizeFunction(g2); };" - "});"); - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun( - "for (var i = 0; i < 5; i++) {" - " f1(new X());" - " g1(new X());" - " f2(new X(), 'z');" - " g2(new X(), 'z');" - "};"); - - // Compile an optimized version of the functions. - i::FLAG_always_opt = true; - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun("f1(new X());"); - CompileRun("g1(new X());"); - CompileRun("f2(new X(), 'z');"); - CompileRun("g2(new X(), 'z');"); - if (i_isolate->use_crankshaft()) { - CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); - } - - // Call functions and force deoptimization while processing the ics. - CompileRun( - "deopt = true;" - "var result = f1(new X());" - "g1(new X());" - "f2(new X(), 'z');" - "g2(new X(), 'z');"); + AllowNativesSyntaxNoInlining options; + // Compile functions and collect to type feedback to insert ic + // calls in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun("var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.__defineGetter__('y', function () {" + " if (deopt) { count++; %DeoptimizeFunction(f1); };" + " return 13;" + "});" + "X.prototype.__defineSetter__('y', function () {" + " if (deopt) { count++; %DeoptimizeFunction(g1); };" + "});" + "X.prototype.__defineGetter__('z', function () {" + " if (deopt) { count++; %DeoptimizeFunction(f2); };" + " return 13;" + "});" + "X.prototype.__defineSetter__('z', function () {" + " if (deopt) { count++; %DeoptimizeFunction(g2); };" + "});"); + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun("for (var i = 0; i < 5; i++) {" + " f1(new X());" + " g1(new X());" + " f2(new X(), 'z');" + " g2(new X(), 'z');" + "};"); + + // Compile an optimized version of the functions. + i::FLAG_always_opt = true; + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun("f1(new X());"); + CompileRun("g1(new X());"); + CompileRun("f2(new X(), 'z');"); + CompileRun("g2(new X(), 'z');"); + if (CcTest::i_isolate()->use_crankshaft()) { + CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); } - NonIncrementalGC(i_isolate); - - CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); - CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); + + // Call functions and force deoptimization while processing the ics. + CompileRun("deopt = true;" + "var result = f1(new X());" + "g1(new X());" + "f2(new X(), 'z');" + "g2(new X(), 'z');"); } - isolate->Exit(); - isolate->Dispose(); + NonIncrementalGC(); + + CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); + CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); } -UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) { +TEST(DeoptimizeLoadICStoreICNested) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + + // Functions to generate load/store/keyed load/keyed store IC calls. + const char* f1_source = "function f1(x) { return x.y; };"; + const char* g1_source = "function g1(x) { x.y = 1; };"; + const char* f2_source = "function f2(x, y) { return x[y]; };"; + const char* g2_source = "function g2(x, y) { x[y] = 1; };"; + { - LocalContext env(isolate); - v8::HandleScope scope(env->GetIsolate()); - - // Functions to generate load/store/keyed load/keyed store IC calls. - const char* f1_source = "function f1(x) { return x.y; };"; - const char* g1_source = "function g1(x) { x.y = 1; };"; - const char* f2_source = "function f2(x, y) { return x[y]; };"; - const char* g2_source = "function g2(x, y) { x[y] = 1; };"; - - { - AllowNativesSyntaxNoInlining options; - // Compile functions and collect to type feedback to insert ic - // calls in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun( - "var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.__defineGetter__('y', function () {" - " g1(this);" - " return 13;" - "});" - "X.prototype.__defineSetter__('y', function () {" - " f2(this, 'z');" - "});" - "X.prototype.__defineGetter__('z', function () {" - " g2(this, 'z');" - "});" - "X.prototype.__defineSetter__('z', function () {" - " if (deopt) {" - " count++;" - " %DeoptimizeFunction(f1);" - " %DeoptimizeFunction(g1);" - " %DeoptimizeFunction(f2);" - " %DeoptimizeFunction(g2); };" - "});"); - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun( - "for (var i = 0; i < 5; i++) {" - " f1(new X());" - " g1(new X());" - " f2(new X(), 'z');" - " g2(new X(), 'z');" - "};"); - - // Compile an optimized version of the functions. - i::FLAG_always_opt = true; - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun("f1(new X());"); - CompileRun("g1(new X());"); - CompileRun("f2(new X(), 'z');"); - CompileRun("g2(new X(), 'z');"); - if (i_isolate->use_crankshaft()) { - CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); - } - - // Call functions and force deoptimization while processing the ics. - CompileRun( - "deopt = true;" - "var result = f1(new X());"); + AllowNativesSyntaxNoInlining options; + // Compile functions and collect to type feedback to insert ic + // calls in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun("var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.__defineGetter__('y', function () {" + " g1(this);" + " return 13;" + "});" + "X.prototype.__defineSetter__('y', function () {" + " f2(this, 'z');" + "});" + "X.prototype.__defineGetter__('z', function () {" + " g2(this, 'z');" + "});" + "X.prototype.__defineSetter__('z', function () {" + " if (deopt) {" + " count++;" + " %DeoptimizeFunction(f1);" + " %DeoptimizeFunction(g1);" + " %DeoptimizeFunction(f2);" + " %DeoptimizeFunction(g2); };" + "});"); + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun("for (var i = 0; i < 5; i++) {" + " f1(new X());" + " g1(new X());" + " f2(new X(), 'z');" + " g2(new X(), 'z');" + "};"); + + // Compile an optimized version of the functions. + i::FLAG_always_opt = true; + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun("f1(new X());"); + CompileRun("g1(new X());"); + CompileRun("f2(new X(), 'z');"); + CompileRun("g2(new X(), 'z');"); + if (CcTest::i_isolate()->use_crankshaft()) { + CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); } - NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); + // Call functions and force deoptimization while processing the ics. + CompileRun("deopt = true;" + "var result = f1(new X());"); } - isolate->Exit(); - isolate->Dispose(); + NonIncrementalGC(); + + CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); } diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index fcee9f4..aca4b9d 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -1052,61 +1052,53 @@ TEST(Regression39128) { } -UNINITIALIZED_TEST(TestCodeFlushing) { +TEST(TestCodeFlushing) { // If we do not flush code this test is invalid. if (!FLAG_flush_code) return; i::FLAG_allow_natives_syntax = true; i::FLAG_optimize_for_size = false; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - isolate->Enter(); - Factory* factory = i_isolate->factory(); - { - v8::HandleScope scope(isolate); - v8::Context::New(isolate)->Enter(); - const char* source = - "function foo() {" - " var x = 42;" - " var y = 42;" - " var z = x + y;" - "};" - "foo()"; - Handle foo_name = factory->InternalizeUtf8String("foo"); - - // This compile will add the code to the compilation cache. - { - v8::HandleScope scope(isolate); - CompileRun(source); - } + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + v8::HandleScope scope(CcTest::isolate()); + const char* source = "function foo() {" + " var x = 42;" + " var y = 42;" + " var z = x + y;" + "};" + "foo()"; + Handle foo_name = factory->InternalizeUtf8String("foo"); - // Check function is compiled. - Handle func_value = Object::GetProperty(i_isolate->global_object(), - foo_name).ToHandleChecked(); - CHECK(func_value->IsJSFunction()); - Handle function = Handle::cast(func_value); - CHECK(function->shared()->is_compiled()); + // This compile will add the code to the compilation cache. + { v8::HandleScope scope(CcTest::isolate()); + CompileRun(source); + } - // The code will survive at least two GCs. - i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK(function->shared()->is_compiled()); + // Check function is compiled. + Handle func_value = Object::GetProperty( + CcTest::i_isolate()->global_object(), foo_name).ToHandleChecked(); + CHECK(func_value->IsJSFunction()); + Handle function = Handle::cast(func_value); + CHECK(function->shared()->is_compiled()); - // Simulate several GCs that use full marking. - const int kAgingThreshold = 6; - for (int i = 0; i < kAgingThreshold; i++) { - i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - } + // The code will survive at least two GCs. + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CHECK(function->shared()->is_compiled()); - // foo should no longer be in the compilation cache - CHECK(!function->shared()->is_compiled() || function->IsOptimized()); - CHECK(!function->is_compiled() || function->IsOptimized()); - // Call foo to get it recompiled. - CompileRun("foo()"); - CHECK(function->shared()->is_compiled()); - CHECK(function->is_compiled()); + // Simulate several GCs that use full marking. + const int kAgingThreshold = 6; + for (int i = 0; i < kAgingThreshold; i++) { + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); } - isolate->Exit(); - isolate->Dispose(); + + // foo should no longer be in the compilation cache + CHECK(!function->shared()->is_compiled() || function->IsOptimized()); + CHECK(!function->is_compiled() || function->IsOptimized()); + // Call foo to get it recompiled. + CompileRun("foo()"); + CHECK(function->shared()->is_compiled()); + CHECK(function->is_compiled()); } @@ -3305,28 +3297,26 @@ class SourceResource : public v8::String::ExternalOneByteStringResource { }; -void ReleaseStackTraceDataTest(v8::Isolate* isolate, const char* source, - const char* accessor) { +void ReleaseStackTraceDataTest(const char* source, const char* accessor) { // Test that the data retained by the Error.stack accessor is released // after the first time the accessor is fired. We use external string // to check whether the data is being released since the external string // resource's callback is fired when the external string is GC'ed. - i::Isolate* i_isolate = reinterpret_cast(isolate); - v8::HandleScope scope(isolate); + v8::HandleScope scope(CcTest::isolate()); SourceResource* resource = new SourceResource(i::StrDup(source)); { - v8::HandleScope scope(isolate); + v8::HandleScope scope(CcTest::isolate()); v8::Handle source_string = - v8::String::NewExternal(isolate, resource); - i_isolate->heap()->CollectAllAvailableGarbage(); + v8::String::NewExternal(CcTest::isolate(), resource); + CcTest::heap()->CollectAllAvailableGarbage(); v8::Script::Compile(source_string)->Run(); CHECK(!resource->IsDisposed()); } - // i_isolate->heap()->CollectAllAvailableGarbage(); + // CcTest::heap()->CollectAllAvailableGarbage(); CHECK(!resource->IsDisposed()); CompileRun(accessor); - i_isolate->heap()->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); // External source has been released. CHECK(resource->IsDisposed()); @@ -3334,7 +3324,7 @@ void ReleaseStackTraceDataTest(v8::Isolate* isolate, const char* source, } -UNINITIALIZED_TEST(ReleaseStackTraceData) { +TEST(ReleaseStackTraceData) { if (i::FLAG_always_opt) { // TODO(ulan): Remove this once the memory leak via code_next_link is fixed. // See: https://codereview.chromium.org/181833004/ @@ -3342,51 +3332,46 @@ UNINITIALIZED_TEST(ReleaseStackTraceData) { } FLAG_use_ic = false; // ICs retain objects. FLAG_concurrent_recompilation = false; - v8::Isolate* isolate = v8::Isolate::New(); - { - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - v8::Context::New(isolate)->Enter(); - static const char* source1 = "var error = null; " - /* Normal Error */ "try { " - " throw new Error(); " - "} catch (e) { " - " error = e; " - "} "; - static const char* source2 = "var error = null; " - /* Stack overflow */ "try { " - " (function f() { f(); })(); " - "} catch (e) { " - " error = e; " - "} "; - static const char* source3 = "var error = null; " - /* Normal Error */ "try { " - /* as prototype */ " throw new Error(); " - "} catch (e) { " - " error = {}; " - " error.__proto__ = e; " - "} "; - static const char* source4 = "var error = null; " - /* Stack overflow */ "try { " - /* as prototype */ " (function f() { f(); })(); " - "} catch (e) { " - " error = {}; " - " error.__proto__ = e; " - "} "; - static const char* getter = "error.stack"; - static const char* setter = "error.stack = 0"; - - ReleaseStackTraceDataTest(isolate, source1, setter); - ReleaseStackTraceDataTest(isolate, source2, setter); - // We do not test source3 and source4 with setter, since the setter is - // supposed to (untypically) write to the receiver, not the holder. This is - // to emulate the behavior of a data property. - - ReleaseStackTraceDataTest(isolate, source1, getter); - ReleaseStackTraceDataTest(isolate, source2, getter); - ReleaseStackTraceDataTest(isolate, source3, getter); - ReleaseStackTraceDataTest(isolate, source4, getter); - } + CcTest::InitializeVM(); + static const char* source1 = "var error = null; " + /* Normal Error */ "try { " + " throw new Error(); " + "} catch (e) { " + " error = e; " + "} "; + static const char* source2 = "var error = null; " + /* Stack overflow */ "try { " + " (function f() { f(); })(); " + "} catch (e) { " + " error = e; " + "} "; + static const char* source3 = "var error = null; " + /* Normal Error */ "try { " + /* as prototype */ " throw new Error(); " + "} catch (e) { " + " error = {}; " + " error.__proto__ = e; " + "} "; + static const char* source4 = "var error = null; " + /* Stack overflow */ "try { " + /* as prototype */ " (function f() { f(); })(); " + "} catch (e) { " + " error = {}; " + " error.__proto__ = e; " + "} "; + static const char* getter = "error.stack"; + static const char* setter = "error.stack = 0"; + + ReleaseStackTraceDataTest(source1, setter); + ReleaseStackTraceDataTest(source2, setter); + // We do not test source3 and source4 with setter, since the setter is + // supposed to (untypically) write to the receiver, not the holder. This is + // to emulate the behavior of a data property. + + ReleaseStackTraceDataTest(source1, getter); + ReleaseStackTraceDataTest(source2, getter); + ReleaseStackTraceDataTest(source3, getter); + ReleaseStackTraceDataTest(source4, getter); } @@ -4364,84 +4349,78 @@ TEST(ArrayShiftSweeping) { } -UNINITIALIZED_TEST(PromotionQueue) { +TEST(PromotionQueue) { i::FLAG_expose_gc = true; i::FLAG_max_semi_space_size = 2; - v8::Isolate* isolate = v8::Isolate::New(); - i::Isolate* i_isolate = reinterpret_cast(isolate); - { - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - v8::Context::New(isolate)->Enter(); - Heap* heap = i_isolate->heap(); - NewSpace* new_space = heap->new_space(); - - // In this test we will try to overwrite the promotion queue which is at the - // end of to-space. To actually make that possible, we need at least two - // semi-space pages and take advantage of fragementation. - // (1) Grow semi-space to two pages. - // (2) Create a few small long living objects and call the scavenger to - // move them to the other semi-space. - // (3) Create a huge object, i.e., remainder of first semi-space page and - // create another huge object which should be of maximum allocatable memory - // size of the second semi-space page. - // (4) Call the scavenger again. - // What will happen is: the scavenger will promote the objects created in - // (2) and will create promotion queue entries at the end of the second - // semi-space page during the next scavenge when it promotes the objects to - // the old generation. The first allocation of (3) will fill up the first - // semi-space page. The second allocation in (3) will not fit into the - // first semi-space page, but it will overwrite the promotion queue which - // are in the second semi-space page. If the right guards are in place, the - // promotion queue will be evacuated in that case. - - // Grow the semi-space to two pages to make semi-space copy overwrite the - // promotion queue, which will be at the end of the second page. - intptr_t old_capacity = new_space->TotalCapacity(); - new_space->Grow(); - CHECK(new_space->IsAtMaximumCapacity()); - CHECK(2 * old_capacity == new_space->TotalCapacity()); - - // Call the scavenger two times to get an empty new space - heap->CollectGarbage(NEW_SPACE); - heap->CollectGarbage(NEW_SPACE); - - // First create a few objects which will survive a scavenge, and will get - // promoted to the old generation later on. These objects will create - // promotion queue entries at the end of the second semi-space page. - const int number_handles = 12; - Handle handles[number_handles]; - for (int i = 0; i < number_handles; i++) { - handles[i] = i_isolate->factory()->NewFixedArray(1, NOT_TENURED); - } - heap->CollectGarbage(NEW_SPACE); - - // Create the first huge object which will exactly fit the first semi-space - // page. - int new_linear_size = - static_cast(*heap->new_space()->allocation_limit_address() - - *heap->new_space()->allocation_top_address()); - int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize; - Handle first = - i_isolate->factory()->NewFixedArray(length, NOT_TENURED); - CHECK(heap->InNewSpace(*first)); - - // Create the second huge object of maximum allocatable second semi-space - // page size. - new_linear_size = - static_cast(*heap->new_space()->allocation_limit_address() - - *heap->new_space()->allocation_top_address()); - length = Page::kMaxRegularHeapObjectSize / kPointerSize - - FixedArray::kHeaderSize; - Handle second = - i_isolate->factory()->NewFixedArray(length, NOT_TENURED); - CHECK(heap->InNewSpace(*second)); - - // This scavenge will corrupt memory if the promotion queue is not - // evacuated. - heap->CollectGarbage(NEW_SPACE); + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + NewSpace* new_space = heap->new_space(); + + // In this test we will try to overwrite the promotion queue which is at the + // end of to-space. To actually make that possible, we need at least two + // semi-space pages and take advantage of fragementation. + // (1) Grow semi-space to two pages. + // (2) Create a few small long living objects and call the scavenger to + // move them to the other semi-space. + // (3) Create a huge object, i.e., remainder of first semi-space page and + // create another huge object which should be of maximum allocatable memory + // size of the second semi-space page. + // (4) Call the scavenger again. + // What will happen is: the scavenger will promote the objects created in (2) + // and will create promotion queue entries at the end of the second + // semi-space page during the next scavenge when it promotes the objects to + // the old generation. The first allocation of (3) will fill up the first + // semi-space page. The second allocation in (3) will not fit into the first + // semi-space page, but it will overwrite the promotion queue which are in + // the second semi-space page. If the right guards are in place, the promotion + // queue will be evacuated in that case. + + // Grow the semi-space to two pages to make semi-space copy overwrite the + // promotion queue, which will be at the end of the second page. + intptr_t old_capacity = new_space->TotalCapacity(); + new_space->Grow(); + CHECK(new_space->IsAtMaximumCapacity()); + CHECK(2 * old_capacity == new_space->TotalCapacity()); + + // Call the scavenger two times to get an empty new space + heap->CollectGarbage(NEW_SPACE); + heap->CollectGarbage(NEW_SPACE); + + // First create a few objects which will survive a scavenge, and will get + // promoted to the old generation later on. These objects will create + // promotion queue entries at the end of the second semi-space page. + const int number_handles = 12; + Handle handles[number_handles]; + for (int i = 0; i < number_handles; i++) { + handles[i] = isolate->factory()->NewFixedArray(1, NOT_TENURED); } - isolate->Dispose(); + heap->CollectGarbage(NEW_SPACE); + + // Create the first huge object which will exactly fit the first semi-space + // page. + int new_linear_size = static_cast( + *heap->new_space()->allocation_limit_address() - + *heap->new_space()->allocation_top_address()); + int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize; + Handle first = + isolate->factory()->NewFixedArray(length, NOT_TENURED); + CHECK(heap->InNewSpace(*first)); + + // Create the second huge object of maximum allocatable second semi-space + // page size. + new_linear_size = static_cast( + *heap->new_space()->allocation_limit_address() - + *heap->new_space()->allocation_top_address()); + length = Page::kMaxRegularHeapObjectSize / kPointerSize - + FixedArray::kHeaderSize; + Handle second = + isolate->factory()->NewFixedArray(length, NOT_TENURED); + CHECK(heap->InNewSpace(*second)); + + // This scavenge will corrupt memory if the promotion queue is not evacuated. + heap->CollectGarbage(NEW_SPACE); } diff --git a/test/cctest/test-liveedit.cc b/test/cctest/test-liveedit.cc index 6a5f0b2..f5c2274 100644 --- a/test/cctest/test-liveedit.cc +++ b/test/cctest/test-liveedit.cc @@ -158,6 +158,7 @@ void CompareStrings(const char* s1, const char* s2, // --- T h e A c t u a l T e s t s TEST(LiveEditDiffer) { + v8::internal::V8::Initialize(NULL); CompareStrings("zz1zzz12zz123zzz", "zzzzzzzzzz", 6); CompareStrings("zz1zzz12zz123zzz", "zz0zzz0zz0zzz", 9); CompareStrings("123456789", "987654321", 16); diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc index 482f89f..d72e6f0 100644 --- a/test/cctest/test-log.cc +++ b/test/cctest/test-log.cc @@ -61,11 +61,9 @@ class ScopedLoggerInitializer { temp_file_(NULL), // Need to run this prior to creating the scope. trick_to_run_init_flags_(init_flags_()), - isolate_(v8::Isolate::New()), - isolate_scope_(isolate_), - scope_(isolate_), - env_(v8::Context::New(isolate_)), - logger_(reinterpret_cast(isolate_)->logger()) { + scope_(CcTest::isolate()), + env_(v8::Context::New(CcTest::isolate())), + logger_(CcTest::i_isolate()->logger()) { env_->Enter(); } @@ -79,8 +77,6 @@ class ScopedLoggerInitializer { v8::Handle& env() { return env_; } - v8::Isolate* isolate() { return isolate_; } - Logger* logger() { return logger_; } FILE* StopLoggingGetTempFile() { @@ -104,8 +100,6 @@ class ScopedLoggerInitializer { const bool saved_prof_; FILE* temp_file_; const bool trick_to_run_init_flags_; - v8::Isolate* isolate_; - v8::Isolate::Scope isolate_scope_; v8::HandleScope scope_; v8::Handle env_; Logger* logger_; @@ -336,41 +330,41 @@ static void ObjMethod1(const v8::FunctionCallbackInfo& args) { TEST(LogCallbacks) { - v8::Isolate* isolate; - { - ScopedLoggerInitializer initialize_logger; - isolate = initialize_logger.isolate(); - Logger* logger = initialize_logger.logger(); - - v8::Local obj = v8::Local::New( - isolate, v8::FunctionTemplate::New(isolate)); - obj->SetClassName(v8_str("Obj")); - v8::Handle proto = obj->PrototypeTemplate(); - v8::Local signature = v8::Signature::New(isolate, obj); - proto->Set(v8_str("method1"), - v8::FunctionTemplate::New(isolate, ObjMethod1, - v8::Handle(), signature), - static_cast(v8::DontDelete)); - - initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction()); - CompileRun("Obj.prototype.method1.toString();"); - - logger->LogCompiledFunctions(); - - bool exists = false; - i::Vector log( - i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); - CHECK(exists); - - i::EmbeddedVector ref_data; - i::SNPrintF(ref_data, - "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"", - reinterpret_cast(ObjMethod1)); - - CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length())); - log.Dispose(); - } - isolate->Dispose(); + v8::Isolate* isolate = CcTest::isolate(); + ScopedLoggerInitializer initialize_logger; + Logger* logger = initialize_logger.logger(); + + v8::Local obj = + v8::Local::New(isolate, + v8::FunctionTemplate::New(isolate)); + obj->SetClassName(v8_str("Obj")); + v8::Handle proto = obj->PrototypeTemplate(); + v8::Local signature = + v8::Signature::New(isolate, obj); + proto->Set(v8_str("method1"), + v8::FunctionTemplate::New(isolate, + ObjMethod1, + v8::Handle(), + signature), + static_cast(v8::DontDelete)); + + initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction()); + CompileRun("Obj.prototype.method1.toString();"); + + logger->LogCompiledFunctions(); + + bool exists = false; + i::Vector log( + i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); + CHECK(exists); + + i::EmbeddedVector ref_data; + i::SNPrintF(ref_data, + "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"", + reinterpret_cast(ObjMethod1)); + + CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length())); + log.Dispose(); } @@ -389,49 +383,46 @@ static void Prop2Getter(v8::Local property, TEST(LogAccessorCallbacks) { - v8::Isolate* isolate; - { - ScopedLoggerInitializer initialize_logger; - isolate = initialize_logger.isolate(); - Logger* logger = initialize_logger.logger(); - - v8::Local obj = v8::Local::New( - isolate, v8::FunctionTemplate::New(isolate)); - obj->SetClassName(v8_str("Obj")); - v8::Handle inst = obj->InstanceTemplate(); - inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter); - inst->SetAccessor(v8_str("prop2"), Prop2Getter); - - logger->LogAccessorCallbacks(); - - bool exists = false; - i::Vector log( - i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); - CHECK(exists); - - EmbeddedVector prop1_getter_record; - i::SNPrintF(prop1_getter_record, - "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"", - reinterpret_cast(Prop1Getter)); - CHECK_NE(NULL, - StrNStr(log.start(), prop1_getter_record.start(), log.length())); - - EmbeddedVector prop1_setter_record; - i::SNPrintF(prop1_setter_record, - "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"", - reinterpret_cast(Prop1Setter)); - CHECK_NE(NULL, - StrNStr(log.start(), prop1_setter_record.start(), log.length())); - - EmbeddedVector prop2_getter_record; - i::SNPrintF(prop2_getter_record, - "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"", - reinterpret_cast(Prop2Getter)); - CHECK_NE(NULL, - StrNStr(log.start(), prop2_getter_record.start(), log.length())); - log.Dispose(); - } - isolate->Dispose(); + v8::Isolate* isolate = CcTest::isolate(); + ScopedLoggerInitializer initialize_logger; + Logger* logger = initialize_logger.logger(); + + v8::Local obj = + v8::Local::New(isolate, + v8::FunctionTemplate::New(isolate)); + obj->SetClassName(v8_str("Obj")); + v8::Handle inst = obj->InstanceTemplate(); + inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter); + inst->SetAccessor(v8_str("prop2"), Prop2Getter); + + logger->LogAccessorCallbacks(); + + bool exists = false; + i::Vector log( + i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); + CHECK(exists); + + EmbeddedVector prop1_getter_record; + i::SNPrintF(prop1_getter_record, + "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"", + reinterpret_cast(Prop1Getter)); + CHECK_NE(NULL, + StrNStr(log.start(), prop1_getter_record.start(), log.length())); + + EmbeddedVector prop1_setter_record; + i::SNPrintF(prop1_setter_record, + "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"", + reinterpret_cast(Prop1Setter)); + CHECK_NE(NULL, + StrNStr(log.start(), prop1_setter_record.start(), log.length())); + + EmbeddedVector prop2_getter_record; + i::SNPrintF(prop2_getter_record, + "code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"", + reinterpret_cast(Prop2Getter)); + CHECK_NE(NULL, + StrNStr(log.start(), prop2_getter_record.start(), log.length())); + log.Dispose(); } @@ -448,63 +439,57 @@ TEST(EquivalenceOfLoggingAndTraversal) { // are using V8. // Start with profiling to capture all code events from the beginning. - v8::Isolate* isolate; - { - ScopedLoggerInitializer initialize_logger; - isolate = initialize_logger.isolate(); - Logger* logger = initialize_logger.logger(); - - // Compile and run a function that creates other functions. - CompileRun( - "(function f(obj) {\n" - " obj.test =\n" - " (function a(j) { return function b() { return j; } })(100);\n" - "})(this);"); - logger->StopProfiler(); - reinterpret_cast(isolate)->heap()->CollectAllGarbage( - i::Heap::kMakeHeapIterableMask); - logger->StringEvent("test-logging-done", ""); - - // Iterate heap to find compiled functions, will write to log. - logger->LogCompiledFunctions(); - logger->StringEvent("test-traversal-done", ""); - - bool exists = false; - i::Vector log( - i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); - CHECK(exists); - v8::Handle log_str = v8::String::NewFromUtf8( - isolate, log.start(), v8::String::kNormalString, log.length()); - initialize_logger.env()->Global()->Set(v8_str("_log"), log_str); - - i::Vector source = TestSources::GetScriptsSource(); - v8::Handle source_str = v8::String::NewFromUtf8( - isolate, reinterpret_cast(source.start()), - v8::String::kNormalString, source.length()); - v8::TryCatch try_catch; - v8::Handle script = CompileWithOrigin(source_str, ""); - if (script.IsEmpty()) { - v8::String::Utf8Value exception(try_catch.Exception()); - printf("compile: %s\n", *exception); - CHECK(false); - } - v8::Handle result = script->Run(); - if (result.IsEmpty()) { - v8::String::Utf8Value exception(try_catch.Exception()); - printf("run: %s\n", *exception); - CHECK(false); - } - // The result either be a "true" literal or problem description. - if (!result->IsTrue()) { - v8::Local s = result->ToString(); - i::ScopedVector data(s->Utf8Length() + 1); - CHECK_NE(NULL, data.start()); - s->WriteUtf8(data.start()); - printf("%s\n", data.start()); - // Make sure that our output is written prior crash due to CHECK failure. - fflush(stdout); - CHECK(false); - } + ScopedLoggerInitializer initialize_logger; + Logger* logger = initialize_logger.logger(); + + // Compile and run a function that creates other functions. + CompileRun( + "(function f(obj) {\n" + " obj.test =\n" + " (function a(j) { return function b() { return j; } })(100);\n" + "})(this);"); + logger->StopProfiler(); + CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); + logger->StringEvent("test-logging-done", ""); + + // Iterate heap to find compiled functions, will write to log. + logger->LogCompiledFunctions(); + logger->StringEvent("test-traversal-done", ""); + + bool exists = false; + i::Vector log( + i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); + CHECK(exists); + v8::Handle log_str = v8::String::NewFromUtf8( + CcTest::isolate(), log.start(), v8::String::kNormalString, log.length()); + initialize_logger.env()->Global()->Set(v8_str("_log"), log_str); + + i::Vector source = TestSources::GetScriptsSource(); + v8::Handle source_str = v8::String::NewFromUtf8( + CcTest::isolate(), reinterpret_cast(source.start()), + v8::String::kNormalString, source.length()); + v8::TryCatch try_catch; + v8::Handle script = CompileWithOrigin(source_str, ""); + if (script.IsEmpty()) { + v8::String::Utf8Value exception(try_catch.Exception()); + printf("compile: %s\n", *exception); + CHECK(false); + } + v8::Handle result = script->Run(); + if (result.IsEmpty()) { + v8::String::Utf8Value exception(try_catch.Exception()); + printf("run: %s\n", *exception); + CHECK(false); + } + // The result either be a "true" literal or problem description. + if (!result->IsTrue()) { + v8::Local s = result->ToString(); + i::ScopedVector data(s->Utf8Length() + 1); + CHECK_NE(NULL, data.start()); + s->WriteUtf8(data.start()); + printf("%s\n", data.start()); + // Make sure that our output is written prior crash due to CHECK failure. + fflush(stdout); + CHECK(false); } - isolate->Dispose(); } diff --git a/test/cctest/test-macro-assembler-arm.cc b/test/cctest/test-macro-assembler-arm.cc index 3ca0266..2cfad0d 100644 --- a/test/cctest/test-macro-assembler-arm.cc +++ b/test/cctest/test-macro-assembler-arm.cc @@ -137,6 +137,8 @@ typedef int (*F5)(void*, void*, void*, void*, void*); TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( diff --git a/test/cctest/test-macro-assembler-ia32.cc b/test/cctest/test-macro-assembler-ia32.cc index b2b8c94..4d37579 100644 --- a/test/cctest/test-macro-assembler-ia32.cc +++ b/test/cctest/test-macro-assembler-ia32.cc @@ -50,6 +50,8 @@ typedef F0Type* F0; TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc index 7f20a8d..2c0e918 100644 --- a/test/cctest/test-macro-assembler-x64.cc +++ b/test/cctest/test-macro-assembler-x64.cc @@ -153,6 +153,7 @@ static void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) { // Test that we can move a Smi value literally into a register. TEST(SmiMove) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -238,6 +239,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) { // Test that we can compare smis for equality (and more). TEST(SmiCompare) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -286,6 +288,7 @@ TEST(SmiCompare) { TEST(Integer32ToSmi) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -412,6 +415,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm, TEST(Integer64PlusConstantToSmi) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -454,6 +458,7 @@ TEST(Integer64PlusConstantToSmi) { TEST(SmiCheck) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -699,6 +704,7 @@ void TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiNeg) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -912,6 +918,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm, TEST(SmiAdd) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1130,6 +1137,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm, TEST(SmiSub) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1218,6 +1226,7 @@ void TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiMul) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1321,6 +1330,7 @@ void TestSmiDiv(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiDiv) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1428,6 +1438,7 @@ void TestSmiMod(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiMod) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1522,6 +1533,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiIndex) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1588,6 +1600,7 @@ void TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiSelectNonSmi) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1664,6 +1677,7 @@ void TestSmiAnd(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiAnd) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1742,6 +1756,7 @@ void TestSmiOr(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiOr) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1822,6 +1837,7 @@ void TestSmiXor(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiXor) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1886,6 +1902,7 @@ void TestSmiNot(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiNot) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -1979,6 +1996,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiShiftLeft) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -2082,6 +2100,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm, TEST(SmiShiftLogicalRight) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -2148,6 +2167,7 @@ void TestSmiShiftArithmeticRight(MacroAssembler* masm, TEST(SmiShiftArithmeticRight) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -2209,6 +2229,7 @@ void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) { TEST(PositiveSmiTimesPowerOfTwoToInteger64) { + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( @@ -2246,6 +2267,7 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) { TEST(OperandOffset) { + i::V8::Initialize(NULL); uint32_t data[256]; for (uint32_t i = 0; i < 256; i++) { data[i] = i * 0x01010101; } @@ -2599,6 +2621,8 @@ TEST(OperandOffset) { TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( diff --git a/test/cctest/test-macro-assembler-x87.cc b/test/cctest/test-macro-assembler-x87.cc index 0b057d8..9aa40c0 100644 --- a/test/cctest/test-macro-assembler-x87.cc +++ b/test/cctest/test-macro-assembler-x87.cc @@ -50,6 +50,8 @@ typedef F0Type* F0; TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast(v8::base::OS::Allocate( diff --git a/test/cctest/test-random-number-generator.cc b/test/cctest/test-random-number-generator.cc index 04b5882..d2e67c7 100644 --- a/test/cctest/test-random-number-generator.cc +++ b/test/cctest/test-random-number-generator.cc @@ -34,16 +34,28 @@ using namespace v8::internal; -static const int64_t kRandomSeeds[] = {-1, 1, 42, 100, 1234567890, 987654321}; +static const int kMaxRuns = 12345; +static const int kRandomSeeds[] = { + -1, 1, 42, 100, 1234567890, 987654321 +}; TEST(RandomSeedFlagIsUsed) { for (unsigned n = 0; n < arraysize(kRandomSeeds); ++n) { - FLAG_random_seed = static_cast(kRandomSeeds[n]); + FLAG_random_seed = kRandomSeeds[n]; v8::Isolate* i = v8::Isolate::New(); - v8::base::RandomNumberGenerator& rng = + v8::base::RandomNumberGenerator& rng1 = *reinterpret_cast(i)->random_number_generator(); - CHECK_EQ(kRandomSeeds[n], rng.initial_seed()); + v8::base::RandomNumberGenerator rng2(kRandomSeeds[n]); + for (int k = 1; k <= kMaxRuns; ++k) { + int64_t i1, i2; + rng1.NextBytes(&i1, sizeof(i1)); + rng2.NextBytes(&i2, sizeof(i2)); + CHECK_EQ(i2, i1); + CHECK_EQ(rng2.NextInt(), rng1.NextInt()); + CHECK_EQ(rng2.NextInt(k), rng1.NextInt(k)); + CHECK_EQ(rng2.NextDouble(), rng1.NextDouble()); + } i->Dispose(); } } diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc index b22b348..801e4b3 100644 --- a/test/cctest/test-regexp.cc +++ b/test/cctest/test-regexp.cc @@ -85,6 +85,7 @@ using namespace v8::internal; static bool CheckParse(const char* input) { + V8::Initialize(NULL); v8::HandleScope scope(CcTest::isolate()); Zone zone(CcTest::i_isolate()); FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); @@ -95,6 +96,7 @@ static bool CheckParse(const char* input) { static void CheckParseEq(const char* input, const char* expected) { + V8::Initialize(NULL); v8::HandleScope scope(CcTest::isolate()); Zone zone(CcTest::i_isolate()); FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); @@ -110,6 +112,7 @@ static void CheckParseEq(const char* input, const char* expected) { static bool CheckSimple(const char* input) { + V8::Initialize(NULL); v8::HandleScope scope(CcTest::isolate()); Zone zone(CcTest::i_isolate()); FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); @@ -128,6 +131,7 @@ struct MinMaxPair { static MinMaxPair CheckMinMaxMatch(const char* input) { + V8::Initialize(NULL); v8::HandleScope scope(CcTest::isolate()); Zone zone(CcTest::i_isolate()); FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); @@ -152,6 +156,8 @@ static MinMaxPair CheckMinMaxMatch(const char* input) { } TEST(Parser) { + V8::Initialize(NULL); + CHECK_PARSE_ERROR("?"); CheckParseEq("abc", "'abc'"); @@ -401,6 +407,7 @@ TEST(ParserRegression) { static void ExpectError(const char* input, const char* expected) { + V8::Initialize(NULL); v8::HandleScope scope(CcTest::isolate()); Zone zone(CcTest::i_isolate()); FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); @@ -487,6 +494,7 @@ static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) { TEST(CharacterClassEscapes) { + v8::internal::V8::Initialize(NULL); TestCharacterClassEscapes('.', IsRegExpNewline); TestCharacterClassEscapes('d', IsDigit); TestCharacterClassEscapes('D', NotDigit); @@ -499,6 +507,7 @@ TEST(CharacterClassEscapes) { static RegExpNode* Compile(const char* input, bool multiline, bool is_one_byte, Zone* zone) { + V8::Initialize(NULL); Isolate* isolate = CcTest::i_isolate(); FlatStringReader reader(isolate, CStrVector(input)); RegExpCompileData compile_data; @@ -555,6 +564,7 @@ static unsigned PseudoRandom(int i, int j) { TEST(SplayTreeSimple) { + v8::internal::V8::Initialize(NULL); static const unsigned kLimit = 1000; Zone zone(CcTest::i_isolate()); ZoneSplayTree tree(&zone); @@ -607,6 +617,7 @@ TEST(SplayTreeSimple) { TEST(DispatchTableConstruction) { + v8::internal::V8::Initialize(NULL); // Initialize test data. static const int kLimit = 1000; static const int kRangeCount = 8; @@ -1351,6 +1362,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) { #else // V8_INTERPRETED_REGEXP TEST(MacroAssembler) { + V8::Initialize(NULL); byte codes[1024]; Zone zone(CcTest::i_isolate()); RegExpMacroAssemblerIrregexp m(Vector(codes, 1024), &zone); @@ -1416,6 +1428,7 @@ TEST(MacroAssembler) { TEST(AddInverseToTable) { + v8::internal::V8::Initialize(NULL); static const int kLimit = 1000; static const int kRangeCount = 16; for (int t = 0; t < 10; t++) { @@ -1575,6 +1588,7 @@ static void TestSimpleRangeCaseIndependence(CharacterRange input, TEST(CharacterRangeCaseIndependence) { + v8::internal::V8::Initialize(NULL); TestSimpleRangeCaseIndependence(CharacterRange::Singleton('a'), CharacterRange::Singleton('A')); TestSimpleRangeCaseIndependence(CharacterRange::Singleton('z'), @@ -1616,6 +1630,7 @@ static bool InClass(uc16 c, ZoneList* ranges) { TEST(CharClassDifference) { + v8::internal::V8::Initialize(NULL); Zone zone(CcTest::i_isolate()); ZoneList* base = new(&zone) ZoneList(1, &zone); @@ -1643,6 +1658,7 @@ TEST(CharClassDifference) { TEST(CanonicalizeCharacterSets) { + v8::internal::V8::Initialize(NULL); Zone zone(CcTest::i_isolate()); ZoneList* list = new(&zone) ZoneList(4, &zone); @@ -1704,6 +1720,7 @@ TEST(CanonicalizeCharacterSets) { TEST(CharacterRangeMerge) { + v8::internal::V8::Initialize(NULL); Zone zone(CcTest::i_isolate()); ZoneList l1(4, &zone); ZoneList l2(4, &zone); @@ -1791,5 +1808,6 @@ TEST(CharacterRangeMerge) { TEST(Graph) { + V8::Initialize(NULL); Execute("\\b\\w+\\b", false, true, true); } diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc index 01cc77a..5431e0b 100644 --- a/test/cctest/test-serialize.cc +++ b/test/cctest/test-serialize.cc @@ -45,6 +45,42 @@ using namespace v8::internal; +static const unsigned kCounters = 256; +static int local_counters[kCounters]; +static const char* local_counter_names[kCounters]; + + +static unsigned CounterHash(const char* s) { + unsigned hash = 0; + while (*++s) { + hash |= hash << 5; + hash += *s; + } + return hash; +} + + +// Callback receiver to track counters in test. +static int* counter_function(const char* name) { + unsigned hash = CounterHash(name) % kCounters; + unsigned original_hash = hash; + USE(original_hash); + while (true) { + if (local_counter_names[hash] == name) { + return &local_counters[hash]; + } + if (local_counter_names[hash] == 0) { + local_counter_names[hash] = name; + return &local_counters[hash]; + } + if (strcmp(local_counter_names[hash], name) == 0) { + return &local_counters[hash]; + } + hash = (hash + 1) % kCounters; + DCHECK(hash != original_hash); // Hash table has been filled up. + } +} + template static Address AddressOf(T id) { @@ -65,6 +101,7 @@ static int make_code(TypeCode type, int id) { TEST(ExternalReferenceEncoder) { Isolate* isolate = CcTest::i_isolate(); + isolate->stats_table()->SetCounterFunction(counter_function); v8::V8::Initialize(); ExternalReferenceEncoder encoder(isolate); @@ -72,6 +109,10 @@ TEST(ExternalReferenceEncoder) { Encode(encoder, Builtins::kArrayCode)); CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort), Encode(encoder, Runtime::kAbort)); + ExternalReference total_compile_size = + ExternalReference(isolate->counters()->total_compile_size()); + CHECK_EQ(make_code(STATS_COUNTER, Counters::k_total_compile_size), + encoder.Encode(total_compile_size.address())); ExternalReference stack_limit_address = ExternalReference::address_of_stack_limit(isolate); CHECK_EQ(make_code(UNCLASSIFIED, 2), @@ -95,6 +136,7 @@ TEST(ExternalReferenceEncoder) { TEST(ExternalReferenceDecoder) { Isolate* isolate = CcTest::i_isolate(); + isolate->stats_table()->SetCounterFunction(counter_function); v8::V8::Initialize(); ExternalReferenceDecoder decoder(isolate); @@ -103,6 +145,12 @@ TEST(ExternalReferenceDecoder) { CHECK_EQ(AddressOf(Runtime::kAbort), decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort))); + ExternalReference total_compile_size = + ExternalReference(isolate->counters()->total_compile_size()); + CHECK_EQ(total_compile_size.address(), + decoder.Decode( + make_code(STATS_COUNTER, + Counters::k_total_compile_size))); CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(), decoder.Decode(make_code(UNCLASSIFIED, 2))); CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(), @@ -194,41 +242,40 @@ static bool WriteToFile(Isolate* isolate, const char* snapshot_file) { } -static void Serialize(v8::Isolate* isolate) { +static void Serialize() { // We have to create one context. One reason for this is so that the builtins // can be loaded from v8natives.js and their addresses can be processed. This // will clear the pending fixups array, which would otherwise contain GC roots // that would confuse the serialization/deserialization process. + v8::Isolate* isolate = CcTest::isolate(); { v8::HandleScope scope(isolate); v8::Context::New(isolate); } - Isolate* internal_isolate = reinterpret_cast(isolate); + Isolate* internal_isolate = CcTest::i_isolate(); internal_isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "serialize"); WriteToFile(internal_isolate, FLAG_testing_serialization_file); } // Test that the whole heap can be serialized. -UNINITIALIZED_TEST(Serialize) { +TEST(Serialize) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate::CreateParams params; - params.enable_serializer = true; - v8::Isolate* isolate = v8::Isolate::New(params); - Serialize(isolate); + CcTest::i_isolate()->enable_serializer(); + v8::V8::Initialize(); + Serialize(); } } // Test that heap serialization is non-destructive. -UNINITIALIZED_TEST(SerializeTwice) { +TEST(SerializeTwice) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate::CreateParams params; - params.enable_serializer = true; - v8::Isolate* isolate = v8::Isolate::New(params); - Serialize(isolate); - Serialize(isolate); + CcTest::i_isolate()->enable_serializer(); + v8::V8::Initialize(); + Serialize(); + Serialize(); } } @@ -272,370 +319,330 @@ static void ReserveSpaceForSnapshot(Deserializer* deserializer, } -v8::Isolate* InitializeFromFile(const char* snapshot_file) { +bool InitializeFromFile(const char* snapshot_file) { int len; byte* str = ReadBytes(snapshot_file, &len); - if (!str) return NULL; - v8::Isolate* v8_isolate = NULL; + if (!str) return false; + bool success; { SnapshotByteSource source(str, len); Deserializer deserializer(&source); ReserveSpaceForSnapshot(&deserializer, snapshot_file); - Isolate* isolate = Isolate::NewForTesting(); - v8_isolate = reinterpret_cast(isolate); - v8::Isolate::Scope isolate_scope(v8_isolate); - isolate->Init(&deserializer); + success = V8::Initialize(&deserializer); } DeleteArray(str); - return v8_isolate; + return success; } -static v8::Isolate* Deserialize() { - v8::Isolate* isolate = InitializeFromFile(FLAG_testing_serialization_file); - CHECK(isolate); - return isolate; +static void Deserialize() { + CHECK(InitializeFromFile(FLAG_testing_serialization_file)); } -static void SanityCheck(v8::Isolate* v8_isolate) { - Isolate* isolate = reinterpret_cast(v8_isolate); - v8::HandleScope scope(v8_isolate); +static void SanityCheck() { + Isolate* isolate = CcTest::i_isolate(); + v8::HandleScope scope(CcTest::isolate()); #ifdef VERIFY_HEAP - isolate->heap()->Verify(); + CcTest::heap()->Verify(); #endif CHECK(isolate->global_object()->IsJSObject()); CHECK(isolate->native_context()->IsContext()); - CHECK(isolate->heap()->string_table()->IsStringTable()); + CHECK(CcTest::heap()->string_table()->IsStringTable()); isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Empty")); } -UNINITIALIZED_DEPENDENT_TEST(Deserialize, Serialize) { +DEPENDENT_TEST(Deserialize, Serialize) { // The serialize-deserialize tests only work if the VM is built without // serialization. That doesn't matter. We don't need to be able to // serialize a snapshot in a VM that is booted from a snapshot. if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = Deserialize(); - { - v8::HandleScope handle_scope(isolate); - v8::Isolate::Scope isolate_scope(isolate); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Deserialize(); - v8::Local env = v8::Context::New(isolate); - env->Enter(); + v8::Local env = v8::Context::New(isolate); + env->Enter(); - SanityCheck(isolate); - } - isolate->Dispose(); + SanityCheck(); } } -UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerialization, - SerializeTwice) { +DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = Deserialize(); - { - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Deserialize(); - v8::Local env = v8::Context::New(isolate); - env->Enter(); + v8::Local env = v8::Context::New(isolate); + env->Enter(); - SanityCheck(isolate); - } - isolate->Dispose(); + SanityCheck(); } } -UNINITIALIZED_DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { +DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = Deserialize(); - { - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Deserialize(); - v8::Local env = v8::Context::New(isolate); - env->Enter(); + v8::Local env = v8::Context::New(isolate); + env->Enter(); - const char* c_source = "\"1234\".length"; - v8::Local source = v8::String::NewFromUtf8(isolate, c_source); - v8::Local script = v8::Script::Compile(source); - CHECK_EQ(4, script->Run()->Int32Value()); - } - isolate->Dispose(); + const char* c_source = "\"1234\".length"; + v8::Local source = v8::String::NewFromUtf8(isolate, c_source); + v8::Local script = v8::Script::Compile(source); + CHECK_EQ(4, script->Run()->Int32Value()); } } -UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, - SerializeTwice) { +DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, + SerializeTwice) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = Deserialize(); - { - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Deserialize(); - v8::Local env = v8::Context::New(isolate); - env->Enter(); + v8::Local env = v8::Context::New(isolate); + env->Enter(); - const char* c_source = "\"1234\".length"; - v8::Local source = v8::String::NewFromUtf8(isolate, c_source); - v8::Local script = v8::Script::Compile(source); - CHECK_EQ(4, script->Run()->Int32Value()); - } - isolate->Dispose(); + const char* c_source = "\"1234\".length"; + v8::Local source = v8::String::NewFromUtf8(isolate, c_source); + v8::Local script = v8::Script::Compile(source); + CHECK_EQ(4, script->Run()->Int32Value()); } } -UNINITIALIZED_TEST(PartialSerialization) { +TEST(PartialSerialization) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate::CreateParams params; - params.enable_serializer = true; - v8::Isolate* v8_isolate = v8::Isolate::New(params); - Isolate* isolate = reinterpret_cast(v8_isolate); - v8_isolate->Enter(); - { - Heap* heap = isolate->heap(); + Isolate* isolate = CcTest::i_isolate(); + CcTest::i_isolate()->enable_serializer(); + v8::V8::Initialize(); + v8::Isolate* v8_isolate = reinterpret_cast(isolate); + Heap* heap = isolate->heap(); - v8::Persistent env; - { - HandleScope scope(isolate); - env.Reset(v8_isolate, v8::Context::New(v8_isolate)); - } - DCHECK(!env.IsEmpty()); - { - v8::HandleScope handle_scope(v8_isolate); - v8::Local::New(v8_isolate, env)->Enter(); - } - // Make sure all builtin scripts are cached. - { - HandleScope scope(isolate); - for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { - isolate->bootstrapper()->NativesSourceLookup(i); - } - } - heap->CollectAllGarbage(Heap::kNoGCFlags); - heap->CollectAllGarbage(Heap::kNoGCFlags); - - Object* raw_foo; - { - v8::HandleScope handle_scope(v8_isolate); - v8::Local foo = v8::String::NewFromUtf8(v8_isolate, "foo"); - DCHECK(!foo.IsEmpty()); - raw_foo = *(v8::Utils::OpenHandle(*foo)); + v8::Persistent env; + { + HandleScope scope(isolate); + env.Reset(v8_isolate, v8::Context::New(v8_isolate)); + } + DCHECK(!env.IsEmpty()); + { + v8::HandleScope handle_scope(v8_isolate); + v8::Local::New(v8_isolate, env)->Enter(); + } + // Make sure all builtin scripts are cached. + { HandleScope scope(isolate); + for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { + isolate->bootstrapper()->NativesSourceLookup(i); } + } + heap->CollectAllGarbage(Heap::kNoGCFlags); + heap->CollectAllGarbage(Heap::kNoGCFlags); - int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; - Vector startup_name = Vector::New(file_name_length + 1); - SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); + Object* raw_foo; + { + v8::HandleScope handle_scope(v8_isolate); + v8::Local foo = v8::String::NewFromUtf8(v8_isolate, "foo"); + DCHECK(!foo.IsEmpty()); + raw_foo = *(v8::Utils::OpenHandle(*foo)); + } - { - v8::HandleScope handle_scope(v8_isolate); - v8::Local::New(v8_isolate, env)->Exit(); - } - env.Reset(); - - FileByteSink startup_sink(startup_name.start()); - StartupSerializer startup_serializer(isolate, &startup_sink); - startup_serializer.SerializeStrongReferences(); - - FileByteSink partial_sink(FLAG_testing_serialization_file); - PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink); - p_ser.Serialize(&raw_foo); - startup_serializer.SerializeWeakReferences(); - - partial_sink.WriteSpaceUsed( - p_ser.CurrentAllocationAddress(NEW_SPACE), - p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), - p_ser.CurrentAllocationAddress(OLD_DATA_SPACE), - p_ser.CurrentAllocationAddress(CODE_SPACE), - p_ser.CurrentAllocationAddress(MAP_SPACE), - p_ser.CurrentAllocationAddress(CELL_SPACE), - p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); - - startup_sink.WriteSpaceUsed( - startup_serializer.CurrentAllocationAddress(NEW_SPACE), - startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE), - startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE), - startup_serializer.CurrentAllocationAddress(CODE_SPACE), - startup_serializer.CurrentAllocationAddress(MAP_SPACE), - startup_serializer.CurrentAllocationAddress(CELL_SPACE), - startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); - startup_name.Dispose(); + int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; + Vector startup_name = Vector::New(file_name_length + 1); + SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); + + { + v8::HandleScope handle_scope(v8_isolate); + v8::Local::New(v8_isolate, env)->Exit(); } - v8_isolate->Exit(); - v8_isolate->Dispose(); + env.Reset(); + + FileByteSink startup_sink(startup_name.start()); + StartupSerializer startup_serializer(isolate, &startup_sink); + startup_serializer.SerializeStrongReferences(); + + FileByteSink partial_sink(FLAG_testing_serialization_file); + PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink); + p_ser.Serialize(&raw_foo); + startup_serializer.SerializeWeakReferences(); + + partial_sink.WriteSpaceUsed( + p_ser.CurrentAllocationAddress(NEW_SPACE), + p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), + p_ser.CurrentAllocationAddress(OLD_DATA_SPACE), + p_ser.CurrentAllocationAddress(CODE_SPACE), + p_ser.CurrentAllocationAddress(MAP_SPACE), + p_ser.CurrentAllocationAddress(CELL_SPACE), + p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); + + startup_sink.WriteSpaceUsed( + startup_serializer.CurrentAllocationAddress(NEW_SPACE), + startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE), + startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE), + startup_serializer.CurrentAllocationAddress(CODE_SPACE), + startup_serializer.CurrentAllocationAddress(MAP_SPACE), + startup_serializer.CurrentAllocationAddress(CELL_SPACE), + startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); + startup_name.Dispose(); } } -UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { +DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { if (!Snapshot::HaveASnapshotToStartFrom()) { int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; Vector startup_name = Vector::New(file_name_length + 1); SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); - v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); - CHECK(v8_isolate); + CHECK(InitializeFromFile(startup_name.start())); startup_name.Dispose(); - { - v8::Isolate::Scope isolate_scope(v8_isolate); - const char* file_name = FLAG_testing_serialization_file; + const char* file_name = FLAG_testing_serialization_file; - int snapshot_size = 0; - byte* snapshot = ReadBytes(file_name, &snapshot_size); + int snapshot_size = 0; + byte* snapshot = ReadBytes(file_name, &snapshot_size); - Isolate* isolate = reinterpret_cast(v8_isolate); - Object* root; - { - SnapshotByteSource source(snapshot, snapshot_size); - Deserializer deserializer(&source); - ReserveSpaceForSnapshot(&deserializer, file_name); - deserializer.DeserializePartial(isolate, &root); - CHECK(root->IsString()); - } - HandleScope handle_scope(isolate); - Handle root_handle(root, isolate); - - - Object* root2; - { - SnapshotByteSource source(snapshot, snapshot_size); - Deserializer deserializer(&source); - ReserveSpaceForSnapshot(&deserializer, file_name); - deserializer.DeserializePartial(isolate, &root2); - CHECK(root2->IsString()); - CHECK(*root_handle == root2); - } + Isolate* isolate = CcTest::i_isolate(); + Object* root; + { + SnapshotByteSource source(snapshot, snapshot_size); + Deserializer deserializer(&source); + ReserveSpaceForSnapshot(&deserializer, file_name); + deserializer.DeserializePartial(isolate, &root); + CHECK(root->IsString()); + } + HandleScope handle_scope(isolate); + Handle root_handle(root, isolate); + + + Object* root2; + { + SnapshotByteSource source(snapshot, snapshot_size); + Deserializer deserializer(&source); + ReserveSpaceForSnapshot(&deserializer, file_name); + deserializer.DeserializePartial(isolate, &root2); + CHECK(root2->IsString()); + CHECK(*root_handle == root2); } - v8_isolate->Dispose(); } } -UNINITIALIZED_TEST(ContextSerialization) { +TEST(ContextSerialization) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate::CreateParams params; - params.enable_serializer = true; - v8::Isolate* v8_isolate = v8::Isolate::New(params); - Isolate* isolate = reinterpret_cast(v8_isolate); + Isolate* isolate = CcTest::i_isolate(); + CcTest::i_isolate()->enable_serializer(); + v8::V8::Initialize(); + v8::Isolate* v8_isolate = reinterpret_cast(isolate); Heap* heap = isolate->heap(); - { - v8::Isolate::Scope isolate_scope(v8_isolate); - v8::Persistent env; - { - HandleScope scope(isolate); - env.Reset(v8_isolate, v8::Context::New(v8_isolate)); - } - DCHECK(!env.IsEmpty()); - { - v8::HandleScope handle_scope(v8_isolate); - v8::Local::New(v8_isolate, env)->Enter(); - } - // Make sure all builtin scripts are cached. - { - HandleScope scope(isolate); - for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { - isolate->bootstrapper()->NativesSourceLookup(i); - } + v8::Persistent env; + { + HandleScope scope(isolate); + env.Reset(v8_isolate, v8::Context::New(v8_isolate)); + } + DCHECK(!env.IsEmpty()); + { + v8::HandleScope handle_scope(v8_isolate); + v8::Local::New(v8_isolate, env)->Enter(); + } + // Make sure all builtin scripts are cached. + { HandleScope scope(isolate); + for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { + 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 env. - heap->CollectAllGarbage(Heap::kNoGCFlags); - - int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; - Vector startup_name = Vector::New(file_name_length + 1); - SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); + } + // If we don't do this then we end up with a stray root pointing at the + // context even after we have disposed of env. + heap->CollectAllGarbage(Heap::kNoGCFlags); - { - v8::HandleScope handle_scope(v8_isolate); - v8::Local::New(v8_isolate, env)->Exit(); - } + int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; + Vector startup_name = Vector::New(file_name_length + 1); + SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); - i::Object* raw_context = *v8::Utils::OpenPersistent(env); - - env.Reset(); - - FileByteSink startup_sink(startup_name.start()); - StartupSerializer startup_serializer(isolate, &startup_sink); - startup_serializer.SerializeStrongReferences(); - - FileByteSink partial_sink(FLAG_testing_serialization_file); - PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink); - p_ser.Serialize(&raw_context); - startup_serializer.SerializeWeakReferences(); - - partial_sink.WriteSpaceUsed( - p_ser.CurrentAllocationAddress(NEW_SPACE), - p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), - p_ser.CurrentAllocationAddress(OLD_DATA_SPACE), - p_ser.CurrentAllocationAddress(CODE_SPACE), - p_ser.CurrentAllocationAddress(MAP_SPACE), - p_ser.CurrentAllocationAddress(CELL_SPACE), - p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); - - startup_sink.WriteSpaceUsed( - startup_serializer.CurrentAllocationAddress(NEW_SPACE), - startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE), - startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE), - startup_serializer.CurrentAllocationAddress(CODE_SPACE), - startup_serializer.CurrentAllocationAddress(MAP_SPACE), - startup_serializer.CurrentAllocationAddress(CELL_SPACE), - startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); - startup_name.Dispose(); + { + v8::HandleScope handle_scope(v8_isolate); + v8::Local::New(v8_isolate, env)->Exit(); } - v8_isolate->Dispose(); + + i::Object* raw_context = *v8::Utils::OpenPersistent(env); + + env.Reset(); + + FileByteSink startup_sink(startup_name.start()); + StartupSerializer startup_serializer(isolate, &startup_sink); + startup_serializer.SerializeStrongReferences(); + + FileByteSink partial_sink(FLAG_testing_serialization_file); + PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink); + p_ser.Serialize(&raw_context); + startup_serializer.SerializeWeakReferences(); + + partial_sink.WriteSpaceUsed( + p_ser.CurrentAllocationAddress(NEW_SPACE), + p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), + p_ser.CurrentAllocationAddress(OLD_DATA_SPACE), + p_ser.CurrentAllocationAddress(CODE_SPACE), + p_ser.CurrentAllocationAddress(MAP_SPACE), + p_ser.CurrentAllocationAddress(CELL_SPACE), + p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); + + startup_sink.WriteSpaceUsed( + startup_serializer.CurrentAllocationAddress(NEW_SPACE), + startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE), + startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE), + startup_serializer.CurrentAllocationAddress(CODE_SPACE), + startup_serializer.CurrentAllocationAddress(MAP_SPACE), + startup_serializer.CurrentAllocationAddress(CELL_SPACE), + startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE)); + startup_name.Dispose(); } } -UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { +DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { if (!Snapshot::HaveASnapshotToStartFrom()) { int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; Vector startup_name = Vector::New(file_name_length + 1); SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); - v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); - CHECK(v8_isolate); + CHECK(InitializeFromFile(startup_name.start())); startup_name.Dispose(); - { - v8::Isolate::Scope isolate_scope(v8_isolate); - const char* file_name = FLAG_testing_serialization_file; + const char* file_name = FLAG_testing_serialization_file; - int snapshot_size = 0; - byte* snapshot = ReadBytes(file_name, &snapshot_size); + int snapshot_size = 0; + byte* snapshot = ReadBytes(file_name, &snapshot_size); - Isolate* isolate = reinterpret_cast(v8_isolate); - Object* root; - { - SnapshotByteSource source(snapshot, snapshot_size); - Deserializer deserializer(&source); - ReserveSpaceForSnapshot(&deserializer, file_name); - deserializer.DeserializePartial(isolate, &root); - CHECK(root->IsContext()); - } - HandleScope handle_scope(isolate); - Handle root_handle(root, isolate); - - - Object* root2; - { - SnapshotByteSource source(snapshot, snapshot_size); - Deserializer deserializer(&source); - ReserveSpaceForSnapshot(&deserializer, file_name); - deserializer.DeserializePartial(isolate, &root2); - CHECK(root2->IsContext()); - CHECK(*root_handle != root2); - } + Isolate* isolate = CcTest::i_isolate(); + Object* root; + { + SnapshotByteSource source(snapshot, snapshot_size); + Deserializer deserializer(&source); + ReserveSpaceForSnapshot(&deserializer, file_name); + deserializer.DeserializePartial(isolate, &root); + CHECK(root->IsContext()); + } + HandleScope handle_scope(isolate); + Handle root_handle(root, isolate); + + + Object* root2; + { + SnapshotByteSource source(snapshot, snapshot_size); + Deserializer deserializer(&source); + ReserveSpaceForSnapshot(&deserializer, file_name); + deserializer.DeserializePartial(isolate, &root2); + CHECK(root2->IsContext()); + CHECK(*root_handle != root2); } - v8_isolate->Dispose(); } } @@ -792,6 +799,7 @@ TEST(SerializeToplevelIsolates) { v8::ScriptCompiler::CachedData* cache; v8::Isolate* isolate1 = v8::Isolate::New(); + v8::Isolate* isolate2 = v8::Isolate::New(); { v8::Isolate::Scope iscope(isolate1); v8::HandleScope scope(isolate1); @@ -815,7 +823,6 @@ TEST(SerializeToplevelIsolates) { } isolate1->Dispose(); - v8::Isolate* isolate2 = v8::Isolate::New(); { v8::Isolate::Scope iscope(isolate2); v8::HandleScope scope(isolate2); diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc index d09c128..27ebc76 100644 --- a/test/cctest/test-spaces.cc +++ b/test/cctest/test-spaces.cc @@ -205,7 +205,9 @@ static void VerifyMemoryChunk(Isolate* isolate, TEST(Regress3540) { Isolate* isolate = CcTest::i_isolate(); + isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); CHECK( memory_allocator->SetUp(heap->MaxReserved(), heap->MaxExecutableSize())); @@ -239,7 +241,9 @@ static unsigned int Pseudorandom() { TEST(MemoryChunk) { Isolate* isolate = CcTest::i_isolate(); + isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); size_t reserve_area_size = 1 * MB; size_t initial_commit_area_size, second_commit_area_size; @@ -293,7 +297,9 @@ TEST(MemoryChunk) { TEST(MemoryAllocator) { Isolate* isolate = CcTest::i_isolate(); + isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); + CHECK(isolate->heap()->ConfigureHeapDefault()); MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); CHECK(memory_allocator->SetUp(heap->MaxReserved(), @@ -340,7 +346,9 @@ TEST(MemoryAllocator) { TEST(NewSpace) { Isolate* isolate = CcTest::i_isolate(); + isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); CHECK(memory_allocator->SetUp(heap->MaxReserved(), heap->MaxExecutableSize())); @@ -366,7 +374,9 @@ TEST(NewSpace) { TEST(OldSpace) { Isolate* isolate = CcTest::i_isolate(); + isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); CHECK(memory_allocator->SetUp(heap->MaxReserved(), heap->MaxExecutableSize())); diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status index 02cca86..bba86bd 100644 --- a/test/mjsunit/mjsunit.status +++ b/test/mjsunit/mjsunit.status @@ -367,8 +367,6 @@ # Currently always deopt on minus zero 'math-floor-of-div-minus-zero': [SKIP], - 'math-floor-of-div-nosudiv': [SKIP], - ############################################################################ # Slow tests. 'regress/regress-2185-2': [PASS, SLOW], diff --git a/tools/lexer-shell.cc b/tools/lexer-shell.cc index f8ddc02..cbd3524 100644 --- a/tools/lexer-shell.cc +++ b/tools/lexer-shell.cc @@ -180,11 +180,10 @@ v8::base::TimeDelta ProcessFile( int main(int argc, char* argv[]) { - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::V8::InitializeICU(); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); + v8::V8::SetFlagsFromCommandLine(&argc, argv, true); Encoding encoding = LATIN1; bool print_tokens = false; std::vector fnames; diff --git a/tools/parser-shell.cc b/tools/parser-shell.cc index 2cafc83..ce18e38 100644 --- a/tools/parser-shell.cc +++ b/tools/parser-shell.cc @@ -123,11 +123,10 @@ std::pair RunBaselineParser( int main(int argc, char* argv[]) { - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::V8::InitializeICU(); v8::Platform* platform = v8::platform::CreateDefaultPlatform(); v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); + v8::V8::SetFlagsFromCommandLine(&argc, argv, true); Encoding encoding = LATIN1; std::vector fnames; std::string benchmark; -- 2.7.4