diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2013-11-10 02:02:27 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2013-11-11 02:40:36 +0100 |
commit | f230a1cf749e984439b5bb9729d9db9f48472827 (patch) | |
tree | 153596de2251b717ad79823f23fabf4c140d6d35 /deps/v8/test | |
parent | a12870c823b9b67110b27a470fcac342cf1dfbd6 (diff) | |
download | node-new-f230a1cf749e984439b5bb9729d9db9f48472827.tar.gz |
v8: upgrade to 3.22.24
This commit removes the simple/test-event-emitter-memory-leak test for
being unreliable with the new garbage collector: the memory pressure
exerted by the test case is too low for the garbage collector to kick
in. It can be made to work again by limiting the heap size with the
--max_old_space_size=x flag but that won't be very reliable across
platforms and architectures.
Diffstat (limited to 'deps/v8/test')
136 files changed, 8354 insertions, 4003 deletions
diff --git a/deps/v8/test/benchmarks/benchmarks.status b/deps/v8/test/benchmarks/benchmarks.status index 651b8d7ad1..103eaeb126 100644 --- a/deps/v8/test/benchmarks/benchmarks.status +++ b/deps/v8/test/benchmarks/benchmarks.status @@ -25,5 +25,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Too slow in Debug mode. -octane/mandreel: PASS, SKIP if $mode == debug +[ +['mode == debug', { + # Too slow in Debug mode. + 'octane/mandreel': [SKIP], +}], # 'mode == debug' +] diff --git a/deps/v8/test/benchmarks/testcfg.py b/deps/v8/test/benchmarks/testcfg.py index 5fb3f51c75..b15553a861 100644 --- a/deps/v8/test/benchmarks/testcfg.py +++ b/deps/v8/test/benchmarks/testcfg.py @@ -172,7 +172,7 @@ class BenchmarksTestSuite(testsuite.TestSuite): os.chdir(old_cwd) - def VariantFlags(self): + def VariantFlags(self, testcase, default_flags): # Both --nocrankshaft and --stressopt are very slow. return [[]] diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index 616c6a3a6b..4aa9c7eb71 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -29,13 +29,20 @@ #include "cctest.h" #include "debug.h" +enum InitializationState {kUnset, kUnintialized, kInitialized}; +static InitializationState initialization_state_ = kUnset; +static bool disable_automatic_dispose_ = false; CcTest* CcTest::last_ = NULL; +bool CcTest::initialize_called_ = false; +bool CcTest::isolate_used_ = false; +v8::Isolate* CcTest::isolate_ = NULL; CcTest::CcTest(TestFunction* callback, const char* file, const char* name, - const char* dependency, bool enabled) - : callback_(callback), name_(name), dependency_(dependency), prev_(last_) { + const char* dependency, bool enabled, bool initialize) + : callback_(callback), name_(name), dependency_(dependency), + enabled_(enabled), initialize_(initialize), prev_(last_) { // Find the base name of this test (const_cast required on Windows). char *basename = strrchr(const_cast<char *>(file), '/'); if (!basename) { @@ -51,35 +58,49 @@ CcTest::CcTest(TestFunction* callback, const char* file, const char* name, if (extension) *extension = 0; // Install this test in the list of tests file_ = basename; - enabled_ = enabled; prev_ = last_; last_ = this; } -v8::Persistent<v8::Context> CcTest::context_; +void CcTest::Run() { + if (!initialize_) { + CHECK(initialization_state_ != kInitialized); + initialization_state_ = kUnintialized; + CHECK(CcTest::isolate_ == NULL); + } else { + CHECK(initialization_state_ != kUnintialized); + initialization_state_ = kInitialized; + if (isolate_ == NULL) { + isolate_ = v8::Isolate::New(); + } + isolate_->Enter(); + } + callback_(); + if (initialize_) { + isolate_->Exit(); + } +} -void CcTest::InitializeVM(CcTestExtensionFlags extensions) { - const char* extension_names[kMaxExtensions]; - int extension_count = 0; -#define CHECK_EXTENSION_FLAG(Name, Id) \ - if (extensions.Contains(Name##_ID)) extension_names[extension_count++] = Id; - EXTENSION_LIST(CHECK_EXTENSION_FLAG) -#undef CHECK_EXTENSION_FLAG - v8::Isolate* isolate = default_isolate(); - if (context_.IsEmpty()) { - v8::HandleScope scope(isolate); +v8::Local<v8::Context> CcTest::NewContext(CcTestExtensionFlags extensions, + v8::Isolate* isolate) { + const char* extension_names[kMaxExtensions]; + int extension_count = 0; + #define CHECK_EXTENSION_FLAG(Name, Id) \ + if (extensions.Contains(Name##_ID)) extension_names[extension_count++] = Id; + EXTENSION_LIST(CHECK_EXTENSION_FLAG) + #undef CHECK_EXTENSION_FLAG v8::ExtensionConfiguration config(extension_count, extension_names); v8::Local<v8::Context> context = v8::Context::New(isolate, &config); - context_.Reset(isolate, context); - } - { - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = - v8::Local<v8::Context>::New(isolate, context_); - context->Enter(); - } + CHECK(!context.IsEmpty()); + return context; +} + + +void CcTest::DisableAutomaticDispose() { + CHECK_EQ(kUnintialized, initialization_state_); + disable_automatic_dispose_ = true; } @@ -95,9 +116,6 @@ static void PrintTestList(CcTest* current) { } -v8::Isolate* CcTest::default_isolate_; - - class CcTestArrayBufferAllocator : public v8::ArrayBuffer::Allocator { virtual void* Allocate(size_t length) { return malloc(length); } virtual void* AllocateUninitialized(size_t length) { return malloc(length); } @@ -115,13 +133,14 @@ static void SuggestTestHarness(int tests) { int main(int argc, char* argv[]) { + v8::V8::InitializeICU(); + i::Isolate::SetCrashIfDefaultIsolateInitialized(); + v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true); CcTestArrayBufferAllocator array_buffer_allocator; v8::V8::SetArrayBufferAllocator(&array_buffer_allocator); - CcTest::set_default_isolate(v8::Isolate::GetCurrent()); - CHECK(CcTest::default_isolate() != NULL); int tests_run = 0; bool print_run_count = true; for (int i = 1; i < argc; i++) { @@ -169,7 +188,7 @@ int main(int argc, char* argv[]) { } if (print_run_count && tests_run != 1) printf("Ran %i tests.\n", tests_run); - v8::V8::Dispose(); + if (!disable_automatic_dispose_) v8::V8::Dispose(); return 0; } diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp index ee7ffad6d3..fbe38f2709 100644 --- a/deps/v8/test/cctest/cctest.gyp +++ b/deps/v8/test/cctest/cctest.gyp @@ -56,6 +56,7 @@ 'test-circular-queue.cc', 'test-compiler.cc', 'test-condition-variable.cc', + 'test-constantpool.cc', 'test-conversions.cc', 'test-cpu.cc', 'test-cpu-profiler.cc', @@ -139,13 +140,15 @@ 'test-assembler-arm.cc', 'test-code-stubs.cc', 'test-code-stubs-arm.cc', - 'test-disasm-arm.cc' + 'test-disasm-arm.cc', + 'test-macro-assembler-arm.cc' ], }], ['v8_target_arch=="mipsel"', { 'sources': [ 'test-assembler-mips.cc', 'test-disasm-mips.cc', + 'test-macro-assembler-mips.cc' ], }], [ 'OS=="linux"', { diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h index ceb97743eb..7f84c259f0 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -31,23 +31,30 @@ #include "v8.h" #ifndef TEST -#define TEST(Name) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true); \ +#define TEST(Name) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, true); \ + static void Test##Name() +#endif + +#ifndef UNINITIALIZED_TEST +#define UNINITIALIZED_TEST(Name) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, false); \ static void Test##Name() #endif #ifndef DEPENDENT_TEST -#define DEPENDENT_TEST(Name, Dep) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true); \ +#define DEPENDENT_TEST(Name, Dep) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true, true); \ static void Test##Name() #endif #ifndef DISABLED_TEST -#define DISABLED_TEST(Name) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, false); \ +#define DISABLED_TEST(Name) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, false, true); \ static void Test##Name() #endif @@ -71,51 +78,70 @@ typedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags; EXTENSION_LIST(DEFINE_EXTENSION_FLAG) #undef DEFINE_EXTENSION_FLAG -// Temporary macros for accessing current isolate and its subobjects. -// They provide better readability, especially when used a lot in the code. -#define HEAP (v8::internal::Isolate::Current()->heap()) class CcTest { public: typedef void (TestFunction)(); CcTest(TestFunction* callback, const char* file, const char* name, - const char* dependency, bool enabled); - void Run() { callback_(); } + const char* dependency, bool enabled, bool initialize); + void Run(); static CcTest* last() { return last_; } CcTest* prev() { return prev_; } const char* file() { return file_; } const char* name() { return name_; } const char* dependency() { return dependency_; } bool enabled() { return enabled_; } - static v8::Isolate* default_isolate() { return default_isolate_; } - static v8::Handle<v8::Context> env() { - return v8::Local<v8::Context>::New(default_isolate_, context_); + static v8::Isolate* isolate() { + CHECK(isolate_ != NULL); + isolate_used_ = true; + return isolate_; } - static v8::Isolate* isolate() { return default_isolate_; } - static i::Isolate* i_isolate() { - return reinterpret_cast<i::Isolate*>(default_isolate_); + return reinterpret_cast<i::Isolate*>(isolate()); + } + + static i::Heap* heap() { + return i_isolate()->heap(); + } + + static v8::Local<v8::Object> global() { + return isolate()->GetCurrentContext()->Global(); + } + + // TODO(dcarney): Remove. + // This must be called first in a test. + static void InitializeVM() { + CHECK(!isolate_used_); + CHECK(!initialize_called_); + initialize_called_ = true; + v8::HandleScope handle_scope(CcTest::isolate()); + v8::Context::New(CcTest::isolate())->Enter(); } - // Helper function to initialize the VM. - static void InitializeVM(CcTestExtensionFlags extensions = NO_EXTENSIONS); + // Only for UNINITIALIZED_TESTs + static void DisableAutomaticDispose(); + + // Helper function to configure a context. + // Must be in a HandleScope. + static v8::Local<v8::Context> NewContext( + CcTestExtensionFlags extensions, + v8::Isolate* isolate = CcTest::isolate()); private: friend int main(int argc, char** argv); - static void set_default_isolate(v8::Isolate* default_isolate) { - default_isolate_ = default_isolate; - } TestFunction* callback_; const char* file_; const char* name_; const char* dependency_; bool enabled_; + bool initialize_; CcTest* prev_; static CcTest* last_; - static v8::Isolate* default_isolate_; - static v8::Persistent<v8::Context> context_; + static v8::Isolate* isolate_; + static bool initialize_called_; + static bool isolate_used_; }; // Switches between all the Api tests using the threading support. @@ -211,20 +237,19 @@ class RegisterThreadedTest { // A LocalContext holds a reference to a v8::Context. class LocalContext { public: + LocalContext(v8::Isolate* isolate, + v8::ExtensionConfiguration* extensions = 0, + v8::Handle<v8::ObjectTemplate> global_template = + v8::Handle<v8::ObjectTemplate>(), + v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) { + Initialize(isolate, extensions, global_template, global_object); + } + LocalContext(v8::ExtensionConfiguration* extensions = 0, v8::Handle<v8::ObjectTemplate> global_template = v8::Handle<v8::ObjectTemplate>(), v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate, - extensions, - global_template, - global_object); - context_.Reset(isolate, context); - context->Enter(); - // We can't do this later perhaps because of a fatal error. - isolate_ = context->GetIsolate(); + Initialize(CcTest::isolate(), extensions, global_template, global_object); } virtual ~LocalContext() { @@ -244,6 +269,21 @@ class LocalContext { } private: + void Initialize(v8::Isolate* isolate, + v8::ExtensionConfiguration* extensions, + v8::Handle<v8::ObjectTemplate> global_template, + v8::Handle<v8::Value> global_object) { + v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = v8::Context::New(isolate, + extensions, + global_template, + global_object); + context_.Reset(isolate, context); + context->Enter(); + // We can't do this later perhaps because of a fatal error. + isolate_ = isolate; + } + v8::Persistent<v8::Context> context_; v8::Isolate* isolate_; }; @@ -308,4 +348,26 @@ static inline void SimulateFullSpace(v8::internal::PagedSpace* space) { } +// Helper class for new allocations tracking and checking. +// To use checking of JS allocations tracking in a test, +// just create an instance of this class. +class HeapObjectsTracker { + public: + HeapObjectsTracker() { + heap_profiler_ = i::Isolate::Current()->heap_profiler(); + CHECK_NE(NULL, heap_profiler_); + heap_profiler_->StartHeapAllocationsRecording(); + } + + ~HeapObjectsTracker() { + i::Isolate::Current()->heap()->CollectAllAvailableGarbage(); + CHECK_EQ(0, heap_profiler_->FindUntrackedObjects()); + heap_profiler_->StopHeapAllocationsRecording(); + } + + private: + i::HeapProfiler* heap_profiler_; +}; + + #endif // ifndef CCTEST_H_ diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index 85661098b2..59bf8268e9 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -25,107 +25,112 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -prefix cctest +[ +[ALWAYS, { + # All tests prefixed with 'Bug' are expected to fail. + 'test-api/Bug*': [FAIL], -# All tests prefixed with 'Bug' are expected to fail. -test-api/Bug*: FAIL + ############################################################################## + # BUG(382): Weird test. Can't guarantee that it never times out. + 'test-api/ApplyInterruption': [PASS, TIMEOUT], -############################################################################## -# BUG(382): Weird test. Can't guarantee that it never times out. -test-api/ApplyInterruption: PASS || TIMEOUT - -# TODO(mstarzinger): Fail gracefully on multiple V8::Dispose calls. -test-api/InitializeAndDisposeOnce: SKIP -test-api/InitializeAndDisposeMultiple: SKIP + # TODO(mstarzinger): Fail gracefully on multiple V8::Dispose calls. + 'test-api/InitializeAndDisposeOnce': [SKIP], + 'test-api/InitializeAndDisposeMultiple': [SKIP], -# These tests always fail. They are here to test test.py. If -# they don't fail then test.py has failed. -test-serialize/TestThatAlwaysFails: FAIL -test-serialize/DependentTestThatAlwaysFails: FAIL + # These tests always fail. They are here to test test.py. If + # they don't fail then test.py has failed. + 'test-serialize/TestThatAlwaysFails': [FAIL], + 'test-serialize/DependentTestThatAlwaysFails': [FAIL], -# This test always fails. It tests that LiveEdit causes abort when turned off. -test-debug/LiveEditDisabled: FAIL + # This test always fails. It tests that LiveEdit causes abort when turned off. + 'test-debug/LiveEditDisabled': [FAIL], -# TODO(gc): Temporarily disabled in the GC branch. -test-log/EquivalenceOfLoggingAndTraversal: PASS || FAIL + # TODO(gc): Temporarily disabled in the GC branch. + 'test-log/EquivalenceOfLoggingAndTraversal': [PASS, FAIL], -# We do not yet shrink weak maps after they have been emptied by the GC -test-weakmaps/Shrinking: FAIL -test-weaksets/WeakSet_Shrinking: FAIL + # We do not yet shrink weak maps after they have been emptied by the GC + 'test-weakmaps/Shrinking': [FAIL], + 'test-weaksets/WeakSet_Shrinking': [FAIL], -# Boot up memory use is bloated in debug mode. -test-mark-compact/BootUpMemoryUse: PASS, PASS || FAIL if $mode == debug + # Boot up memory use is bloated in debug mode. + 'test-mark-compact/BootUpMemoryUse': [PASS, PASS, ['mode == debug', FAIL]], -# Some CPU profiler tests are flaky. -test-cpu-profiler/*: PASS || FLAKY + # This tests only that the preparser and parser agree, so there is no point in + # running several variants. Note that this still takes ages, because there + # are actually 13 * 38 * 5 * 128 = 316160 individual tests hidden here. + 'test-parsing/ParserSync': [PASS, NO_VARIANTS], +}], # ALWAYS ############################################################################## -[ $arch == arm ] - -# We cannot assume that we can throw OutOfMemory exceptions in all situations. -# Apparently our ARM box is in such a state. Skip the test as it also runs for -# a long time. -test-api/OutOfMemory: SKIP -test-api/OutOfMemoryNested: SKIP - -# BUG(355): Test crashes on ARM. -test-log/ProfLazyMode: SKIP - -# BUG(1075): Unresolved crashes. -test-serialize/Deserialize: SKIP -test-serialize/DeserializeFromSecondSerializationAndRunScript2: SKIP -test-serialize/DeserializeAndRunScript2: SKIP -test-serialize/DeserializeFromSecondSerialization: SKIP - -# BUG(2874): Threading problems. -test-api/*: PASS || FLAKY +['arch == arm', { + + # We cannot assume that we can throw OutOfMemory exceptions in all situations. + # Apparently our ARM box is in such a state. Skip the test as it also runs for + # a long time. + 'test-api/OutOfMemory': [SKIP], + 'test-api/OutOfMemoryNested': [SKIP], + + # BUG(355): Test crashes on ARM. + 'test-log/ProfLazyMode': [SKIP], + + # BUG(1075): Unresolved crashes. + 'test-serialize/Deserialize': [SKIP], + 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP], + 'test-serialize/DeserializeAndRunScript2': [SKIP], + 'test-serialize/DeserializeFromSecondSerialization': [SKIP], +}], # 'arch == arm' ############################################################################## -[ $arch == mipsel ] +['arch == mipsel', { -# BUG(2657): Test sometimes times out on MIPS simulator. -test-thread-termination/TerminateMultipleV8ThreadsDefaultIsolate: PASS || TIMEOUT + # BUG(2657): Test sometimes times out on MIPS simulator. + 'test-thread-termination/TerminateMultipleV8ThreadsDefaultIsolate': [PASS, TIMEOUT], -# BUG(1075): Unresolved crashes on MIPS also. -test-serialize/Deserialize: SKIP -test-serialize/DeserializeFromSecondSerializationAndRunScript2: SKIP -test-serialize/DeserializeAndRunScript2: SKIP -test-serialize/DeserializeFromSecondSerialization: SKIP + # BUG(1075): Unresolved crashes on MIPS also. + 'test-serialize/Deserialize': [SKIP], + 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP], + 'test-serialize/DeserializeAndRunScript2': [SKIP], + 'test-serialize/DeserializeFromSecondSerialization': [SKIP], +}], # 'arch == mipsel' ############################################################################## -[ $arch == android_arm || $arch == android_ia32 ] +['arch == android_arm or arch == android_ia32', { -# Tests crash as there is no /tmp directory in Android. -test-log/LogAccessorCallbacks: SKIP -test-log/LogCallbacks: SKIP -test-log/ProfLazyMode: SKIP + # Tests crash as there is no /tmp directory in Android. + 'test-log/LogAccessorCallbacks': [SKIP], + 'test-log/LogCallbacks': [SKIP], + 'test-log/ProfLazyMode': [SKIP], -# platform-tls.h does not contain an ANDROID-related header. -test-platform-tls/FastTLS: SKIP + # platform-tls.h does not contain an ANDROID-related header. + 'test-platform-tls/FastTLS': [SKIP], -# This test times out. -test-threads/ThreadJoinSelf: SKIP + # This test times out. + 'test-threads/ThreadJoinSelf': [SKIP], +}], # 'arch == android_arm or arch == android_ia32' ############################################################################## -[ $arch == nacl_ia32 || $arch == nacl_x64 ] - -# NaCl builds have problems with threaded tests since Pepper_28. -# V8 Issue 2786 -test-api/Threading1: SKIP -test-lockers/MultithreadedParallelIsolates: SKIP -test-lockers/ExtensionsRegistration: SKIP - -# These tests fail as there is no /tmp directory in Native Client. -test-log/LogAccessorCallbacks: SKIP -test-log/LogCallbacks: SKIP -test-log/ProfLazyMode: SKIP - -# Native Client doesn't support sockets. -test-debug/DebuggerAgent: SKIP -test-debug/DebuggerAgentProtocolOverflowHeader: SKIP -test-socket/Socket: SKIP - -# Profiling doesn't work on Native Client. -test-cpu-profiler/*: SKIP - -# Fails since 16322 (new test). -test-code-stubs-arm/ConvertDToI: SKIP +['arch == nacl_ia32 or arch == nacl_x64', { + + # NaCl builds have problems with threaded tests since Pepper_28. + # V8 Issue 2786 + 'test-api/Threading1': [SKIP], + 'test-lockers/MultithreadedParallelIsolates': [SKIP], + 'test-lockers/ExtensionsRegistration': [SKIP], + + # These tests fail as there is no /tmp directory in Native Client. + 'test-log/LogAccessorCallbacks': [SKIP], + 'test-log/LogCallbacks': [SKIP], + 'test-log/ProfLazyMode': [SKIP], + + # Native Client doesn't support sockets. + 'test-debug/DebuggerAgent': [SKIP], + 'test-debug/DebuggerAgentProtocolOverflowHeader': [SKIP], + 'test-socket/Socket': [SKIP], + + # Profiling doesn't work on Native Client. + 'test-cpu-profiler/*': [SKIP], + + # Fails since 16322 (new test). + 'test-code-stubs-arm/ConvertDToI': [SKIP], +}], # 'arch == nacl_ia32 or arch == nacl_x64' +] diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc index 2aaac922bf..df4937ee28 100644 --- a/deps/v8/test/cctest/test-accessors.cc +++ b/deps/v8/test/cctest/test-accessors.cc @@ -120,7 +120,7 @@ THREADED_TEST(GlobalVariableAccess) { foo = 0; bar = -4; baz = 10; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetAccessor(v8_str("foo"), GetIntValue, @@ -148,7 +148,7 @@ static v8::Handle<v8::Object> x_holder; template<class Info> static void XGetter(const Info& info, int offset) { ApiTestFuzzer::Fuzz(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(x_receiver, info.This()); info.GetReturnValue().Set(v8_num(x_register[offset])); @@ -170,7 +170,7 @@ static void XGetter(const v8::FunctionCallbackInfo<v8::Value>& info) { template<class Info> static void XSetter(Local<Value> value, const Info& info, int offset) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(x_holder, info.This()); CHECK_EQ(x_holder, info.Holder()); @@ -293,7 +293,7 @@ THREADED_TEST(HandleScopePop) { obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>); v8::Handle<v8::Object> inst = obj->NewInstance(); context->Global()->Set(v8::String::New("obj"), inst); - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); int count_before = i::HandleScope::NumberOfHandles(isolate); { v8::HandleScope scope(context->GetIsolate()); @@ -310,15 +310,15 @@ THREADED_TEST(HandleScopePop) { static void CheckAccessorArgsCorrect( Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { - CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); + CHECK(info.GetIsolate() == CcTest::isolate()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); ApiTestFuzzer::Fuzz(); - CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); + CHECK(info.GetIsolate() == CcTest::isolate()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CHECK(info.GetIsolate() == CcTest::isolate()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); info.GetReturnValue().Set(17); @@ -354,7 +354,8 @@ static void EmptyGetter(Local<String> name, THREADED_TEST(EmptyResult) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data")); v8::Handle<v8::Object> inst = obj->NewInstance(); @@ -362,7 +363,7 @@ THREADED_TEST(EmptyResult) { Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); for (int i = 0; i < 10; i++) { Local<Value> result = scr->Run(); - CHECK(result == v8::Undefined()); + CHECK(result == v8::Undefined(isolate)); } } @@ -370,7 +371,8 @@ THREADED_TEST(EmptyResult) { THREADED_TEST(NoReuseRegress) { // Check that the IC generated for the one test doesn't get reused // for the other. - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); { v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data")); @@ -380,7 +382,7 @@ THREADED_TEST(NoReuseRegress) { Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); for (int i = 0; i < 2; i++) { Local<Value> result = scr->Run(); - CHECK(result == v8::Undefined()); + CHECK(result == v8::Undefined(isolate)); } } { @@ -405,14 +407,14 @@ static void ThrowingGetAccessor( Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - v8::ThrowException(v8_str("g")); + info.GetIsolate()->ThrowException(v8_str("g")); } static void ThrowingSetAccessor(Local<String> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { - v8::ThrowException(value); + info.GetIsolate()->ThrowException(value); } @@ -505,7 +507,7 @@ THREADED_TEST(StackIteration) { static void AllocateHandles(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { for (int i = 0; i < i::kHandleBlockSize + 1; i++) { - v8::Local<v8::Value>::New(name); + v8::Local<v8::Value>::New(info.GetIsolate(), name); } info.GetReturnValue().Set(v8::Integer::New(100)); } @@ -554,7 +556,7 @@ THREADED_TEST(JSONStringifyNamedInterceptorObject) { } -THREADED_TEST(CrossContextAccess) { +THREADED_TEST(AccessorPropertyCrossContext) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc index f4f13d0d83..7a5979a951 100644 --- a/deps/v8/test/cctest/test-alloc.cc +++ b/deps/v8/test/cctest/test-alloc.cc @@ -37,7 +37,7 @@ using namespace v8::internal; static MaybeObject* AllocateAfterFailures() { static int attempts = 0; if (++attempts < 3) return Failure::RetryAfterGC(); - Heap* heap = Isolate::Current()->heap(); + Heap* heap = CcTest::heap(); // New space. SimulateFullSpace(heap->new_space()); @@ -50,7 +50,7 @@ static MaybeObject* AllocateAfterFailures() { CHECK(!heap->AllocateHeapNumber(0.42)->IsFailure()); CHECK(!heap->AllocateArgumentsObject(Smi::FromInt(87), 10)->IsFailure()); Object* object = heap->AllocateJSObject( - *Isolate::Current()->object_function())->ToObjectChecked(); + *CcTest::i_isolate()->object_function())->ToObjectChecked(); CHECK(!heap->CopyJSObject(JSObject::cast(object))->IsFailure()); // Old data space. @@ -81,7 +81,7 @@ static MaybeObject* AllocateAfterFailures() { // Test that we can allocate in old pointer space and code space. SimulateFullSpace(heap->code_space()); CHECK(!heap->AllocateFixedArray(100, TENURED)->IsFailure()); - CHECK(!heap->CopyCode(Isolate::Current()->builtins()->builtin( + CHECK(!heap->CopyCode(CcTest::i_isolate()->builtins()->builtin( Builtins::kIllegal))->IsFailure()); // Return success. @@ -90,13 +90,13 @@ static MaybeObject* AllocateAfterFailures() { static Handle<Object> Test() { - CALL_HEAP_FUNCTION(Isolate::Current(), AllocateAfterFailures(), Object); + CALL_HEAP_FUNCTION(CcTest::i_isolate(), AllocateAfterFailures(), Object); } TEST(StressHandles) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Handle<v8::Context> env = v8::Context::New(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); + v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate()); env->Enter(); Handle<Object> o = Test(); CHECK(o->IsSmi() && Smi::cast(*o)->value() == 42); @@ -117,17 +117,17 @@ const AccessorDescriptor kDescriptor = { TEST(StressJS) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Handle<v8::Context> env = v8::Context::New(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); + v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate()); env->Enter(); Handle<JSFunction> function = factory->NewFunction(factory->function_string(), factory->null_value()); // Force the creation of an initial map and set the code to // something empty. factory->NewJSObject(function); - function->ReplaceCode(Isolate::Current()->builtins()->builtin( + function->ReplaceCode(CcTest::i_isolate()->builtins()->builtin( Builtins::kEmptyFunction)); // Patch the map to have an accessor for "get". Handle<Map> map(function->initial_map()); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index f4e40cdd38..d5e838ebe0 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -84,6 +84,7 @@ using ::v8::Value; } \ THREADED_TEST(Name) + void RunWithProfiler(void (*test)()) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -185,7 +186,7 @@ TEST(InitializeAndDisposeMultiple) { THREADED_TEST(Handles) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<Context> local_env; { LocalContext env; @@ -196,7 +197,7 @@ THREADED_TEST(Handles) { CHECK(!local_env.IsEmpty()); local_env->Enter(); - v8::Handle<v8::Primitive> undef = v8::Undefined(); + v8::Handle<v8::Primitive> undef = v8::Undefined(CcTest::isolate()); CHECK(!undef.IsEmpty()); CHECK(undef->IsUndefined()); @@ -210,17 +211,17 @@ THREADED_TEST(Handles) { THREADED_TEST(IsolateOfContext) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Handle<Context> env = Context::New(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); + v8::Handle<Context> env = Context::New(CcTest::isolate()); CHECK(!env->InContext()); - CHECK(env->GetIsolate() == v8::Isolate::GetCurrent()); + CHECK(env->GetIsolate() == CcTest::isolate()); env->Enter(); CHECK(env->InContext()); - CHECK(env->GetIsolate() == v8::Isolate::GetCurrent()); + CHECK(env->GetIsolate() == CcTest::isolate()); env->Exit(); CHECK(!env->InContext()); - CHECK(env->GetIsolate() == v8::Isolate::GetCurrent()); + CHECK(env->GetIsolate() == CcTest::isolate()); } @@ -383,8 +384,9 @@ THREADED_TEST(ArgumentSignature) { THREADED_TEST(HulIgennem) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::Primitive> undef = v8::Undefined(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::Primitive> undef = v8::Undefined(isolate); Local<String> undef_str = undef->ToString(); char* value = i::NewArray<char>(undef_str->Utf8Length() + 1); undef_str->WriteUtf8(value); @@ -395,7 +397,8 @@ THREADED_TEST(HulIgennem) { THREADED_TEST(Access) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); Local<v8::Object> obj = v8::Object::New(); Local<Value> foo_before = obj->Get(v8_str("foo")); CHECK(foo_before->IsUndefined()); @@ -515,11 +518,11 @@ THREADED_TEST(ScriptUsingStringResource) { CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), source->GetExternalStringResourceBase(&encoding)); CHECK_EQ(String::TWO_BYTE_ENCODING, encoding); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(0, dispose_count); } - v8::internal::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllAvailableGarbage(); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(1, dispose_count); } @@ -544,11 +547,11 @@ THREADED_TEST(ScriptUsingAsciiStringResource) { Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(0, dispose_count); } - i::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllAvailableGarbage(); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(1, dispose_count); } @@ -561,8 +564,8 @@ THREADED_TEST(ScriptMakingExternalString) { v8::HandleScope scope(env->GetIsolate()); Local<String> source = String::New(two_byte_source); // Trigger GCs so that the newly allocated string moves to old gen. - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now CHECK_EQ(source->IsExternal(), false); CHECK_EQ(source->IsExternalAscii(), false); String::Encoding encoding = String::UNKNOWN_ENCODING; @@ -575,11 +578,11 @@ THREADED_TEST(ScriptMakingExternalString) { Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(0, dispose_count); } - i::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); CHECK_EQ(1, dispose_count); } @@ -592,8 +595,8 @@ THREADED_TEST(ScriptMakingExternalAsciiString) { v8::HandleScope scope(env->GetIsolate()); Local<String> source = v8_str(c_source); // Trigger GCs so that the newly allocated string moves to old gen. - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now bool success = source->MakeExternal( new TestAsciiResource(i::StrDup(c_source), &dispose_count)); CHECK(success); @@ -601,11 +604,11 @@ THREADED_TEST(ScriptMakingExternalAsciiString) { Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(0, dispose_count); } - i::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); CHECK_EQ(1, dispose_count); } @@ -615,8 +618,8 @@ TEST(MakingExternalStringConditions) { v8::HandleScope scope(env->GetIsolate()); // Free some space in the new space so that we can check freshness. - HEAP->CollectGarbage(i::NEW_SPACE); - HEAP->CollectGarbage(i::NEW_SPACE); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); uint16_t* two_byte_string = AsciiToTwoByteString("s1"); Local<String> small_string = String::New(two_byte_string); @@ -625,8 +628,8 @@ TEST(MakingExternalStringConditions) { // We should refuse to externalize newly created small string. CHECK(!small_string->CanMakeExternal()); // Trigger GCs so that the newly allocated string moves to old gen. - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now // Old space strings should be accepted. CHECK(small_string->CanMakeExternal()); @@ -661,15 +664,15 @@ TEST(MakingExternalAsciiStringConditions) { v8::HandleScope scope(env->GetIsolate()); // Free some space in the new space so that we can check freshness. - HEAP->CollectGarbage(i::NEW_SPACE); - HEAP->CollectGarbage(i::NEW_SPACE); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); Local<String> small_string = String::New("s1"); // We should refuse to externalize newly created small string. CHECK(!small_string->CanMakeExternal()); // Trigger GCs so that the newly allocated string moves to old gen. - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now // Old space strings should be accepted. CHECK(small_string->CanMakeExternal()); @@ -707,9 +710,9 @@ TEST(MakingExternalUnalignedAsciiString) { "slice('abcdefghijklmnopqrstuvwxyz');")); // Trigger GCs so that the newly allocated string moves to old gen. - SimulateFullSpace(HEAP->old_pointer_space()); - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + SimulateFullSpace(CcTest::heap()->old_pointer_space()); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now // Turn into external string with unaligned resource data. int dispose_count = 0; @@ -723,48 +726,48 @@ TEST(MakingExternalUnalignedAsciiString) { CHECK(success); // Trigger GCs and force evacuation. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - HEAP->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask); } THREADED_TEST(UsingExternalString) { - i::Factory* factory = i::Isolate::Current()->factory(); + i::Factory* factory = CcTest::i_isolate()->factory(); { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); uint16_t* two_byte_string = AsciiToTwoByteString("test string"); Local<String> string = String::NewExternal(new TestResource(two_byte_string)); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); // Trigger GCs so that the newly allocated string moves to old gen. - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now i::Handle<i::String> isymbol = factory->InternalizedStringFromString(istring); CHECK(isymbol->IsInternalizedString()); } - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } THREADED_TEST(UsingExternalAsciiString) { - i::Factory* factory = i::Isolate::Current()->factory(); + i::Factory* factory = CcTest::i_isolate()->factory(); { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); const char* one_byte_string = "test string"; Local<String> string = String::NewExternal( new TestAsciiResource(i::StrDup(one_byte_string))); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); // Trigger GCs so that the newly allocated string moves to old gen. - HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now - HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now i::Handle<i::String> isymbol = factory->InternalizedStringFromString(istring); CHECK(isymbol->IsInternalizedString()); } - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -774,18 +777,19 @@ THREADED_TEST(ScavengeExternalString) { int dispose_count = 0; bool in_new_space = false; { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); uint16_t* two_byte_string = AsciiToTwoByteString("test string"); Local<String> string = String::NewExternal(new TestResource(two_byte_string, &dispose_count)); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); - HEAP->CollectGarbage(i::NEW_SPACE); - in_new_space = HEAP->InNewSpace(*istring); - CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring)); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + in_new_space = CcTest::heap()->InNewSpace(*istring); + CHECK(in_new_space || CcTest::heap()->old_data_space()->Contains(*istring)); CHECK_EQ(0, dispose_count); } - HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); + CcTest::heap()->CollectGarbage( + in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); CHECK_EQ(1, dispose_count); } @@ -796,17 +800,18 @@ THREADED_TEST(ScavengeExternalAsciiString) { int dispose_count = 0; bool in_new_space = false; { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); const char* one_byte_string = "test string"; Local<String> string = String::NewExternal( new TestAsciiResource(i::StrDup(one_byte_string), &dispose_count)); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); - HEAP->CollectGarbage(i::NEW_SPACE); - in_new_space = HEAP->InNewSpace(*istring); - CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring)); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + in_new_space = CcTest::heap()->InNewSpace(*istring); + CHECK(in_new_space || CcTest::heap()->old_data_space()->Contains(*istring)); CHECK_EQ(0, dispose_count); } - HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); + CcTest::heap()->CollectGarbage( + in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); CHECK_EQ(1, dispose_count); } @@ -849,11 +854,11 @@ TEST(ExternalStringWithDisposeHandling) { Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); } - i::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllAvailableGarbage(); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); @@ -870,11 +875,11 @@ TEST(ExternalStringWithDisposeHandling) { Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); } - i::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllAvailableGarbage(); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); } @@ -920,9 +925,9 @@ THREADED_TEST(StringConcat) { CHECK(value->IsNumber()); CHECK_EQ(68, value->Int32Value()); } - i::Isolate::Current()->compilation_cache()->Clear(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -940,7 +945,7 @@ template<typename T> static void CheckReturnValue(const T& t, i::Address callback) { v8::ReturnValue<v8::Value> rv = t.GetReturnValue(); i::Object** o = *reinterpret_cast<i::Object***>(&rv); - CHECK_EQ(v8::Isolate::GetCurrent(), t.GetIsolate()); + CHECK_EQ(CcTest::isolate(), t.GetIsolate()); CHECK_EQ(t.GetIsolate(), rv.GetIsolate()); CHECK((*o)->IsTheHole() || (*o)->IsUndefined()); // Verify reset @@ -1192,7 +1197,7 @@ Handle<Value> TestFastReturnValues() { THREADED_PROFILED_TEST(FastReturnValues) { LocalContext env; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Value> value; // check int32_t and uint32_t int32_t int_values[] = { @@ -1412,7 +1417,7 @@ THREADED_TEST(FindInstanceInPrototypeChain) { THREADED_TEST(TinyInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); int32_t value = 239; Local<v8::Integer> value_obj = v8::Integer::New(value); @@ -1426,7 +1431,7 @@ THREADED_TEST(TinyInteger) { THREADED_TEST(BigSmiInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); int32_t value = i::Smi::kMaxValue; // We cannot add one to a Smi::kMaxValue without wrapping. @@ -1446,7 +1451,7 @@ THREADED_TEST(BigSmiInteger) { THREADED_TEST(BigInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); // We cannot add one to a Smi::kMaxValue without wrapping. if (i::SmiValuesAre31Bits()) { @@ -1469,7 +1474,7 @@ THREADED_TEST(BigInteger) { THREADED_TEST(TinyUnsignedInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); uint32_t value = 239; @@ -1484,7 +1489,7 @@ THREADED_TEST(TinyUnsignedInteger) { THREADED_TEST(BigUnsignedSmiInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue); CHECK(i::Smi::IsValid(value)); @@ -1501,7 +1506,7 @@ THREADED_TEST(BigUnsignedSmiInteger) { THREADED_TEST(BigUnsignedInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue) + 1; CHECK(value > static_cast<uint32_t>(i::Smi::kMaxValue)); @@ -1518,7 +1523,7 @@ THREADED_TEST(BigUnsignedInteger) { THREADED_TEST(OutOfSignedRangeUnsignedInteger) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); uint32_t INT32_MAX_AS_UINT = (1U << 31) - 1; uint32_t value = INT32_MAX_AS_UINT + 1; @@ -1679,12 +1684,13 @@ THREADED_TEST(Number) { THREADED_TEST(ToNumber) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); Local<String> str = v8_str("3.1415926"); CHECK_EQ(3.1415926, str->NumberValue()); - v8::Handle<v8::Boolean> t = v8::True(); + v8::Handle<v8::Boolean> t = v8::True(isolate); CHECK_EQ(1.0, t->NumberValue()); - v8::Handle<v8::Boolean> f = v8::False(); + v8::Handle<v8::Boolean> f = v8::False(isolate); CHECK_EQ(0.0, f->NumberValue()); } @@ -1703,13 +1709,13 @@ THREADED_TEST(Date) { THREADED_TEST(Boolean) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::Boolean> t = v8::True(); + v8::Handle<v8::Boolean> t = v8::True(CcTest::isolate()); CHECK(t->Value()); - v8::Handle<v8::Boolean> f = v8::False(); + v8::Handle<v8::Boolean> f = v8::False(CcTest::isolate()); CHECK(!f->Value()); - v8::Handle<v8::Primitive> u = v8::Undefined(); + v8::Handle<v8::Primitive> u = v8::Undefined(CcTest::isolate()); CHECK(!u->BooleanValue()); - v8::Handle<v8::Primitive> n = v8::Null(); + v8::Handle<v8::Primitive> n = v8::Null(CcTest::isolate()); CHECK(!n->BooleanValue()); v8::Handle<String> str1 = v8_str(""); CHECK(!str1->BooleanValue()); @@ -1737,7 +1743,7 @@ static void GetM(Local<String> name, THREADED_TEST(GlobalPrototype) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New(); func_templ->PrototypeTemplate()->Set( "dummy", @@ -1755,7 +1761,7 @@ THREADED_TEST(GlobalPrototype) { THREADED_TEST(ObjectTemplate) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ1 = ObjectTemplate::New(); templ1->Set("x", v8_num(10)); templ1->Set("y", v8_num(13)); @@ -1792,7 +1798,7 @@ static void GetKnurd(Local<String> property, THREADED_TEST(DescriptorInheritance) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New(); super->PrototypeTemplate()->Set("flabby", v8::FunctionTemplate::New(GetFlabby)); @@ -1933,7 +1939,7 @@ void AddInterceptor(Handle<FunctionTemplate> templ, THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -1951,7 +1957,7 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -1972,7 +1978,7 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -1992,7 +1998,7 @@ THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { THREADED_TEST(SwitchFromInterceptorToAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddAccessor(templ, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); @@ -2010,7 +2016,7 @@ THREADED_TEST(SwitchFromInterceptorToAccessor) { THREADED_TEST(SwitchFromAccessorToInterceptor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddAccessor(templ, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); @@ -2028,7 +2034,7 @@ THREADED_TEST(SwitchFromAccessorToInterceptor) { THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -2048,7 +2054,7 @@ THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -2068,7 +2074,7 @@ THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { THREADED_TEST(SwitchFromInterceptorToJSAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -2093,7 +2099,7 @@ THREADED_TEST(SwitchFromInterceptorToJSAccessor) { THREADED_TEST(SwitchFromJSAccessorToInterceptor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -2118,7 +2124,7 @@ THREADED_TEST(SwitchFromJSAccessorToInterceptor) { THREADED_TEST(SwitchFromInterceptorToProperty) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -2136,7 +2142,7 @@ THREADED_TEST(SwitchFromInterceptorToProperty) { THREADED_TEST(SwitchFromPropertyToInterceptor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> parent = FunctionTemplate::New(); Handle<FunctionTemplate> child = FunctionTemplate::New(); child->Inherit(parent); @@ -2155,7 +2161,7 @@ THREADED_TEST(SwitchFromPropertyToInterceptor) { THREADED_TEST(NamedPropertyHandlerGetter) { echo_named_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, 0, 0, 0, 0, @@ -2191,7 +2197,7 @@ static void EchoIndexedProperty( THREADED_TEST(IndexedPropertyHandlerGetter) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetIndexedPropertyHandler(EchoIndexedProperty, 0, 0, 0, 0, @@ -2362,7 +2368,7 @@ static void PrePropertyHandlerQuery( THREADED_TEST(PrePropertyHandler) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(); desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet, 0, @@ -2419,7 +2425,7 @@ static void CallFunctionRecursivelyCall( THREADED_TEST(DeepCrossLanguageRecursion) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); global->Set(v8_str("callScriptRecursively"), v8::FunctionTemplate::New(CallScriptRecursivelyCall)); @@ -2441,7 +2447,7 @@ static void ThrowingPropertyHandlerGet( Local<String> key, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - info.GetReturnValue().Set(v8::ThrowException(key)); + info.GetReturnValue().Set(info.GetIsolate()->ThrowException(key)); } @@ -2449,13 +2455,13 @@ static void ThrowingPropertyHandlerSet( Local<String> key, Local<Value>, const v8::PropertyCallbackInfo<v8::Value>& info) { - v8::ThrowException(key); + info.GetIsolate()->ThrowException(key); info.GetReturnValue().SetUndefined(); // not the same as empty handle } THREADED_TEST(CallbackExceptionRegression) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetNamedPropertyHandler(ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet); @@ -2471,7 +2477,7 @@ THREADED_TEST(CallbackExceptionRegression) { THREADED_TEST(FunctionPrototype) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(); Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); LocalContext env; @@ -2497,7 +2503,7 @@ THREADED_TEST(InternalFields) { THREADED_TEST(GlobalObjectInternalFields) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->SetInternalFieldCount(1); LocalContext env(NULL, global_template); @@ -2512,7 +2518,7 @@ THREADED_TEST(GlobalObjectInternalFields) { THREADED_TEST(GlobalObjectHasRealIndexedProperty) { LocalContext env; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Object> global = env->Global(); global->Set(0, v8::String::New("value")); @@ -2524,7 +2530,7 @@ static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj, void* value) { CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); obj->SetAlignedPointerInInternalField(0, value); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0)); } @@ -2558,7 +2564,7 @@ static void CheckAlignedPointerInEmbedderData(LocalContext* env, void* value) { CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); (*env)->SetAlignedPointerInEmbedderData(index, value); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(value, (*env)->GetAlignedPointerFromEmbedderData(index)); } @@ -2588,7 +2594,7 @@ THREADED_TEST(EmbedderDataAlignedPointers) { for (int i = 0; i < 100; i++) { env->SetAlignedPointerInEmbedderData(i, AlignedTestPointer(i)); } - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); for (int i = 0; i < 100; i++) { CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i)); } @@ -2620,7 +2626,7 @@ THREADED_TEST(IdentityHash) { // Ensure that the test starts with an fresh heap to test whether the hash // code is based on the address. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); Local<v8::Object> obj = v8::Object::New(); int hash = obj->GetIdentityHash(); int hash1 = obj->GetIdentityHash(); @@ -2630,7 +2636,7 @@ THREADED_TEST(IdentityHash) { // objects should not be assigned the same hash code. If the test below fails // the random number generator should be evaluated. CHECK_NE(hash, hash2); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); int hash3 = v8::Object::New()->GetIdentityHash(); // Make sure that the identity hash is not based on the initial address of // the object alone. If the test below fails the random number generator @@ -2669,7 +2675,7 @@ THREADED_TEST(SymbolProperties) { v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate); v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, "my-symbol"); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); // Check basic symbol functionality. CHECK(sym1->IsSymbol()); @@ -2720,7 +2726,7 @@ THREADED_TEST(SymbolProperties) { CHECK_EQ(1, obj->GetOwnPropertyNames()->Length()); CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); // Add another property and delete it afterwards to force the object in // slow case. @@ -2770,7 +2776,7 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { CheckInternalFieldsAreZero(ab); CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); CHECK(!ab->IsExternal()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); ScopedArrayBufferContents ab_contents(ab->Externalize()); CHECK(ab->IsExternal()); @@ -3012,7 +3018,7 @@ THREADED_TEST(HiddenProperties) { v8::Local<v8::String> empty = v8_str(""); v8::Local<v8::String> prop_name = v8_str("prop_name"); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); // Make sure delete of a non-existent hidden value works CHECK(obj->DeleteHiddenValue(key)); @@ -3022,7 +3028,7 @@ THREADED_TEST(HiddenProperties) { CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); // Make sure we do not find the hidden property. CHECK(!obj->Has(empty)); @@ -3033,7 +3039,7 @@ THREADED_TEST(HiddenProperties) { CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); CHECK_EQ(2003, obj->Get(empty)->Int32Value()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); // Add another property and delete it afterwards to force the object in // slow case. @@ -3044,7 +3050,7 @@ THREADED_TEST(HiddenProperties) { CHECK(obj->Delete(prop_name)); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK(obj->SetHiddenValue(key, Handle<Value>())); CHECK(obj->GetHiddenValue(key).IsEmpty()); @@ -3111,7 +3117,7 @@ THREADED_TEST(HiddenPropertiesWithInterceptors) { THREADED_TEST(External) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); int x = 3; Local<v8::External> ext = v8::External::New(&x); LocalContext env; @@ -3143,7 +3149,7 @@ THREADED_TEST(External) { THREADED_TEST(GlobalHandle) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::Persistent<String> global; { v8::HandleScope scope(isolate); @@ -3168,7 +3174,7 @@ THREADED_TEST(GlobalHandle) { THREADED_TEST(ResettingGlobalHandle) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::Persistent<String> global; { v8::HandleScope scope(isolate); @@ -3196,7 +3202,7 @@ THREADED_TEST(ResettingGlobalHandle) { THREADED_TEST(ResettingGlobalHandleToEmpty) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::Persistent<String> global; { v8::HandleScope scope(isolate); @@ -3220,7 +3226,7 @@ THREADED_TEST(ResettingGlobalHandleToEmpty) { THREADED_TEST(ClearAndLeakGlobal) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::internal::GlobalHandles* global_handles = NULL; int initial_handle_count = 0; v8::Persistent<String> global; @@ -3242,9 +3248,9 @@ THREADED_TEST(ClearAndLeakGlobal) { THREADED_TEST(GlobalHandleUpcast) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Local<String> local = v8::Local<String>::New(v8_str("str")); + v8::Local<String> local = v8::Local<String>::New(isolate, v8_str("str")); v8::Persistent<String> global_string(isolate, local); v8::Persistent<Value>& global_value = v8::Persistent<Value>::Cast(global_string); @@ -3255,7 +3261,7 @@ THREADED_TEST(GlobalHandleUpcast) { THREADED_TEST(HandleEquality) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::Persistent<String> global1; v8::Persistent<String> global2; { @@ -3293,11 +3299,9 @@ THREADED_TEST(HandleEquality) { THREADED_TEST(LocalHandle) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Local<String> local = v8::Local<String>::New(v8_str("str")); - CHECK_EQ(local->Length(), 3); - - local = v8::Local<String>::New(v8::Isolate::GetCurrent(), v8_str("str")); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<String> local = + v8::Local<String>::New(CcTest::isolate(), v8_str("str")); CHECK_EQ(local->Length(), 3); } @@ -3314,8 +3318,9 @@ class WeakCallCounter { }; +template<typename T> static void WeakPointerCallback(v8::Isolate* isolate, - Persistent<Value>* handle, + Persistent<T>* handle, WeakCallCounter* counter) { CHECK_EQ(1234, counter->id()); counter->increment(); @@ -3323,7 +3328,8 @@ static void WeakPointerCallback(v8::Isolate* isolate, } -static UniqueId MakeUniqueId(const Persistent<Value>& p) { +template<typename T> +static UniqueId MakeUniqueId(const Persistent<T>& p) { return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); } @@ -3421,6 +3427,97 @@ THREADED_TEST(ApiObjectGroups) { } +THREADED_TEST(ApiObjectGroupsForSubtypes) { + LocalContext env; + v8::Isolate* iso = env->GetIsolate(); + HandleScope scope(iso); + + Persistent<Object> g1s1; + Persistent<String> g1s2; + Persistent<String> g1c1; + Persistent<Object> g2s1; + Persistent<String> g2s2; + Persistent<String> g2c1; + + WeakCallCounter counter(1234); + + { + HandleScope scope(iso); + g1s1.Reset(iso, Object::New()); + g1s2.Reset(iso, String::New("foo1")); + g1c1.Reset(iso, String::New("foo2")); + g1s1.MakeWeak(&counter, &WeakPointerCallback); + g1s2.MakeWeak(&counter, &WeakPointerCallback); + g1c1.MakeWeak(&counter, &WeakPointerCallback); + + g2s1.Reset(iso, Object::New()); + g2s2.Reset(iso, String::New("foo3")); + g2c1.Reset(iso, String::New("foo4")); + g2s1.MakeWeak(&counter, &WeakPointerCallback); + g2s2.MakeWeak(&counter, &WeakPointerCallback); + g2c1.MakeWeak(&counter, &WeakPointerCallback); + } + + Persistent<Value> root(iso, g1s1); // make a root. + + // Connect group 1 and 2, make a cycle. + { + HandleScope scope(iso); + CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1))); + CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1))); + } + + { + UniqueId id1 = MakeUniqueId(g1s1); + UniqueId id2 = MakeUniqueId(g2s2); + iso->SetObjectGroupId(g1s1, id1); + iso->SetObjectGroupId(g1s2, id1); + iso->SetReference(g1s1, g1c1); + iso->SetObjectGroupId(g2s1, id2); + iso->SetObjectGroupId(g2s2, id2); + iso->SetReferenceFromGroup(id2, g2c1); + } + // Do a single full GC, ensure incremental marking is stopped. + v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( + iso)->heap(); + heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + + // All object should be alive. + CHECK_EQ(0, counter.NumberOfWeakCalls()); + + // Weaken the root. + root.MakeWeak(&counter, &WeakPointerCallback); + // But make children strong roots---all the objects (except for children) + // should be collectable now. + g1c1.ClearWeak(); + g2c1.ClearWeak(); + + // Groups are deleted, rebuild groups. + { + UniqueId id1 = MakeUniqueId(g1s1); + UniqueId id2 = MakeUniqueId(g2s2); + iso->SetObjectGroupId(g1s1, id1); + iso->SetObjectGroupId(g1s2, id1); + iso->SetReference(g1s1, g1c1); + iso->SetObjectGroupId(g2s1, id2); + iso->SetObjectGroupId(g2s2, id2); + iso->SetReferenceFromGroup(id2, g2c1); + } + + heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + + // All objects should be gone. 5 global handles in total. + CHECK_EQ(5, counter.NumberOfWeakCalls()); + + // And now make children weak again and collect them. + g1c1.MakeWeak(&counter, &WeakPointerCallback); + g2c1.MakeWeak(&counter, &WeakPointerCallback); + + heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CHECK_EQ(7, counter.NumberOfWeakCalls()); +} + + THREADED_TEST(ApiObjectGroupsCycle) { LocalContext env; v8::Isolate* iso = env->GetIsolate(); @@ -3675,7 +3772,7 @@ static void check_message_0(v8::Handle<v8::Message> message, THREADED_TEST(MessageHandler0) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); v8::V8::AddMessageListener(check_message_0, v8_num(5.76)); LocalContext context; @@ -3702,7 +3799,7 @@ static void check_message_1(v8::Handle<v8::Message> message, TEST(MessageHandler1) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); v8::V8::AddMessageListener(check_message_1); LocalContext context; @@ -3727,7 +3824,7 @@ static void check_message_2(v8::Handle<v8::Message> message, TEST(MessageHandler2) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); v8::V8::AddMessageListener(check_message_2); LocalContext context; @@ -3752,15 +3849,16 @@ static void check_message_3(v8::Handle<v8::Message> message, TEST(MessageHandler3) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); CHECK(!message_received); v8::V8::AddMessageListener(check_message_3); LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1), - v8::Integer::New(2), - v8::True()); + v8::Integer::New(1, isolate), + v8::Integer::New(2, isolate), + v8::True(isolate)); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), &origin); script->Run(); @@ -3780,15 +3878,16 @@ static void check_message_4(v8::Handle<v8::Message> message, TEST(MessageHandler4) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); CHECK(!message_received); v8::V8::AddMessageListener(check_message_4); LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1), - v8::Integer::New(2), - v8::False()); + v8::Integer::New(1, isolate), + v8::Integer::New(2, isolate), + v8::False(isolate)); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), &origin); script->Run(); @@ -3816,15 +3915,16 @@ static void check_message_5b(v8::Handle<v8::Message> message, TEST(MessageHandler5) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); CHECK(!message_received); v8::V8::AddMessageListener(check_message_5a); LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1), - v8::Integer::New(2), - v8::True()); + v8::Integer::New(1, isolate), + v8::Integer::New(2, isolate), + v8::True(isolate)); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), &origin); script->Run(); @@ -3836,9 +3936,9 @@ TEST(MessageHandler5) { v8::V8::AddMessageListener(check_message_5b); origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1), - v8::Integer::New(2), - v8::False()); + v8::Integer::New(1, isolate), + v8::Integer::New(2, isolate), + v8::False(isolate)); script = Script::Compile(v8_str("throw 'error'"), &origin); script->Run(); @@ -3958,7 +4058,7 @@ void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(Vector) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> global = ObjectTemplate::New(); global->Set(v8_str("f"), v8::FunctionTemplate::New(HandleF)); LocalContext context(0, global); @@ -3997,7 +4097,8 @@ THREADED_TEST(Vector) { THREADED_TEST(FunctionCall) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); CompileRun( "function Foo() {" " var result = [];" @@ -4005,9 +4106,20 @@ THREADED_TEST(FunctionCall) { " result.push(arguments[i]);" " }" " return result;" + "}" + "function ReturnThisSloppy() {" + " return this;" + "}" + "function ReturnThisStrict() {" + " 'use strict';" + " return this;" "}"); Local<Function> Foo = Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); + Local<Function> ReturnThisSloppy = + Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisSloppy"))); + Local<Function> ReturnThisStrict = + Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisStrict"))); v8::Handle<Value>* args0 = NULL; Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->Call(Foo, 0, args0)); @@ -4044,6 +4156,31 @@ THREADED_TEST(FunctionCall) { CHECK_EQ(8.8, a4->Get(v8::Integer::New(1))->NumberValue()); CHECK_EQ(9.9, a4->Get(v8::Integer::New(2))->NumberValue()); CHECK_EQ(10.11, a4->Get(v8::Integer::New(3))->NumberValue()); + + Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL); + CHECK(r1->StrictEquals(context->Global())); + Local<v8::Value> r2 = ReturnThisSloppy->Call(v8::Null(isolate), 0, NULL); + CHECK(r2->StrictEquals(context->Global())); + Local<v8::Value> r3 = ReturnThisSloppy->Call(v8_num(42), 0, NULL); + CHECK(r3->IsNumberObject()); + CHECK_EQ(42.0, r3.As<v8::NumberObject>()->ValueOf()); + Local<v8::Value> r4 = ReturnThisSloppy->Call(v8_str("hello"), 0, NULL); + CHECK(r4->IsStringObject()); + CHECK(r4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); + Local<v8::Value> r5 = ReturnThisSloppy->Call(v8::True(isolate), 0, NULL); + CHECK(r5->IsBooleanObject()); + CHECK(r5.As<v8::BooleanObject>()->ValueOf()); + + Local<v8::Value> r6 = ReturnThisStrict->Call(v8::Undefined(isolate), 0, NULL); + CHECK(r6->IsUndefined()); + Local<v8::Value> r7 = ReturnThisStrict->Call(v8::Null(isolate), 0, NULL); + CHECK(r7->IsNull()); + Local<v8::Value> r8 = ReturnThisStrict->Call(v8_num(42), 0, NULL); + CHECK(r8->StrictEquals(v8_num(42))); + Local<v8::Value> r9 = ReturnThisStrict->Call(v8_str("hello"), 0, NULL); + CHECK(r9->StrictEquals(v8_str("hello"))); + Local<v8::Value> r10 = ReturnThisStrict->Call(v8::True(isolate), 0, NULL); + CHECK(r10->StrictEquals(v8::True(isolate))); } @@ -4104,7 +4241,7 @@ TEST(OutOfMemoryNested) { constraints.set_max_old_space_size(5 * K * K); v8::SetResourceConstraints(&constraints); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ProvokeOutOfMemory"), v8::FunctionTemplate::New(ProvokeOutOfMemory)); @@ -4311,7 +4448,8 @@ THREADED_TEST(isNumberType) { THREADED_TEST(ConversionException) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); CompileRun( "function TestClass() { };" "TestClass.prototype.toString = function () { throw 'uncle?'; };" @@ -4340,7 +4478,7 @@ THREADED_TEST(ConversionException) { CHECK(to_int32_result.IsEmpty()); CheckUncle(&try_catch); - Local<Value> to_object_result = v8::Undefined()->ToObject(); + Local<Value> to_object_result = v8::Undefined(isolate)->ToObject(); CHECK(to_object_result.IsEmpty()); CHECK(try_catch.HasCaught()); try_catch.Reset(); @@ -4365,7 +4503,7 @@ THREADED_TEST(ConversionException) { void ThrowFromC(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); - v8::ThrowException(v8_str("konto")); + args.GetIsolate()->ThrowException(v8_str("konto")); } @@ -4383,7 +4521,7 @@ void CCatcher(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(APICatch) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(ThrowFromC)); @@ -4401,7 +4539,7 @@ THREADED_TEST(APICatch) { THREADED_TEST(APIThrowTryCatch) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(ThrowFromC)); @@ -4420,7 +4558,7 @@ THREADED_TEST(APIThrowTryCatch) { // JS stack. This test therefore fails on the simulator. The test is // not threaded to allow the threading tests to run on the simulator. TEST(TryCatchInTryFinally) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("CCatcher"), v8::FunctionTemplate::New(CCatcher)); @@ -4454,7 +4592,7 @@ static void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { // formatting. However, they are invoked when performing normal error // string conversions. TEST(APIThrowMessageOverwrittenToString) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::V8::AddMessageListener(check_reference_error_message); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("fail"), v8::FunctionTemplate::New(Fail)); @@ -4578,7 +4716,7 @@ static void receive_message(v8::Handle<v8::Message> message, TEST(APIThrowMessage) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::V8::AddMessageListener(receive_message); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), @@ -4592,7 +4730,7 @@ TEST(APIThrowMessage) { TEST(APIThrowMessageAndVerboseTryCatch) { message_received = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::V8::AddMessageListener(receive_message); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), @@ -4624,7 +4762,7 @@ TEST(APIStackOverflowAndVerboseTryCatch) { THREADED_TEST(ExternalScriptException) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(ThrowFromC)); @@ -4648,10 +4786,11 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { int count = args[0]->Int32Value(); int cInterval = args[2]->Int32Value(); if (count == 0) { - v8::ThrowException(v8_str("FromC")); + args.GetIsolate()->ThrowException(v8_str("FromC")); return; } else { - Local<v8::Object> global = Context::GetCurrent()->Global(); + Local<v8::Object> global = + args.GetIsolate()->GetCurrentContext()->Global(); Local<Value> fun = global->Get(v8_str("JSThrowCountDown")); v8::Handle<Value> argv[] = { v8_num(count - 1), args[1], @@ -4664,7 +4803,7 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { if (try_catch.HasCaught()) { CHECK_EQ(expected, count); CHECK(result.IsEmpty()); - CHECK(!i::Isolate::Current()->has_scheduled_exception()); + CHECK(!CcTest::i_isolate()->has_scheduled_exception()); } else { CHECK_NE(expected, count); } @@ -4728,7 +4867,7 @@ THREADED_TEST(EvalInTryFinally) { // JS stack. This test therefore fails on the simulator. The test is // not threaded to allow the threading tests to run on the simulator. TEST(ExceptionOrder) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("check"), v8::FunctionTemplate::New(JSCheck)); templ->Set(v8_str("CThrowCountDown"), @@ -4787,12 +4926,12 @@ TEST(ExceptionOrder) { void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); CHECK_EQ(1, args.Length()); - v8::ThrowException(args[0]); + args.GetIsolate()->ThrowException(args[0]); } THREADED_TEST(ThrowValues) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(ThrowValue)); LocalContext context(0, templ); @@ -4885,7 +5024,7 @@ static void TryCatchNestedHelper(int depth) { CHECK(try_catch.HasCaught()); try_catch.ReThrow(); } else { - v8::ThrowException(v8_str("back")); + CcTest::isolate()->ThrowException(v8_str("back")); } } @@ -4930,7 +5069,7 @@ void TryCatchMixedNestingHelper( // This exercises the ability of TryCatch.ReThrow() to restore the // inner pending Message before throwing the exception again. TEST(TryCatchMixedNesting) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::V8::Initialize(); v8::TryCatch try_catch; Local<ObjectTemplate> templ = ObjectTemplate::New(); @@ -4962,16 +5101,26 @@ THREADED_TEST(Equality) { CHECK(!v8_str("5")->StrictEquals(v8_num(5))); CHECK(v8_num(1)->StrictEquals(v8_num(1))); CHECK(!v8_num(1)->StrictEquals(v8_num(2))); - CHECK(v8_num(0)->StrictEquals(v8_num(-0))); + CHECK(v8_num(0.0)->StrictEquals(v8_num(-0.0))); Local<Value> not_a_number = v8_num(i::OS::nan_value()); CHECK(!not_a_number->StrictEquals(not_a_number)); - CHECK(v8::False()->StrictEquals(v8::False())); - CHECK(!v8::False()->StrictEquals(v8::Undefined())); + CHECK(v8::False(isolate)->StrictEquals(v8::False(isolate))); + CHECK(!v8::False(isolate)->StrictEquals(v8::Undefined(isolate))); v8::Handle<v8::Object> obj = v8::Object::New(); v8::Persistent<v8::Object> alias(isolate, obj); CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj)); alias.Dispose(); + + CHECK(v8_str("a")->SameValue(v8_str("a"))); + CHECK(!v8_str("a")->SameValue(v8_str("b"))); + CHECK(!v8_str("5")->SameValue(v8_num(5))); + CHECK(v8_num(1)->SameValue(v8_num(1))); + CHECK(!v8_num(1)->SameValue(v8_num(2))); + CHECK(!v8_num(0.0)->SameValue(v8_num(-0.0))); + CHECK(not_a_number->SameValue(not_a_number)); + CHECK(v8::False(isolate)->SameValue(v8::False(isolate))); + CHECK(!v8::False(isolate)->SameValue(v8::Undefined(isolate))); } @@ -5056,7 +5205,7 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) { THREADED_TEST(DefinePropertyOnDefineGetterSetter) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); LocalContext context; @@ -5108,7 +5257,7 @@ static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context, THREADED_TEST(DefineAPIAccessorOnObject) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); LocalContext context; @@ -5182,7 +5331,7 @@ THREADED_TEST(DefineAPIAccessorOnObject) { THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); LocalContext context; @@ -5238,7 +5387,7 @@ static void Get239Value(Local<String> name, THREADED_TEST(ElementAPIAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); LocalContext context; @@ -5276,7 +5425,7 @@ static void SetXValue(Local<String> name, THREADED_TEST(SimplePropertyWrite) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut")); LocalContext context; @@ -5285,7 +5434,7 @@ THREADED_TEST(SimplePropertyWrite) { for (int i = 0; i < 10; i++) { CHECK(xValue.IsEmpty()); script->Run(); - CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue)); + CHECK_EQ(v8_num(4), Local<Value>::New(CcTest::isolate(), xValue)); xValue.Dispose(); xValue.Clear(); } @@ -5293,7 +5442,7 @@ THREADED_TEST(SimplePropertyWrite) { THREADED_TEST(SetterOnly) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut")); LocalContext context; @@ -5302,7 +5451,7 @@ THREADED_TEST(SetterOnly) { for (int i = 0; i < 10; i++) { CHECK(xValue.IsEmpty()); script->Run(); - CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue)); + CHECK_EQ(v8_num(4), Local<Value>::New(CcTest::isolate(), xValue)); xValue.Dispose(); xValue.Clear(); } @@ -5310,7 +5459,7 @@ THREADED_TEST(SetterOnly) { THREADED_TEST(NoAccessors) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), static_cast<v8::AccessorGetterCallback>(NULL), @@ -5334,7 +5483,7 @@ static void XPropertyGetter(Local<String> property, THREADED_TEST(NamedInterceptorPropertyRead) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(XPropertyGetter); LocalContext context; @@ -5348,7 +5497,7 @@ THREADED_TEST(NamedInterceptorPropertyRead) { THREADED_TEST(NamedInterceptorDictionaryIC) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(XPropertyGetter); LocalContext context; @@ -5378,7 +5527,7 @@ THREADED_TEST(NamedInterceptorDictionaryIC) { THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> context1 = Context::New(isolate); @@ -5430,7 +5579,7 @@ static void SetXOnPrototypeGetter( // This is a regression test for http://crbug.com/20104. Map // transitions should not interfere with post interceptor lookup. THREADED_TEST(NamedInterceptorMapTransitionRead) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New(); Local<v8::ObjectTemplate> instance_template = function_template->InstanceTemplate(); @@ -5467,7 +5616,7 @@ static void IndexedPropertySetter( THREADED_TEST(IndexedInterceptorWithIndexedAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IndexedPropertyGetter, IndexedPropertySetter); @@ -5532,7 +5681,7 @@ void UnboxedDoubleIndexedPropertyEnumerator( // Make sure that the the interceptor code in the runtime properly handles // merging property name lists for double-array-backed arrays. THREADED_TEST(IndexedInterceptorUnboxedDoubleWithIndexedAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(UnboxedDoubleIndexedPropertyGetter, UnboxedDoubleIndexedPropertySetter, @@ -5588,7 +5737,7 @@ static void NonStrictIndexedPropertyGetter( // Make sure that the the interceptor code in the runtime properly handles // merging property name lists for non-string arguments arrays. THREADED_TEST(IndexedInterceptorNonStrictArgsWithIndexedAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(NonStrictIndexedPropertyGetter, 0, @@ -5614,7 +5763,7 @@ static void IdentityIndexedPropertyGetter( THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5635,7 +5784,7 @@ THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { THREADED_TEST(IndexedInterceptorWithNoSetter) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5658,7 +5807,7 @@ THREADED_TEST(IndexedInterceptorWithNoSetter) { THREADED_TEST(IndexedInterceptorWithAccessorCheck) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5683,7 +5832,7 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) { THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5712,7 +5861,7 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) { THREADED_TEST(IndexedInterceptorWithDifferentIndices) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5735,7 +5884,7 @@ THREADED_TEST(IndexedInterceptorWithDifferentIndices) { THREADED_TEST(IndexedInterceptorWithNegativeIndices) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5774,7 +5923,7 @@ THREADED_TEST(IndexedInterceptorWithNegativeIndices) { THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5803,7 +5952,7 @@ THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { THREADED_TEST(IndexedInterceptorGoingMegamorphic) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5833,7 +5982,7 @@ THREADED_TEST(IndexedInterceptorGoingMegamorphic) { THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5863,7 +6012,7 @@ THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { THREADED_TEST(IndexedInterceptorOnProto) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); @@ -5887,7 +6036,7 @@ THREADED_TEST(IndexedInterceptorOnProto) { THREADED_TEST(MultiContexts) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(DummyCallHandler)); @@ -5923,7 +6072,7 @@ THREADED_TEST(FunctionPrototypeAcrossContexts) { // Make sure that functions created by cloning boilerplates cannot // communicate through their __proto__ field. - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); LocalContext env0; v8::Handle<v8::Object> global0 = @@ -5956,7 +6105,7 @@ THREADED_TEST(Regress892105) { // to Object.prototype and Array.prototype and create a new // environment. This should succeed. - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<String> source = v8_str("Object.prototype.obj = 1234;" "Array.prototype.arr = 4567;" @@ -6187,7 +6336,7 @@ static void HandleLogDelegator( THREADED_TEST(GlobalObjectTemplate) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); Local<ObjectTemplate> global_template = ObjectTemplate::New(); global_template->Set(v8_str("JSNI_Log"), @@ -6205,12 +6354,12 @@ static const char* kSimpleExtensionSource = THREADED_TEST(SimpleExtensions) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); const char* extension_names[] = { "simpletest" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); CHECK_EQ(result, v8::Integer::New(4)); @@ -6218,12 +6367,12 @@ THREADED_TEST(SimpleExtensions) { THREADED_TEST(NullExtensions) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("nulltest", NULL)); const char* extension_names[] = { "nulltest" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run(); CHECK_EQ(result, v8::Integer::New(4)); @@ -6237,13 +6386,13 @@ static const int kEmbeddedExtensionSourceValidLen = 34; THREADED_TEST(ExtensionMissingSourceLength) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("srclentest_fail", kEmbeddedExtensionSource)); const char* extension_names[] = { "srclentest_fail" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); CHECK_EQ(0, *context); } @@ -6251,7 +6400,7 @@ THREADED_TEST(ExtensionMissingSourceLength) { THREADED_TEST(ExtensionWithSourceLength) { for (int source_len = kEmbeddedExtensionSourceValidLen - 1; source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); i::ScopedVector<char> extension_name(32); i::OS::SNPrintF(extension_name, "ext #%d", source_len); v8::RegisterExtension(new Extension(extension_name.start(), @@ -6260,7 +6409,7 @@ THREADED_TEST(ExtensionWithSourceLength) { const char* extension_names[1] = { extension_name.start() }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); if (source_len == kEmbeddedExtensionSourceValidLen) { Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run(); @@ -6291,13 +6440,13 @@ static const char* kEvalExtensionSource2 = THREADED_TEST(UseEvalFromExtension) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); const char* extension_names[] = { "evaltest1", "evaltest2" }; v8::ExtensionConfiguration extensions(2, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("UseEval1()"))->Run(); CHECK_EQ(result, v8::Integer::New(42)); @@ -6325,13 +6474,13 @@ static const char* kWithExtensionSource2 = THREADED_TEST(UseWithFromExtension) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); const char* extension_names[] = { "withtest1", "withtest2" }; v8::ExtensionConfiguration extensions(2, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("UseWith1()"))->Run(); CHECK_EQ(result, v8::Integer::New(87)); @@ -6341,12 +6490,12 @@ THREADED_TEST(UseWithFromExtension) { THREADED_TEST(AutoExtensions) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); Extension* extension = new Extension("autotest", kSimpleExtensionSource); extension->set_auto_enable(true); v8::RegisterExtension(extension); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent()); + Context::New(CcTest::isolate()); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); CHECK_EQ(result, v8::Integer::New(4)); @@ -6360,13 +6509,13 @@ static const char* kSyntaxErrorInExtensionSource = // Test that a syntax error in an extension does not cause a fatal // error but results in an empty context. THREADED_TEST(SyntaxErrorExtensions) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("syntaxerror", kSyntaxErrorInExtensionSource)); const char* extension_names[] = { "syntaxerror" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } @@ -6378,13 +6527,13 @@ static const char* kExceptionInExtensionSource = // Test that an exception when installing an extension does not cause // a fatal error but results in an empty context. THREADED_TEST(ExceptionExtensions) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("exception", kExceptionInExtensionSource)); const char* extension_names[] = { "exception" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } @@ -6400,13 +6549,13 @@ static const char* kNativeCallTest = // Test that a native runtime calls are supported in extensions. THREADED_TEST(NativeCallInExtensions) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("nativecall", kNativeCallInExtensionSource)); const char* extension_names[] = { "nativecall" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run(); CHECK_EQ(result, v8::Integer::New(3)); @@ -6435,14 +6584,14 @@ class NativeFunctionExtension : public Extension { THREADED_TEST(NativeFunctionDeclaration) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedecl"; v8::RegisterExtension(new NativeFunctionExtension(name, "native function foo();")); const char* extension_names[] = { name }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run(); CHECK_EQ(result, v8::Integer::New(42)); @@ -6450,7 +6599,7 @@ THREADED_TEST(NativeFunctionDeclaration) { THREADED_TEST(NativeFunctionDeclarationError) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedeclerr"; // Syntax error in extension code. v8::RegisterExtension(new NativeFunctionExtension(name, @@ -6458,13 +6607,13 @@ THREADED_TEST(NativeFunctionDeclarationError) { const char* extension_names[] = { name }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } THREADED_TEST(NativeFunctionDeclarationErrorEscape) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedeclerresc"; // Syntax error in extension code - escape code in "native" means that // it's not treated as a keyword. @@ -6474,13 +6623,13 @@ THREADED_TEST(NativeFunctionDeclarationErrorEscape) { const char* extension_names[] = { name }; v8::ExtensionConfiguration extensions(1, extension_names); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } static void CheckDependencies(const char* name, const char* expected) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::ExtensionConfiguration config(1, &name); LocalContext context(&config); CHECK_EQ(String::New(expected), context->Global()->Get(v8_str("loaded"))); @@ -6508,7 +6657,7 @@ THREADED_TEST(ExtensionDependency) { CheckDependencies("C", "undefinedAC"); CheckDependencies("D", "undefinedABCD"); CheckDependencies("E", "undefinedABCDE"); - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[2] = { "C", "E" }; v8::ExtensionConfiguration config(2, exts); LocalContext context(&config); @@ -6564,7 +6713,7 @@ v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunction( THREADED_TEST(FunctionLookup) { v8::RegisterExtension(new FunctionExtension()); - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[1] = { "functiontest" }; v8::ExtensionConfiguration config(1, exts); LocalContext context(&config); @@ -6577,7 +6726,7 @@ THREADED_TEST(FunctionLookup) { THREADED_TEST(NativeFunctionConstructCall) { v8::RegisterExtension(new FunctionExtension()); - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[1] = { "functiontest" }; v8::ExtensionConfiguration config(1, exts); LocalContext context(&config); @@ -6616,7 +6765,7 @@ TEST(ErrorReporting) { last_location = NULL; v8::ExtensionConfiguration config(1, bDeps); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &config); + Context::New(CcTest::isolate(), &config); CHECK(context.IsEmpty()); CHECK_NE(last_location, NULL); } @@ -6637,7 +6786,7 @@ void OOMCallback(const char* location, const char* message) { TEST(RegexpOutOfMemory) { // Execute a script that causes out of memory when flattening a string. - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::V8::SetFatalErrorHandler(OOMCallback); LocalContext context; Local<Script> script = @@ -6652,7 +6801,7 @@ TEST(RegexpOutOfMemory) { static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, v8::Handle<Value> data) { CHECK(message->GetScriptResourceName()->IsUndefined()); - CHECK_EQ(v8::Undefined(), message->GetScriptResourceName()); + CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName()); message->GetLineNumber(); message->GetSourceLine(); } @@ -6720,16 +6869,16 @@ void WhammyPropertyGetter(Local<String> name, THREADED_TEST(WeakReference) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); - Whammy* whammy = new Whammy(v8::Isolate::GetCurrent()); + Whammy* whammy = new Whammy(CcTest::isolate()); templ->SetNamedPropertyHandler(WhammyPropertyGetter, 0, 0, 0, 0, v8::External::New(whammy)); const char* extension_list[] = { "v8/gc" }; v8::ExtensionConfiguration extensions(1, extension_list); v8::Handle<Context> context = - Context::New(v8::Isolate::GetCurrent(), &extensions); + Context::New(CcTest::isolate(), &extensions); Context::Scope context_scope(context); v8::Handle<v8::Object> interceptor = templ->NewInstance(); @@ -6758,7 +6907,7 @@ static void DisposeAndSetFlag(v8::Isolate* isolate, THREADED_TEST(IndependentWeakHandle) { - v8::Isolate* iso = v8::Isolate::GetCurrent(); + v8::Isolate* iso = CcTest::isolate(); v8::HandleScope scope(iso); v8::Handle<Context> context = Context::New(iso); Context::Scope context_scope(context); @@ -6779,19 +6928,19 @@ THREADED_TEST(IndependentWeakHandle) { object_a.MarkIndependent(); object_b.MarkIndependent(); CHECK(object_b.IsIndependent()); - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); CHECK(object_a_disposed); CHECK(object_b_disposed); } static void InvokeScavenge() { - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); } static void InvokeMarkSweep() { - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -6814,7 +6963,7 @@ static void ForceMarkSweep(v8::Isolate* isolate, THREADED_TEST(GCFromWeakCallbacks) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Handle<Context> context = Context::New(isolate); Context::Scope context_scope(context); @@ -6853,7 +7002,7 @@ static void RevivingCallback(v8::Isolate* isolate, THREADED_TEST(IndependentHandleRevival) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Handle<Context> context = Context::New(isolate); Context::Scope context_scope(context); @@ -6870,9 +7019,9 @@ THREADED_TEST(IndependentHandleRevival) { bool revived = false; object.MakeWeak(&revived, &RevivingCallback); object.MarkIndependent(); - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); CHECK(revived); - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); { v8::HandleScope handle_scope(isolate); v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object); @@ -6889,19 +7038,20 @@ v8::Handle<Function> args_fun; static void ArgumentsTestCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); + v8::Isolate* isolate = args.GetIsolate(); CHECK_EQ(args_fun, args.Callee()); CHECK_EQ(3, args.Length()); - CHECK_EQ(v8::Integer::New(1), args[0]); - CHECK_EQ(v8::Integer::New(2), args[1]); - CHECK_EQ(v8::Integer::New(3), args[2]); - CHECK_EQ(v8::Undefined(), args[3]); + CHECK_EQ(v8::Integer::New(1, isolate), args[0]); + CHECK_EQ(v8::Integer::New(2, isolate), args[1]); + CHECK_EQ(v8::Integer::New(3, isolate), args[2]); + CHECK_EQ(v8::Undefined(isolate), args[3]); v8::HandleScope scope(args.GetIsolate()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } THREADED_TEST(Arguments) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); LocalContext context(NULL, global); @@ -6941,7 +7091,7 @@ static void IDeleter(uint32_t index, THREADED_TEST(Deleter) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetNamedPropertyHandler(NoBlockGetterX, NULL, NULL, PDeleter, NULL); obj->SetIndexedPropertyHandler(NoBlockGetterI, NULL, NULL, IDeleter, NULL); @@ -7004,7 +7154,7 @@ static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { THREADED_TEST(Enumerators) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetNamedPropertyHandler(GetK, NULL, NULL, NULL, NamedEnum); obj->SetIndexedPropertyHandler(IndexedGetK, NULL, NULL, NULL, IndexedEnum); @@ -7068,7 +7218,8 @@ static void PGetter(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); p_getter_count++; - v8::Handle<v8::Object> global = Context::GetCurrent()->Global(); + v8::Handle<v8::Object> global = + info.GetIsolate()->GetCurrentContext()->Global(); CHECK_EQ(info.Holder(), global->Get(v8_str("o1"))); if (name->Equals(v8_str("p1"))) { CHECK_EQ(info.This(), global->Get(v8_str("o1"))); @@ -7102,7 +7253,8 @@ static void PGetter2(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); p_getter_count2++; - v8::Handle<v8::Object> global = Context::GetCurrent()->Global(); + v8::Handle<v8::Object> global = + info.GetIsolate()->GetCurrentContext()->Global(); CHECK_EQ(info.Holder(), global->Get(v8_str("o1"))); if (name->Equals(v8_str("p1"))) { CHECK_EQ(info.This(), global->Get(v8_str("o1"))); @@ -7117,7 +7269,7 @@ static void PGetter2(Local<String> name, THREADED_TEST(GetterHolders) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetAccessor(v8_str("p1"), PGetter); obj->SetAccessor(v8_str("p2"), PGetter); @@ -7130,7 +7282,7 @@ THREADED_TEST(GetterHolders) { THREADED_TEST(PreInterceptorHolders) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetNamedPropertyHandler(PGetter2); p_getter_count2 = 0; @@ -7140,19 +7292,20 @@ THREADED_TEST(PreInterceptorHolders) { THREADED_TEST(ObjectInstantiation) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("t"), PGetter2); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); for (int i = 0; i < 100; i++) { - v8::HandleScope inner_scope(v8::Isolate::GetCurrent()); + v8::HandleScope inner_scope(CcTest::isolate()); v8::Handle<v8::Object> obj = templ->NewInstance(); CHECK_NE(obj, context->Global()->Get(v8_str("o"))); context->Global()->Set(v8_str("o2"), obj); v8::Handle<Value> value = Script::Compile(v8_str("o.__proto__ === o2.__proto__"))->Run(); - CHECK_EQ(v8::True(), value); + CHECK_EQ(v8::True(isolate), value); context->Global()->Set(v8_str("o"), obj); } } @@ -7208,7 +7361,7 @@ THREADED_TEST(StringWrite) { "for (var i = 0; i < 0xd800; i += 4) {" " right = String.fromCharCode(i) + right;" "}"); - v8::Handle<v8::Object> global = Context::GetCurrent()->Global(); + v8::Handle<v8::Object> global = context->Global(); Handle<String> left_tree = global->Get(v8_str("left")).As<String>(); Handle<String> right_tree = global->Get(v8_str("right")).As<String>(); @@ -7724,7 +7877,7 @@ static void YSetter(Local<String> name, THREADED_TEST(DeleteAccessor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetAccessor(v8_str("y"), YGetter, YSetter); LocalContext context; @@ -7737,7 +7890,7 @@ THREADED_TEST(DeleteAccessor) { THREADED_TEST(TypeSwitch) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> templ1 = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> templ3 = v8::FunctionTemplate::New(); @@ -7795,7 +7948,8 @@ static void TroubleCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { trouble_nesting++; // Call a JS function that throws an uncaught exception. - Local<v8::Object> arg_this = Context::GetCurrent()->Global(); + Local<v8::Object> arg_this = + args.GetIsolate()->GetCurrentContext()->Global(); Local<Value> trouble_callee = (trouble_nesting == 3) ? arg_this->Get(v8_str("trouble_callee")) : arg_this->Get(v8_str("trouble_caller")); @@ -7907,13 +8061,13 @@ TEST(TryCatchFinallyUsingTryCatchHandler) { // SecurityHandler can't be run twice TEST(SecurityHandler) { - v8::HandleScope scope0(v8::Isolate::GetCurrent()); + v8::HandleScope scope0(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->SetAccessCheckCallbacks(NamedSecurityTestCallback, IndexedSecurityTestCallback); // Create an environment v8::Handle<Context> context0 = - Context::New(v8::Isolate::GetCurrent(), NULL, global_template); + Context::New(CcTest::isolate(), NULL, global_template); context0->Enter(); v8::Handle<v8::Object> global0 = context0->Global(); @@ -7926,10 +8080,10 @@ TEST(SecurityHandler) { CHECK_EQ(999, z0->Int32Value()); // Create another environment, should fail security checks. - v8::HandleScope scope1(v8::Isolate::GetCurrent()); + v8::HandleScope scope1(CcTest::isolate()); v8::Handle<Context> context1 = - Context::New(v8::Isolate::GetCurrent(), NULL, global_template); + Context::New(CcTest::isolate(), NULL, global_template); context1->Enter(); v8::Handle<v8::Object> global1 = context1->Global(); @@ -7947,7 +8101,7 @@ TEST(SecurityHandler) { // Create another environment, should pass security checks. { g_security_callback_result = true; // allow security handler to pass. - v8::HandleScope scope2(v8::Isolate::GetCurrent()); + v8::HandleScope scope2(CcTest::isolate()); LocalContext context2; v8::Handle<v8::Object> global2 = context2->Global(); global2->Set(v8_str("othercontext"), global0); @@ -8317,7 +8471,7 @@ static bool NamedAccessBlocker(Local<v8::Object> global, Local<Value> name, v8::AccessType type, Local<Value> data) { - return Context::GetCurrent()->Global()->Equals(global) || + return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) || allowed_access_type[type]; } @@ -8326,7 +8480,7 @@ static bool IndexedAccessBlocker(Local<v8::Object> global, uint32_t key, v8::AccessType type, Local<Value> data) { - return Context::GetCurrent()->Global()->Equals(global) || + return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) || allowed_access_type[type]; } @@ -8383,7 +8537,7 @@ static void UnreachableFunction( TEST(AccessControl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); @@ -8662,7 +8816,7 @@ TEST(AccessControl) { TEST(AccessControlES5) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); @@ -8749,7 +8903,7 @@ static bool GetOwnPropertyNamesIndexedBlocker(Local<v8::Object> global, THREADED_TEST(AccessControlGetOwnPropertyNames) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(); @@ -8763,7 +8917,7 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) { v8::Handle<v8::Object> global0 = context0->Global(); - v8::HandleScope scope1(v8::Isolate::GetCurrent()); + v8::HandleScope scope1(CcTest::isolate()); v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); @@ -8809,7 +8963,7 @@ static void NamedPropertyEnumerator( THREADED_TEST(GetOwnPropertyNamesWithInterceptor) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(); obj_template->Set(v8_str("7"), v8::Integer::New(7)); @@ -8844,7 +8998,7 @@ static void ConstTenGetter(Local<String> name, THREADED_TEST(CrossDomainAccessors) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(); @@ -8875,7 +9029,7 @@ THREADED_TEST(CrossDomainAccessors) { global->Set(v8_str("accessible"), v8_num(11)); // Enter a new context. - v8::HandleScope scope1(v8::Isolate::GetCurrent()); + v8::HandleScope scope1(CcTest::isolate()); v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); @@ -8921,7 +9075,7 @@ TEST(AccessControlIC) { named_access_count = 0; indexed_access_count = 0; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); // Create an environment. @@ -9069,7 +9223,7 @@ THREADED_TEST(AccessControlFlatten) { named_access_count = 0; indexed_access_count = 0; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); // Create an environment. @@ -9137,7 +9291,7 @@ THREADED_TEST(AccessControlInterceptorIC) { named_access_count = 0; indexed_access_count = 0; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); // Create an environment. @@ -9241,7 +9395,7 @@ static void GlobalObjectInstancePropertiesGet( THREADED_TEST(GlobalObjectInstanceProperties) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); Local<Value> global_object; @@ -9297,7 +9451,7 @@ THREADED_TEST(GlobalObjectInstanceProperties) { THREADED_TEST(CallKnownGlobalReceiver) { - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); Local<Value> global_object; @@ -9376,7 +9530,7 @@ static void ShadowNamedGet(Local<String> key, THREADED_TEST(ShadowObject) { shadow_y = shadow_y_setter_call_count = shadow_y_getter_call_count = 0; - v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); + v8::HandleScope handle_scope(CcTest::isolate()); Local<ObjectTemplate> global_template = v8::ObjectTemplate::New(); LocalContext context(NULL, global_template); @@ -9676,7 +9830,7 @@ THREADED_TEST(SetPrototypeThrows) { v8::TryCatch try_catch; CHECK(!o1->SetPrototype(o0)); CHECK(!try_catch.HasCaught()); - ASSERT(!i::Isolate::Current()->has_pending_exception()); + ASSERT(!CcTest::i_isolate()->has_pending_exception()); CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value()); } @@ -9770,7 +9924,8 @@ static void FakeConstructorCallback( THREADED_TEST(ConstructorForObject) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); instance_template->SetCallAsFunctionHandler(ConstructorCallback); @@ -9819,7 +9974,7 @@ THREADED_TEST(ConstructorForObject) { CHECK(value->IsBoolean()); CHECK_EQ(true, value->BooleanValue()); - Handle<Value> args3[] = { v8::True() }; + Handle<Value> args3[] = { v8::True(isolate) }; Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); CHECK(value_obj3->IsObject()); Local<Object> object3 = Local<Object>::Cast(value_obj3); @@ -9829,7 +9984,7 @@ THREADED_TEST(ConstructorForObject) { CHECK_EQ(true, value->BooleanValue()); // Call the Object's constructor with undefined. - Handle<Value> args4[] = { v8::Undefined() }; + Handle<Value> args4[] = { v8::Undefined(isolate) }; Local<Value> value_obj4 = instance->CallAsConstructor(1, args4); CHECK(value_obj4->IsObject()); Local<Object> object4 = Local<Object>::Cast(value_obj4); @@ -9838,7 +9993,7 @@ THREADED_TEST(ConstructorForObject) { CHECK(value->IsUndefined()); // Call the Object's constructor with null. - Handle<Value> args5[] = { v8::Null() }; + Handle<Value> args5[] = { v8::Null(isolate) }; Local<Value> value_obj5 = instance->CallAsConstructor(1, args5); CHECK(value_obj5->IsObject()); Local<Object> object5 = Local<Object>::Cast(value_obj5); @@ -9997,7 +10152,7 @@ THREADED_TEST(EvalAliasedDynamic) { THREADED_TEST(CrossEval) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); LocalContext other; LocalContext current; @@ -10080,7 +10235,7 @@ THREADED_TEST(CrossEval) { // its global throws an exception. This behavior is consistent with // other JavaScript implementations. THREADED_TEST(EvalInDetachedGlobal) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> context0 = Context::New(isolate); @@ -10113,7 +10268,7 @@ THREADED_TEST(EvalInDetachedGlobal) { THREADED_TEST(CrossLazyLoad) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); LocalContext other; LocalContext current; @@ -10145,6 +10300,11 @@ static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) { } +static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set(args.This()); +} + + // Test that a call handler can be set for objects which will allow // non-function objects created through the API to be called as // functions. @@ -10257,6 +10417,81 @@ THREADED_TEST(CallAsFunction) { CHECK_EQ("23", *exception_value2); try_catch.Reset(); } + + { v8::Isolate* isolate = context->GetIsolate(); + Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + Local<ObjectTemplate> instance_template = t->InstanceTemplate(); + instance_template->SetCallAsFunctionHandler(ReturnThis); + Local<v8::Object> instance = t->GetFunction()->NewInstance(); + + Local<v8::Value> a1 = + instance->CallAsFunction(v8::Undefined(isolate), 0, NULL); + CHECK(a1->StrictEquals(instance)); + Local<v8::Value> a2 = + instance->CallAsFunction(v8::Null(isolate), 0, NULL); + CHECK(a2->StrictEquals(instance)); + Local<v8::Value> a3 = + instance->CallAsFunction(v8_num(42), 0, NULL); + CHECK(a3->StrictEquals(instance)); + Local<v8::Value> a4 = + instance->CallAsFunction(v8_str("hello"), 0, NULL); + CHECK(a4->StrictEquals(instance)); + Local<v8::Value> a5 = + instance->CallAsFunction(v8::True(isolate), 0, NULL); + CHECK(a5->StrictEquals(instance)); + } + + { v8::Isolate* isolate = context->GetIsolate(); + CompileRun( + "function ReturnThisSloppy() {" + " return this;" + "}" + "function ReturnThisStrict() {" + " 'use strict';" + " return this;" + "}"); + Local<Function> ReturnThisSloppy = + Local<Function>::Cast( + context->Global()->Get(v8_str("ReturnThisSloppy"))); + Local<Function> ReturnThisStrict = + Local<Function>::Cast( + context->Global()->Get(v8_str("ReturnThisStrict"))); + + Local<v8::Value> a1 = + ReturnThisSloppy->CallAsFunction(v8::Undefined(isolate), 0, NULL); + CHECK(a1->StrictEquals(context->Global())); + Local<v8::Value> a2 = + ReturnThisSloppy->CallAsFunction(v8::Null(isolate), 0, NULL); + CHECK(a2->StrictEquals(context->Global())); + Local<v8::Value> a3 = + ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); + CHECK(a3->IsNumberObject()); + CHECK_EQ(42.0, a3.As<v8::NumberObject>()->ValueOf()); + Local<v8::Value> a4 = + ReturnThisSloppy->CallAsFunction(v8_str("hello"), 0, NULL); + CHECK(a4->IsStringObject()); + CHECK(a4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); + Local<v8::Value> a5 = + ReturnThisSloppy->CallAsFunction(v8::True(isolate), 0, NULL); + CHECK(a5->IsBooleanObject()); + CHECK(a5.As<v8::BooleanObject>()->ValueOf()); + + Local<v8::Value> a6 = + ReturnThisStrict->CallAsFunction(v8::Undefined(isolate), 0, NULL); + CHECK(a6->IsUndefined()); + Local<v8::Value> a7 = + ReturnThisStrict->CallAsFunction(v8::Null(isolate), 0, NULL); + CHECK(a7->IsNull()); + Local<v8::Value> a8 = + ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); + CHECK(a8->StrictEquals(v8_num(42))); + Local<v8::Value> a9 = + ReturnThisStrict->CallAsFunction(v8_str("hello"), 0, NULL); + CHECK(a9->StrictEquals(v8_str("hello"))); + Local<v8::Value> a10 = + ReturnThisStrict->CallAsFunction(v8::True(isolate), 0, NULL); + CHECK(a10->StrictEquals(v8::True(isolate))); + } } @@ -10309,7 +10544,7 @@ static int CountHandles() { static int Recurse(int depth, int iterations) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); if (depth == 0) return CountHandles(); for (int i = 0; i < iterations; i++) { Local<v8::Number> n(v8::Integer::New(42)); @@ -10323,7 +10558,7 @@ THREADED_TEST(HandleIteration) { static const int kNesting = 200; CHECK_EQ(0, CountHandles()); { - v8::HandleScope scope1(v8::Isolate::GetCurrent()); + v8::HandleScope scope1(CcTest::isolate()); CHECK_EQ(0, CountHandles()); for (int i = 0; i < kIterations; i++) { Local<v8::Number> n(v8::Integer::New(42)); @@ -10332,7 +10567,7 @@ THREADED_TEST(HandleIteration) { CHECK_EQ(kIterations, CountHandles()); { - v8::HandleScope scope2(v8::Isolate::GetCurrent()); + v8::HandleScope scope2(CcTest::isolate()); for (int j = 0; j < kIterations; j++) { Local<v8::Number> n(v8::Integer::New(42)); CHECK_EQ(j + 1 + kIterations, CountHandles()); @@ -10379,7 +10614,7 @@ static void InterceptorHasOwnPropertyGetterGC( Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -10420,7 +10655,7 @@ typedef void (*NamedPropertyGetter)( static void CheckInterceptorLoadIC(NamedPropertyGetter getter, const char* source, int expected) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(getter, 0, 0, 0, 0, v8_str("data")); LocalContext context; @@ -10434,7 +10669,7 @@ static void InterceptorLoadICGetter( Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(v8_str("data"), info.Data()); CHECK_EQ(v8_str("x"), name); @@ -10633,7 +10868,7 @@ static void SetOnThis(Local<String> name, THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorLoadXICGetter); templ->SetAccessor(v8_str("y"), Return239Callback); @@ -10662,7 +10897,7 @@ THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); @@ -10695,7 +10930,7 @@ THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorLoadXICGetter); templ->SetAccessor(v8_str("y"), Return239Callback); @@ -10723,7 +10958,7 @@ THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { // Test the case when we stored callback into // a stub, but interceptor produced value on its own. THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); @@ -10751,7 +10986,7 @@ THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { // Test the case when we stored callback into // a stub, but it got invalidated later on. THREADED_TEST(InterceptorLoadICInvalidatedCallback) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); @@ -10783,7 +11018,7 @@ THREADED_TEST(InterceptorLoadICInvalidatedCallback) { // a stub, but it got invalidated later on due to override on // global object which is between interceptor and callbacks' holders. THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); @@ -10838,7 +11073,7 @@ static void InterceptorStoreICSetter( // This test should hit the store IC for the interceptor case. THREADED_TEST(InterceptorStoreIC) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorLoadICGetter, InterceptorStoreICSetter, @@ -10853,7 +11088,7 @@ THREADED_TEST(InterceptorStoreIC) { THREADED_TEST(InterceptorStoreICWithNoSetter) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorLoadXICGetter); LocalContext context; @@ -10884,7 +11119,7 @@ static void InterceptorCallICGetter( // This test should hit the call IC for the interceptor case. THREADED_TEST(InterceptorCallIC) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorCallICGetter); LocalContext context; @@ -10903,7 +11138,7 @@ THREADED_TEST(InterceptorCallIC) { // This test checks that if interceptor doesn't provide // a value, we can fetch regular value. THREADED_TEST(InterceptorCallICSeesOthers) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -10932,7 +11167,7 @@ static void InterceptorCallICGetter4( // even if we cached shadowed variant, interceptor's function // is invoked THREADED_TEST(InterceptorCallICCacheableNotNeeded) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorCallICGetter4); LocalContext context; @@ -10952,7 +11187,7 @@ THREADED_TEST(InterceptorCallICCacheableNotNeeded) { // Test the case when we stored cacheable lookup into // a stub, but it got invalidated later on THREADED_TEST(InterceptorCallICInvalidatedCacheable) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -10979,7 +11214,7 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) { // This test checks that if interceptor doesn't provide a function, // cached constant function is used THREADED_TEST(InterceptorCallICConstantFunctionUsed) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11010,7 +11245,7 @@ static void InterceptorCallICGetter5( // even if we cached constant function, interceptor's function // is invoked THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorCallICGetter5); LocalContext context; @@ -11043,7 +11278,7 @@ static void InterceptorCallICGetter6( // to test the optimized compiler. THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorCallICGetter6); LocalContext context; @@ -11073,7 +11308,7 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { // Test the case when we stored constant function into // a stub, but it got invalidated later on THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11103,7 +11338,7 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { // a stub, but it got invalidated later on due to override on // global object which is between interceptor and constant function' holders. THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11128,7 +11363,7 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { // Test the case when actual function to call sits on global object. THREADED_TEST(InterceptorCallICCachedFromGlobal) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(NoBlockGetterX); @@ -11163,7 +11398,7 @@ static void InterceptorCallICFastApi( reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value()); ++(*call_count); if ((*call_count) % 20 == 0) { - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } } @@ -11171,7 +11406,7 @@ static void FastApiCallback_TrivialSignature( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); CheckReturnValue(args, FUNCTION_ADDR(FastApiCallback_TrivialSignature)); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, args.GetIsolate()); CHECK_EQ(args.This(), args.Holder()); CHECK(args.Data()->Equals(v8_str("method_data"))); @@ -11182,7 +11417,7 @@ static void FastApiCallback_SimpleSignature( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); CheckReturnValue(args, FUNCTION_ADDR(FastApiCallback_SimpleSignature)); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, args.GetIsolate()); CHECK_EQ(args.This()->GetPrototype(), args.Holder()); CHECK(args.Data()->Equals(v8_str("method_data"))); @@ -11207,7 +11442,7 @@ static void GenerateSomeGarbage() { void DirectApiCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { static int count = 0; if (count++ % 3 == 0) { - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); // This should move the stub GenerateSomeGarbage(); // This should ensure the old stub memory is flushed } @@ -11235,7 +11470,7 @@ THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { void ThrowingDirectApiCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::ThrowException(v8_str("g")); + args.GetIsolate()->ThrowException(v8_str("g")); } @@ -11262,7 +11497,7 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) { static Handle<Value> DoDirectGetter() { if (++p_getter_count % 3 == 0) { - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); GenerateSomeGarbage(); } return v8_str("Direct Getter Result"); @@ -11303,7 +11538,7 @@ THREADED_PROFILED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { void ThrowingDirectGetterCallback( Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { - v8::ThrowException(v8_str("g")); + info.GetIsolate()->ThrowException(v8_str("g")); } @@ -11325,7 +11560,7 @@ THREADED_TEST(LoadICFastApi_DirectCall_Throw) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_TrivialSignature) { int interceptor_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, @@ -11353,7 +11588,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_TrivialSignature) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { int interceptor_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11385,7 +11620,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { int interceptor_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11423,7 +11658,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { int interceptor_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11461,7 +11696,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { int interceptor_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11502,7 +11737,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { int interceptor_call_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11542,7 +11777,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, @@ -11567,7 +11802,7 @@ THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11596,7 +11831,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11630,7 +11865,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11667,7 +11902,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, @@ -11718,7 +11953,7 @@ static void InterceptorKeyedCallICGetter( // Test the case when we stored cacheable lookup into // a stub, but the function name changed (to another cacheable function). THREADED_TEST(InterceptorKeyedCallICKeyChange1) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11742,7 +11977,7 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange1) { // a stub, but the function name changed (and the new function is present // both before and after the interceptor in the prototype chain). THREADED_TEST(InterceptorKeyedCallICKeyChange2) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorKeyedCallICGetter); LocalContext context; @@ -11769,7 +12004,7 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange2) { // Same as InterceptorKeyedCallICKeyChange1 only the cacheable function sit // on the global object. THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11794,7 +12029,7 @@ THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { // Test the case when actual function to call sits on global object. THREADED_TEST(InterceptorKeyedCallICFromGlobal) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11819,7 +12054,7 @@ THREADED_TEST(InterceptorKeyedCallICFromGlobal) { // Test the map transition before the interceptor. THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11841,7 +12076,7 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { // Test the map transition after the interceptor. THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11877,7 +12112,7 @@ static void InterceptorICRefErrorGetter( // Once in a while, the interceptor will reply that a property was not // found in which case we should get a reference error. THREADED_TEST(InterceptorICReferenceErrors) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorICRefErrorGetter); LocalContext context(0, templ, v8::Handle<Value>()); @@ -11914,7 +12149,7 @@ static void InterceptorICExceptionGetter( info.GetReturnValue().Set(call_ic_function3); } if (interceptor_ic_exception_get_count == 20) { - v8::ThrowException(v8_num(42)); + info.GetIsolate()->ThrowException(v8_num(42)); return; } } @@ -11924,7 +12159,7 @@ static void InterceptorICExceptionGetter( // exception once in a while. THREADED_TEST(InterceptorICGetterExceptions) { interceptor_ic_exception_get_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(InterceptorICExceptionGetter); LocalContext context(0, templ, v8::Handle<Value>()); @@ -11959,7 +12194,7 @@ static void InterceptorICExceptionSetter( const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); if (++interceptor_ic_exception_set_count > 20) { - v8::ThrowException(v8_num(42)); + info.GetIsolate()->ThrowException(v8_num(42)); } } @@ -11968,7 +12203,7 @@ static void InterceptorICExceptionSetter( // once in a while. THREADED_TEST(InterceptorICSetterExceptions) { interceptor_ic_exception_set_count = 0; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter); LocalContext context(0, templ, v8::Handle<Value>()); @@ -11986,7 +12221,7 @@ THREADED_TEST(InterceptorICSetterExceptions) { // Test that we ignore null interceptors. THREADED_TEST(NullNamedInterceptor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler( static_cast<v8::NamedPropertyGetterCallback>(0)); @@ -12002,7 +12237,7 @@ THREADED_TEST(NullNamedInterceptor) { // Test that we ignore null interceptors. THREADED_TEST(NullIndexedInterceptor) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler( static_cast<v8::IndexedPropertyGetterCallback>(0)); @@ -12017,7 +12252,7 @@ THREADED_TEST(NullIndexedInterceptor) { THREADED_TEST(NamedPropertyHandlerGetterAttributes) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetNamedPropertyHandler(InterceptorLoadXICGetter); LocalContext env; @@ -12031,7 +12266,7 @@ THREADED_TEST(NamedPropertyHandlerGetterAttributes) { static void ThrowingGetter(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - ThrowException(Handle<Value>()); + info.GetIsolate()->ThrowException(Handle<Value>()); info.GetReturnValue().SetUndefined(); } @@ -12097,8 +12332,8 @@ static void ThrowingCallbackWithTryCatch( try_catch.SetVerbose(true); CompileRun("throw 'from JS';"); CHECK(try_catch.HasCaught()); - CHECK(!i::Isolate::Current()->has_pending_exception()); - CHECK(!i::Isolate::Current()->has_scheduled_exception()); + CHECK(!CcTest::i_isolate()->has_pending_exception()); + CHECK(!CcTest::i_isolate()->has_scheduled_exception()); } @@ -12116,7 +12351,7 @@ static void ThrowFromJS(Handle<Message> message, Handle<Value> data) { static void ThrowViaApi(Handle<Message> message, Handle<Value> data) { - if (--call_depth) ThrowException(v8_str("ThrowViaApi")); + if (--call_depth) CcTest::isolate()->ThrowException(v8_str("ThrowViaApi")); } @@ -12237,7 +12472,7 @@ static void IsConstructHandler( THREADED_TEST(IsConstructCall) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); // Function template with call handler. Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); @@ -12254,7 +12489,7 @@ THREADED_TEST(IsConstructCall) { THREADED_TEST(ObjectProtoToString) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->SetClassName(v8_str("MyClass")); @@ -12354,7 +12589,7 @@ void ApiTestFuzzer::Run() { gate_.Wait(); { // ... get the V8 lock and start running the test. - v8::Locker locker(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); CallTest(); } // This test finished. @@ -12418,7 +12653,7 @@ void ApiTestFuzzer::ContextSwitch() { // If the new thread is the same as the current thread there is nothing to do. if (NextThread()) { // Now it can start. - v8::Unlocker unlocker(CcTest::default_isolate()); + v8::Unlocker unlocker(CcTest::isolate()); // Wait till someone starts us again. gate_.Wait(); // And we're off. @@ -12465,6 +12700,7 @@ TEST(Threading4) { void ApiTestFuzzer::CallTest() { + v8::Isolate::Scope scope(CcTest::isolate()); if (kLogThreading) printf("Start test %d\n", test_number_); CallTestNumber(test_number_); @@ -12474,13 +12710,14 @@ void ApiTestFuzzer::CallTest() { static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(v8::Locker::IsLocked(CcTest::default_isolate())); + v8::Isolate* isolate = args.GetIsolate(); + CHECK(v8::Locker::IsLocked(isolate)); ApiTestFuzzer::Fuzz(); - v8::Unlocker unlocker(CcTest::default_isolate()); + v8::Unlocker unlocker(isolate); const char* code = "throw 7;"; { - v8::Locker nested_locker(CcTest::default_isolate()); - v8::HandleScope scope(args.GetIsolate()); + v8::Locker nested_locker(isolate); + v8::HandleScope scope(isolate); v8::Handle<Value> exception; { v8::TryCatch try_catch; v8::Handle<Value> value = CompileRun(code); @@ -12489,20 +12726,20 @@ static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) { // Make sure to wrap the exception in a new handle because // the handle returned from the TryCatch is destroyed // when the TryCatch is destroyed. - exception = Local<Value>::New(try_catch.Exception()); + exception = Local<Value>::New(isolate, try_catch.Exception()); } - v8::ThrowException(exception); + args.GetIsolate()->ThrowException(exception); } } static void ThrowInJSNoCatch(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(v8::Locker::IsLocked(CcTest::default_isolate())); + CHECK(v8::Locker::IsLocked(CcTest::isolate())); ApiTestFuzzer::Fuzz(); - v8::Unlocker unlocker(CcTest::default_isolate()); + v8::Unlocker unlocker(CcTest::isolate()); const char* code = "throw 7;"; { - v8::Locker nested_locker(CcTest::default_isolate()); + v8::Locker nested_locker(CcTest::isolate()); v8::HandleScope scope(args.GetIsolate()); v8::Handle<Value> value = CompileRun(code); CHECK(value.IsEmpty()); @@ -12514,8 +12751,8 @@ static void ThrowInJSNoCatch(const v8::FunctionCallbackInfo<v8::Value>& args) { // These are locking tests that don't need to be run again // as part of the locking aggregation tests. TEST(NestedLockers) { - v8::Locker locker(CcTest::default_isolate()); - CHECK(v8::Locker::IsLocked(CcTest::default_isolate())); + v8::Locker locker(CcTest::isolate()); + CHECK(v8::Locker::IsLocked(CcTest::isolate())); LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(ThrowInJS); @@ -12536,7 +12773,7 @@ TEST(NestedLockers) { // These are locking tests that don't need to be run again // as part of the locking aggregation tests. TEST(NestedLockersNoTryCatch) { - v8::Locker locker(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = @@ -12556,24 +12793,24 @@ TEST(NestedLockersNoTryCatch) { THREADED_TEST(RecursiveLocking) { - v8::Locker locker(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); { - v8::Locker locker2(CcTest::default_isolate()); - CHECK(v8::Locker::IsLocked(CcTest::default_isolate())); + v8::Locker locker2(CcTest::isolate()); + CHECK(v8::Locker::IsLocked(CcTest::isolate())); } } static void UnlockForAMoment(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); - v8::Unlocker unlocker(CcTest::default_isolate()); + v8::Unlocker unlocker(CcTest::isolate()); } THREADED_TEST(LockUnlockLock) { { - v8::Locker locker(CcTest::default_isolate()); - v8::HandleScope scope(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); + v8::HandleScope scope(CcTest::isolate()); LocalContext env; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(UnlockForAMoment); @@ -12586,8 +12823,8 @@ THREADED_TEST(LockUnlockLock) { CHECK_EQ(42, script->Run()->Int32Value()); } { - v8::Locker locker(CcTest::default_isolate()); - v8::HandleScope scope(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); + v8::HandleScope scope(CcTest::isolate()); LocalContext env; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(UnlockForAMoment); @@ -12603,9 +12840,9 @@ THREADED_TEST(LockUnlockLock) { static int GetGlobalObjectsCount() { - i::Isolate::Current()->heap()->EnsureHeapIsIterable(); + CcTest::heap()->EnsureHeapIsIterable(); int count = 0; - i::HeapIterator it(HEAP); + i::HeapIterator it(CcTest::heap()); for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) if (object->IsJSGlobalObject()) count++; return count; @@ -12618,11 +12855,11 @@ static void CheckSurvivingGlobalObjectsCount(int expected) { // the first garbage collection but some of the maps have already // been marked at that point. Therefore some of the maps are not // collected until the second garbage collection. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); int count = GetGlobalObjectsCount(); #ifdef DEBUG - if (count != expected) HEAP->TracePathToGlobal(); + if (count != expected) CcTest::heap()->TracePathToGlobal(); #endif CHECK_EQ(expected, count); } @@ -12634,27 +12871,27 @@ TEST(DontLeakGlobalObjects) { v8::V8::Initialize(); for (int i = 0; i < 5; i++) { - { v8::HandleScope scope(v8::Isolate::GetCurrent()); + { v8::HandleScope scope(CcTest::isolate()); LocalContext context; } v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); - { v8::HandleScope scope(v8::Isolate::GetCurrent()); + { v8::HandleScope scope(CcTest::isolate()); LocalContext context; v8_compile("Date")->Run(); } v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); - { v8::HandleScope scope(v8::Isolate::GetCurrent()); + { v8::HandleScope scope(CcTest::isolate()); LocalContext context; v8_compile("/aaa/")->Run(); } v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); - { v8::HandleScope scope(v8::Isolate::GetCurrent()); + { v8::HandleScope scope(CcTest::isolate()); const char* extension_list[] = { "v8/gc" }; v8::ExtensionConfiguration extensions(1, extension_list); LocalContext context(&extensions); @@ -12665,17 +12902,6 @@ TEST(DontLeakGlobalObjects) { } } -template<class T> -struct CopyablePersistentTraits { - typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent; - static const bool kResetInDestructor = true; - template<class S, class M> - static V8_INLINE void Copy(const Persistent<S, M>& source, - CopyablePersistent* dest) { - // do nothing, just allow copy - } -}; - TEST(CopyablePersistent) { LocalContext context; @@ -12683,19 +12909,20 @@ TEST(CopyablePersistent) { i::GlobalHandles* globals = reinterpret_cast<i::Isolate*>(isolate)->global_handles(); int initial_handles = globals->global_handles_count(); + typedef v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > + CopyableObject; { - v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > handle1; + CopyableObject handle1; { v8::HandleScope scope(isolate); handle1.Reset(isolate, v8::Object::New()); } CHECK_EQ(initial_handles + 1, globals->global_handles_count()); - v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > handle2; + CopyableObject handle2; handle2 = handle1; CHECK(handle1 == handle2); CHECK_EQ(initial_handles + 2, globals->global_handles_count()); - v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > - handle3(handle2); + CopyableObject handle3(handle2); CHECK(handle1 == handle3); CHECK_EQ(initial_handles + 3, globals->global_handles_count()); } @@ -12764,7 +12991,7 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) { // weak callback of the first handle would be able to 'reallocate' it. handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback); handle2.Dispose(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -12774,7 +13001,7 @@ void DisposeAndForceGcCallback(v8::Isolate* isolate, v8::Persistent<v8::Value>* handle, void*) { to_be_disposed.Dispose(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); handle->Dispose(); } @@ -12791,7 +13018,7 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { } handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback); to_be_disposed.Reset(isolate, handle2); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } void DisposingCallback(v8::Isolate* isolate, @@ -12822,7 +13049,7 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { } handle2.MakeWeak<v8::Value, void>(NULL, DisposingCallback); handle3.MakeWeak<v8::Value, void>(NULL, HandleCreatingCallback); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -12837,11 +13064,11 @@ THREADED_TEST(CheckForCrossContextObjectLiterals) { for (int i = 0; i < nof; i++) { const char* source = sources[i]; - { v8::HandleScope scope(v8::Isolate::GetCurrent()); + { v8::HandleScope scope(CcTest::isolate()); LocalContext context; CompileRun(source); } - { v8::HandleScope scope(v8::Isolate::GetCurrent()); + { v8::HandleScope scope(CcTest::isolate()); LocalContext context; CompileRun(source); } @@ -12860,7 +13087,7 @@ static v8::Handle<Value> NestedScope(v8::Local<Context> env) { THREADED_TEST(NestedHandleScopeAndContexts) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer(isolate); v8::Local<Context> env = Context::New(isolate); env->Enter(); @@ -13354,7 +13581,7 @@ static void event_handler(const v8::JitCodeEvent* event) { } -TEST(SetJitCodeEventHandler) { +UNINITIALIZED_TEST(SetJitCodeEventHandler) { i::FLAG_stress_compaction = true; i::FLAG_incremental_marking = false; const char* script = @@ -13371,6 +13598,7 @@ TEST(SetJitCodeEventHandler) { // have remnants of state from other code. v8::Isolate* isolate = v8::Isolate::New(); isolate->Enter(); + i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap(); { v8::HandleScope scope(isolate); @@ -13389,9 +13617,9 @@ TEST(SetJitCodeEventHandler) { // different fragmented code-space pages. const int kIterations = 10; for (int i = 0; i < kIterations; ++i) { - LocalContext env; + LocalContext env(isolate); i::AlwaysAllocateScope always_allocate; - SimulateFullSpace(HEAP->code_space()); + SimulateFullSpace(heap->code_space()); CompileRun(script); // Keep a strong reference to the code object in the handle scope. @@ -13405,7 +13633,7 @@ TEST(SetJitCodeEventHandler) { } // Force code movement. - HEAP->CollectAllAvailableGarbage("TestSetJitCodeEventHandler"); + heap->CollectAllAvailableGarbage("TestSetJitCodeEventHandler"); V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL); @@ -13427,7 +13655,7 @@ TEST(SetJitCodeEventHandler) { // request enumeration of existing code. { v8::HandleScope scope(isolate); - LocalContext env; + LocalContext env(isolate); CompileRun(script); // Now get code through initial iteration. @@ -13459,7 +13687,7 @@ static int64_t cast(intptr_t x) { return static_cast<int64_t>(x); } THREADED_TEST(ExternalAllocatedMemory) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer(isolate); v8::Local<Context> env(Context::New(isolate)); CHECK(!env.IsEmpty()); @@ -13472,28 +13700,6 @@ THREADED_TEST(ExternalAllocatedMemory) { } -THREADED_TEST(DisposeEnteredContext) { - LocalContext outer; - v8::Isolate* isolate = outer->GetIsolate(); - v8::Persistent<v8::Context> inner; - { - v8::HandleScope scope(isolate); - inner.Reset(isolate, v8::Context::New(isolate)); - } - v8::HandleScope scope(isolate); - { - // Don't want a handle here, so do this unsafely - v8::Handle<v8::Context> inner_local = - v8::Utils::Convert<i::Object, v8::Context>( - v8::Utils::OpenPersistent(inner)); - inner_local->Enter(); - inner.Dispose(); - inner.Clear(); - inner_local->Exit(); - } -} - - // Regression test for issue 54, object templates with internal fields // but no accessors or interceptors did not get their internal field // count set on instances. @@ -13534,7 +13740,7 @@ TEST(CatchStackOverflow) { static void CheckTryCatchSourceInfo(v8::Handle<v8::Script> script, const char* resource_name, int line_offset) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::TryCatch try_catch; v8::Handle<v8::Value> result = script->Run(); CHECK(result.IsEmpty()); @@ -13738,11 +13944,12 @@ static bool IndexedSetAccessBlocker(Local<v8::Object> obj, THREADED_TEST(DisableAccessChecksWhileConfiguring) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessCheckCallbacks(NamedSetAccessBlocker, IndexedSetAccessBlocker); - templ->Set(v8_str("x"), v8::True()); + templ->Set(v8_str("x"), v8::True(isolate)); Local<v8::Object> instance = templ->NewInstance(); context->Global()->Set(v8_str("obj"), instance); Local<Value> value = CompileRun("obj.x"); @@ -13807,7 +14014,7 @@ THREADED_TEST(AccessChecksReenabledCorrectly) { // This tests that access check information remains on the global // object template when creating contexts. THREADED_TEST(AccessControlRepeatedContextCreation) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->SetAccessCheckCallbacks(NamedSetAccessBlocker, @@ -13825,7 +14032,7 @@ THREADED_TEST(AccessControlRepeatedContextCreation) { THREADED_TEST(TurnOnAccessCheck) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); // Create an environment with access check to the global object disabled by @@ -13906,7 +14113,7 @@ static bool NamedGetAccessBlockAandH(Local<v8::Object> obj, THREADED_TEST(TurnOnAccessCheckAndRecompile) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); // Create an environment with access check to the global object disabled by @@ -13999,9 +14206,10 @@ TEST(PreCompile) { // TODO(155): This test would break without the initialization of V8. This is // a workaround for now to make this test not fail. v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); const char* script = "function foo(a) { return a+1; }"; v8::ScriptData* sd = - v8::ScriptData::PreCompile(script, i::StrLength(script)); + v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); CHECK_NE(sd->Length(), 0); CHECK_NE(sd->Data(), NULL); CHECK(!sd->HasError()); @@ -14011,9 +14219,10 @@ TEST(PreCompile) { TEST(PreCompileWithError) { v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); const char* script = "function foo(a) { return 1 * * 2; }"; v8::ScriptData* sd = - v8::ScriptData::PreCompile(script, i::StrLength(script)); + v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); CHECK(sd->HasError()); delete sd; } @@ -14021,9 +14230,10 @@ TEST(PreCompileWithError) { TEST(Regress31661) { v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); const char* script = " The Definintive Guide"; v8::ScriptData* sd = - v8::ScriptData::PreCompile(script, i::StrLength(script)); + v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); CHECK(sd->HasError()); delete sd; } @@ -14032,9 +14242,10 @@ TEST(Regress31661) { // Tests that ScriptData can be serialized and deserialized. TEST(PreCompileSerialization) { v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); const char* script = "function foo(a) { return a+1; }"; v8::ScriptData* sd = - v8::ScriptData::PreCompile(script, i::StrLength(script)); + v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); // Serialize. int serialized_data_length = sd->Length(); @@ -14071,13 +14282,14 @@ TEST(PreCompileDeserializationError) { // Attempts to deserialize bad data. TEST(PreCompileInvalidPreparseDataError) { v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); LocalContext context; v8::HandleScope scope(context->GetIsolate()); const char* script = "function foo(){ return 5;}\n" "function bar(){ return 6 + 7;} foo();"; v8::ScriptData* sd = - v8::ScriptData::PreCompile(script, i::StrLength(script)); + v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); CHECK(!sd->HasError()); // ScriptDataImpl private implementation details const int kHeaderSize = i::PreparseDataConstants::kHeaderSize; @@ -14103,7 +14315,7 @@ TEST(PreCompileInvalidPreparseDataError) { // Overwrite function bar's start position with 200. The function entry // will not be found when searching for it by position and we should fall // back on eager compilation. - sd = v8::ScriptData::PreCompile(script, i::StrLength(script)); + sd = v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data())); sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] = 200; @@ -14118,12 +14330,13 @@ TEST(PreCompileInvalidPreparseDataError) { // the same results (at least for one trivial case). TEST(PreCompileAPIVariationsAreSame) { v8::V8::Initialize(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); const char* cstring = "function foo(a) { return a+1; }"; v8::ScriptData* sd_from_cstring = - v8::ScriptData::PreCompile(cstring, i::StrLength(cstring)); + v8::ScriptData::PreCompile(isolate, cstring, i::StrLength(cstring)); TestAsciiResource* resource = new TestAsciiResource(cstring); v8::ScriptData* sd_from_external_string = v8::ScriptData::PreCompile( @@ -14155,18 +14368,18 @@ TEST(PreCompileAPIVariationsAreSame) { // arise because we share code between contexts via the compilation // cache. THREADED_TEST(DictionaryICLoadedFunction) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); // Test LoadIC. for (int i = 0; i < 2; i++) { LocalContext context; - context->Global()->Set(v8_str("tmp"), v8::True()); + context->Global()->Set(v8_str("tmp"), v8::True(CcTest::isolate())); context->Global()->Delete(v8_str("tmp")); CompileRun("for (var j = 0; j < 10; j++) new RegExp('');"); } // Test CallIC. for (int i = 0; i < 2; i++) { LocalContext context; - context->Global()->Set(v8_str("tmp"), v8::True()); + context->Global()->Set(v8_str("tmp"), v8::True(CcTest::isolate())); context->Global()->Delete(v8_str("tmp")); CompileRun("for (var j = 0; j < 10; j++) RegExp('')"); } @@ -14176,7 +14389,7 @@ THREADED_TEST(DictionaryICLoadedFunction) { // Test that cross-context new calls use the context of the callee to // create the new JavaScript object. THREADED_TEST(CrossContextNew) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> context0 = Context::New(isolate); v8::Local<Context> context1 = Context::New(isolate); @@ -14203,128 +14416,6 @@ THREADED_TEST(CrossContextNew) { } -class RegExpInterruptTest { - public: - RegExpInterruptTest() : block_(0) {} - ~RegExpInterruptTest() {} - void RunTest() { - gc_count_ = 0; - gc_during_regexp_ = 0; - regexp_success_ = false; - gc_success_ = false; - GCThread gc_thread(this); - gc_thread.Start(); - v8::Locker::StartPreemption(1); - - LongRunningRegExp(); - { - v8::Unlocker unlock(CcTest::default_isolate()); - gc_thread.Join(); - } - v8::Locker::StopPreemption(); - CHECK(regexp_success_); - CHECK(gc_success_); - } - - private: - // Number of garbage collections required. - static const int kRequiredGCs = 5; - - class GCThread : public i::Thread { - public: - explicit GCThread(RegExpInterruptTest* test) - : Thread("GCThread"), test_(test) {} - virtual void Run() { - test_->CollectGarbage(); - } - private: - RegExpInterruptTest* test_; - }; - - void CollectGarbage() { - block_.Wait(); - while (gc_during_regexp_ < kRequiredGCs) { - { - v8::Locker lock(CcTest::default_isolate()); - // TODO(lrn): Perhaps create some garbage before collecting. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - gc_count_++; - } - i::OS::Sleep(1); - } - gc_success_ = true; - } - - void LongRunningRegExp() { - block_.Signal(); // Enable garbage collection thread on next preemption. - int rounds = 0; - while (gc_during_regexp_ < kRequiredGCs) { - int gc_before = gc_count_; - { - // Match 15-30 "a"'s against 14 and a "b". - const char* c_source = - "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/" - ".exec('aaaaaaaaaaaaaaab') === null"; - Local<String> source = String::New(c_source); - Local<Script> script = Script::Compile(source); - Local<Value> result = script->Run(); - if (!result->BooleanValue()) { - gc_during_regexp_ = kRequiredGCs; // Allow gc thread to exit. - return; - } - } - { - // Match 15-30 "a"'s against 15 and a "b". - const char* c_source = - "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/" - ".exec('aaaaaaaaaaaaaaaab')[0] === 'aaaaaaaaaaaaaaaa'"; - Local<String> source = String::New(c_source); - Local<Script> script = Script::Compile(source); - Local<Value> result = script->Run(); - if (!result->BooleanValue()) { - gc_during_regexp_ = kRequiredGCs; - return; - } - } - int gc_after = gc_count_; - gc_during_regexp_ += gc_after - gc_before; - rounds++; - i::OS::Sleep(1); - } - regexp_success_ = true; - } - - i::Semaphore block_; - int gc_count_; - int gc_during_regexp_; - bool regexp_success_; - bool gc_success_; -}; - - -// Test that a regular expression execution can be interrupted and -// survive a garbage collection. -TEST(RegExpInterruption) { - v8::Locker lock(CcTest::default_isolate()); - v8::V8::Initialize(); - v8::HandleScope scope(CcTest::default_isolate()); - Local<Context> local_env; - { - LocalContext env; - local_env = env.local(); - } - - // Local context should still be live. - CHECK(!local_env.IsEmpty()); - local_env->Enter(); - - // Should complete without problems. - RegExpInterruptTest().RunTest(); - - local_env->Exit(); -} - - class ApplyInterruptTest { public: ApplyInterruptTest() : block_(0) {} @@ -14336,14 +14427,15 @@ class ApplyInterruptTest { gc_success_ = false; GCThread gc_thread(this); gc_thread.Start(); - v8::Locker::StartPreemption(1); + v8::Isolate* isolate = CcTest::isolate(); + v8::Locker::StartPreemption(isolate, 1); LongRunningApply(); { - v8::Unlocker unlock(CcTest::default_isolate()); + v8::Unlocker unlock(isolate); gc_thread.Join(); } - v8::Locker::StopPreemption(); + v8::Locker::StopPreemption(isolate); CHECK(apply_success_); CHECK(gc_success_); } @@ -14367,8 +14459,9 @@ class ApplyInterruptTest { block_.Wait(); while (gc_during_apply_ < kRequiredGCs) { { - v8::Locker lock(CcTest::default_isolate()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + v8::Locker lock(CcTest::isolate()); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); gc_count_++; } i::OS::Sleep(1); @@ -14413,9 +14506,9 @@ class ApplyInterruptTest { // Test that nothing bad happens if we get a preemption just when we were // about to do an apply(). TEST(ApplyInterruption) { - v8::Locker lock(CcTest::default_isolate()); + v8::Locker lock(CcTest::isolate()); v8::V8::Initialize(); - v8::HandleScope scope(CcTest::default_isolate()); + v8::HandleScope scope(CcTest::isolate()); Local<Context> local_env; { LocalContext env; @@ -14497,17 +14590,17 @@ static void MorphAString(i::String* string, CHECK(i::StringShape(string).IsExternal()); if (string->IsOneByteRepresentation()) { // Check old map is not internalized or long. - CHECK(string->map() == HEAP->external_ascii_string_map()); + CHECK(string->map() == CcTest::heap()->external_ascii_string_map()); // Morph external string to be TwoByte string. - string->set_map(HEAP->external_string_map()); + string->set_map(CcTest::heap()->external_string_map()); i::ExternalTwoByteString* morphed = i::ExternalTwoByteString::cast(string); morphed->set_resource(uc16_resource); } else { // Check old map is not internalized or long. - CHECK(string->map() == HEAP->external_string_map()); + CHECK(string->map() == CcTest::heap()->external_string_map()); // Morph external string to be ASCII string. - string->set_map(HEAP->external_ascii_string_map()); + string->set_map(CcTest::heap()->external_ascii_string_map()); i::ExternalAsciiString* morphed = i::ExternalAsciiString::cast(string); morphed->set_resource(ascii_resource); @@ -14524,7 +14617,7 @@ THREADED_TEST(MorphCompositeStringTest) { uint16_t* two_byte_string = AsciiToTwoByteString(c_string); { LocalContext env; - i::Factory* factory = i::Isolate::Current()->factory(); + i::Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(env->GetIsolate()); AsciiVectorResource ascii_resource( i::Vector<const char>(c_string, i::StrLength(c_string))); @@ -14612,148 +14705,85 @@ TEST(CompileExternalTwoByteSource) { } -class RegExpStringModificationTest { - public: - RegExpStringModificationTest() - : block_(0), - morphs_(0), - morphs_during_regexp_(0), - ascii_resource_(i::Vector<const char>("aaaaaaaaaaaaaab", 15)), - uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {} - ~RegExpStringModificationTest() {} - void RunTest() { - i::Factory* factory = i::Isolate::Current()->factory(); +#ifndef V8_INTERPRETED_REGEXP - regexp_success_ = false; - morph_success_ = false; +struct RegExpInterruptionData { + int loop_count; + UC16VectorResource* string_resource; + v8::Persistent<v8::String> string; +} regexp_interruption_data; - // Initialize the contents of two_byte_content_ to be a uc16 representation - // of "aaaaaaaaaaaaaab". - for (int i = 0; i < 14; i++) { - two_byte_content_[i] = 'a'; - } - two_byte_content_[14] = 'b'; - - // Create the input string for the regexp - the one we are going to change - // properties of. - input_ = factory->NewExternalStringFromAscii(&ascii_resource_); - - // Inject the input as a global variable. - i::Handle<i::String> input_name = - factory->NewStringFromAscii(i::Vector<const char>("input", 5)); - i::Isolate::Current()->native_context()->global_object()->SetProperty( - *input_name, - *input_, - NONE, - i::kNonStrictMode)->ToObjectChecked(); - - MorphThread morph_thread(this); - morph_thread.Start(); - v8::Locker::StartPreemption(1); - LongRunningRegExp(); - { - v8::Unlocker unlock(CcTest::default_isolate()); - morph_thread.Join(); + +class RegExpInterruptionThread : public i::Thread { + public: + explicit RegExpInterruptionThread(v8::Isolate* isolate) + : Thread("TimeoutThread"), isolate_(isolate) {} + + virtual void Run() { + for (regexp_interruption_data.loop_count = 0; + regexp_interruption_data.loop_count < 7; + regexp_interruption_data.loop_count++) { + i::OS::Sleep(50); // Wait a bit before requesting GC. + reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC(); } - v8::Locker::StopPreemption(); - CHECK(regexp_success_); - CHECK(morph_success_); + i::OS::Sleep(50); // Wait a bit before terminating. + v8::V8::TerminateExecution(isolate_); } private: - // Number of string modifications required. - static const int kRequiredModifications = 5; - static const int kMaxModifications = 100; + v8::Isolate* isolate_; +}; - class MorphThread : public i::Thread { - public: - explicit MorphThread(RegExpStringModificationTest* test) - : Thread("MorphThread"), test_(test) {} - virtual void Run() { - test_->MorphString(); - } - private: - RegExpStringModificationTest* test_; - }; - void MorphString() { - block_.Wait(); - while (morphs_during_regexp_ < kRequiredModifications && - morphs_ < kMaxModifications) { - { - v8::Locker lock(CcTest::default_isolate()); - // Swap string between ascii and two-byte representation. - i::String* string = *input_; - MorphAString(string, &ascii_resource_, &uc16_resource_); - morphs_++; - } - i::OS::Sleep(1); - } - morph_success_ = true; - } +void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) { + if (regexp_interruption_data.loop_count != 2) return; + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::String> string = v8::Local<v8::String>::New( + CcTest::isolate(), regexp_interruption_data.string); + string->MakeExternal(regexp_interruption_data.string_resource); +} - void LongRunningRegExp() { - block_.Signal(); // Enable morphing thread on next preemption. - while (morphs_during_regexp_ < kRequiredModifications && - morphs_ < kMaxModifications) { - int morphs_before = morphs_; - { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - // Match 15-30 "a"'s against 14 and a "b". - const char* c_source = - "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/" - ".exec(input) === null"; - Local<String> source = String::New(c_source); - Local<Script> script = Script::Compile(source); - Local<Value> result = script->Run(); - CHECK(result->IsTrue()); - } - int morphs_after = morphs_; - morphs_during_regexp_ += morphs_after - morphs_before; - } - regexp_success_ = true; - } - i::uc16 two_byte_content_[15]; - i::Semaphore block_; - int morphs_; - int morphs_during_regexp_; - bool regexp_success_; - bool morph_success_; - i::Handle<i::String> input_; - AsciiVectorResource ascii_resource_; - UC16VectorResource uc16_resource_; -}; +// Test that RegExp execution can be interrupted. Specifically, we test +// * interrupting with GC +// * turn the subject string from one-byte internal to two-byte external string +// * force termination +TEST(RegExpInterruption) { + v8::HandleScope scope(CcTest::isolate()); + LocalContext env; + RegExpInterruptionThread timeout_thread(CcTest::isolate()); -// Test that a regular expression execution can be interrupted and -// the string changed without failing. -TEST(RegExpStringModification) { - v8::Locker lock(CcTest::default_isolate()); - v8::V8::Initialize(); - v8::HandleScope scope(CcTest::default_isolate()); - Local<Context> local_env; - { - LocalContext env; - local_env = env.local(); - } + v8::V8::AddGCPrologueCallback(RunBeforeGC); + static const char* ascii_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + i::uc16* uc16_content = AsciiToTwoByteString(ascii_content); + v8::Local<v8::String> string = v8_str(ascii_content); - // Local context should still be live. - CHECK(!local_env.IsEmpty()); - local_env->Enter(); + CcTest::global()->Set(v8_str("a"), string); + regexp_interruption_data.string.Reset(CcTest::isolate(), string); + regexp_interruption_data.string_resource = new UC16VectorResource( + i::Vector<const i::uc16>(uc16_content, i::StrLength(ascii_content))); - // Should complete without problems. - RegExpStringModificationTest().RunTest(); + v8::TryCatch try_catch; + timeout_thread.Start(); - local_env->Exit(); + CompileRun("/((a*)*)*b/.exec(a)"); + CHECK(try_catch.HasTerminated()); + + timeout_thread.Join(); + + delete regexp_interruption_data.string_resource; + regexp_interruption_data.string.Dispose(); } +#endif // V8_INTERPRETED_REGEXP + // Test that we cannot set a property on the global object if there // is a read-only property in the prototype chain. TEST(ReadOnlyPropertyInGlobalProto) { i::FLAG_es5_readonly = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); LocalContext context(0, templ); v8::Handle<v8::Object> global = context->Global(); @@ -14806,7 +14836,7 @@ TEST(ForceSet) { force_set_set_count = 0; pass_on_get = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); v8::Handle<v8::String> access_property = v8::String::New("a"); templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter); @@ -14848,7 +14878,7 @@ TEST(ForceSetWithInterceptor) { force_set_set_count = 0; pass_on_get = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter); LocalContext context(NULL, templ); @@ -14891,7 +14921,7 @@ TEST(ForceSetWithInterceptor) { THREADED_TEST(ForceDelete) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); LocalContext context(NULL, templ); v8::Handle<v8::Object> global = context->Global(); @@ -14926,7 +14956,7 @@ THREADED_TEST(ForceDeleteWithInterceptor) { force_delete_interceptor_count = 0; pass_on_delete = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); templ->SetNamedPropertyHandler(0, 0, 0, ForceDeleteDeleter); LocalContext context(NULL, templ); @@ -14979,14 +15009,14 @@ THREADED_TEST(ForceDeleteIC) { TEST(InlinedFunctionAcrossContexts) { i::FLAG_allow_natives_syntax = true; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer_scope(isolate); v8::Local<v8::Context> ctx1 = v8::Context::New(isolate); v8::Local<v8::Context> ctx2 = v8::Context::New(isolate); ctx1->Enter(); { - v8::HandleScope inner_scope(v8::Isolate::GetCurrent()); + v8::HandleScope inner_scope(CcTest::isolate()); CompileRun("var G = 42; function foo() { return G; }"); v8::Local<v8::Value> foo = ctx1->Global()->Get(v8_str("foo")); ctx2->Enter(); @@ -15027,16 +15057,15 @@ static v8::Local<Context> calling_context2; static void GetCallingContextCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); - CHECK(Context::GetCurrent() == calling_context0); CHECK(args.GetIsolate()->GetCurrentContext() == calling_context0); - CHECK(Context::GetCalling() == calling_context1); - CHECK(Context::GetEntered() == calling_context2); + CHECK(args.GetIsolate()->GetCallingContext() == calling_context1); + CHECK(args.GetIsolate()->GetEnteredContext() == calling_context2); args.GetReturnValue().Set(42); } THREADED_TEST(GetCurrentContextWhenNotInContext) { - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); CHECK(isolate != NULL); CHECK(isolate->context() == NULL); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); @@ -15048,7 +15077,7 @@ THREADED_TEST(GetCurrentContextWhenNotInContext) { THREADED_TEST(GetCallingContext) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Local<Context> calling_context0(Context::New(isolate)); @@ -15153,7 +15182,7 @@ static void CheckElementValue(i::Isolate* isolate, THREADED_TEST(PixelArray) { LocalContext context; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); v8::HandleScope scope(context->GetIsolate()); const int kElementCount = 260; @@ -15164,12 +15193,12 @@ THREADED_TEST(PixelArray) { v8::kExternalPixelArray, pixel_data)); // Force GC to trigger verification. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); for (int i = 0; i < kElementCount; i++) { pixels->set(i, i % 256); } // Force GC to trigger verification. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); for (int i = 0; i < kElementCount; i++) { CHECK_EQ(i % 256, pixels->get_scalar(i)); CHECK_EQ(i % 256, pixel_data[i]); @@ -15567,7 +15596,7 @@ static void NotHandledIndexedPropertySetter( THREADED_TEST(PixelArrayWithInterceptor) { LocalContext context; - i::Factory* factory = i::Isolate::Current()->factory(); + i::Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(context->GetIsolate()); const int kElementCount = 260; uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); @@ -15740,7 +15769,7 @@ static void ObjectWithExternalArrayTestHelper( "}" "sum;"); // Force GC to trigger verification. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(28, result->Int32Value()); // Make sure out-of-range loads do not throw. @@ -15933,7 +15962,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, int64_t low, int64_t high) { LocalContext context; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); v8::HandleScope scope(context->GetIsolate()); const int kElementCount = 40; @@ -15944,12 +15973,12 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, i::Handle<ExternalArrayClass>::cast( factory->NewExternalArray(kElementCount, array_type, array_data)); // Force GC to trigger verification. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); for (int i = 0; i < kElementCount; i++) { array->set(i, static_cast<ElementType>(i)); } // Force GC to trigger verification. - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); for (int i = 0; i < kElementCount; i++) { CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get_scalar(i))); @@ -16460,7 +16489,7 @@ void checkStackFrame(const char* expected_script_name, const char* expected_func_name, int expected_line_number, int expected_column, bool is_eval, bool is_constructor, v8::Handle<v8::StackFrame> frame) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::String::Utf8Value func_name(frame->GetFunctionName()); v8::String::Utf8Value script_name(frame->GetScriptName()); if (*script_name == NULL) { @@ -16532,7 +16561,7 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { // TODO(3074796): Reenable this as a THREADED_TEST once it passes. // THREADED_TEST(CaptureStackTrace) { TEST(CaptureStackTrace) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::String> origin = v8::String::New("capture-stack-trace-test"); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("AnalyzeStackInNativeCode"), @@ -16781,7 +16810,7 @@ void AnalyzeStackOfEvalWithSourceURL( TEST(SourceURLInStackTrace) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("AnalyzeStackOfEvalWithSourceURL"), v8::FunctionTemplate::New(AnalyzeStackOfEvalWithSourceURL)); @@ -16823,7 +16852,7 @@ void AnalyzeScriptIdInStack( TEST(ScriptIdInStackTrace) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("AnalyzeScriptIdInStack"), v8::FunctionTemplate::New(AnalyzeScriptIdInStack)); @@ -16861,7 +16890,7 @@ void AnalyzeStackOfInlineScriptWithSourceURL( TEST(InlineScriptWithSourceURLInStackTrace) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("AnalyzeStackOfInlineScriptWithSourceURL"), v8::FunctionTemplate::New( @@ -16906,7 +16935,7 @@ void AnalyzeStackOfDynamicScriptWithSourceURL( TEST(DynamicWithSourceURLInStackTrace) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("AnalyzeStackOfDynamicScriptWithSourceURL"), v8::FunctionTemplate::New( @@ -16935,8 +16964,8 @@ TEST(DynamicWithSourceURLInStackTrace) { static void CreateGarbageInOldSpace() { - i::Factory* factory = i::Isolate::Current()->factory(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + i::Factory* factory = CcTest::i_isolate()->factory(); + v8::HandleScope scope(CcTest::isolate()); i::AlwaysAllocateScope always_allocate; for (int i = 0; i < 1000; i++) { factory->NewFixedArray(1000, i::TENURED); @@ -16949,15 +16978,15 @@ TEST(IdleNotification) { const intptr_t MB = 1024 * 1024; LocalContext env; v8::HandleScope scope(env->GetIsolate()); - intptr_t initial_size = HEAP->SizeOfObjects(); + intptr_t initial_size = CcTest::heap()->SizeOfObjects(); CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); + intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects(); CHECK_GT(size_with_garbage, initial_size + MB); bool finished = false; for (int i = 0; i < 200 && !finished; i++) { finished = v8::V8::IdleNotification(); } - intptr_t final_size = HEAP->SizeOfObjects(); + intptr_t final_size = CcTest::heap()->SizeOfObjects(); CHECK(finished); CHECK_LT(final_size, initial_size + 1); } @@ -16969,15 +16998,15 @@ TEST(IdleNotificationWithSmallHint) { const int IdlePauseInMs = 900; LocalContext env; v8::HandleScope scope(env->GetIsolate()); - intptr_t initial_size = HEAP->SizeOfObjects(); + intptr_t initial_size = CcTest::heap()->SizeOfObjects(); CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); + intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects(); CHECK_GT(size_with_garbage, initial_size + MB); bool finished = false; for (int i = 0; i < 200 && !finished; i++) { finished = v8::V8::IdleNotification(IdlePauseInMs); } - intptr_t final_size = HEAP->SizeOfObjects(); + intptr_t final_size = CcTest::heap()->SizeOfObjects(); CHECK(finished); CHECK_LT(final_size, initial_size + 1); } @@ -16989,15 +17018,15 @@ TEST(IdleNotificationWithLargeHint) { const int IdlePauseInMs = 900; LocalContext env; v8::HandleScope scope(env->GetIsolate()); - intptr_t initial_size = HEAP->SizeOfObjects(); + intptr_t initial_size = CcTest::heap()->SizeOfObjects(); CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); + intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects(); CHECK_GT(size_with_garbage, initial_size + MB); bool finished = false; for (int i = 0; i < 200 && !finished; i++) { finished = v8::V8::IdleNotification(IdlePauseInMs); } - intptr_t final_size = HEAP->SizeOfObjects(); + intptr_t final_size = CcTest::heap()->SizeOfObjects(); CHECK(finished); CHECK_LT(final_size, initial_size + 1); } @@ -17010,7 +17039,7 @@ TEST(Regress2107) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(env->GetIsolate()); - intptr_t initial_size = HEAP->SizeOfObjects(); + intptr_t initial_size = CcTest::heap()->SizeOfObjects(); // Send idle notification to start a round of incremental GCs. v8::V8::IdleNotification(kShortIdlePauseInMs); // Emulate 7 page reloads. @@ -17027,13 +17056,13 @@ TEST(Regress2107) { } // Create garbage and check that idle notification still collects it. CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); + intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects(); CHECK_GT(size_with_garbage, initial_size + MB); bool finished = false; for (int i = 0; i < 200 && !finished; i++) { finished = v8::V8::IdleNotification(kShortIdlePauseInMs); } - intptr_t final_size = HEAP->SizeOfObjects(); + intptr_t final_size = CcTest::heap()->SizeOfObjects(); CHECK_LT(final_size, initial_size + 1); } @@ -17042,7 +17071,7 @@ static uint32_t* stack_limit; static void GetStackLimitCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { stack_limit = reinterpret_cast<uint32_t*>( - i::Isolate::Current()->stack_guard()->real_climit()); + CcTest::i_isolate()->stack_guard()->real_climit()); } @@ -17088,7 +17117,7 @@ TEST(SetResourceConstraints) { TEST(SetResourceConstraintsInThread) { uint32_t* set_limit; { - v8::Locker locker(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); set_limit = ComputeStackLimit(stack_breathing_room); // Set stack limit. @@ -17097,7 +17126,7 @@ TEST(SetResourceConstraintsInThread) { CHECK(v8::SetResourceConstraints(&constraints)); // Execute a script. - v8::HandleScope scope(CcTest::default_isolate()); + v8::HandleScope scope(CcTest::isolate()); LocalContext env; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(GetStackLimitCallback); @@ -17108,7 +17137,7 @@ TEST(SetResourceConstraintsInThread) { CHECK(stack_limit == set_limit); } { - v8::Locker locker(CcTest::default_isolate()); + v8::Locker locker(CcTest::isolate()); CHECK(stack_limit == set_limit); } } @@ -17181,10 +17210,10 @@ TEST(VisitExternalStrings) { // Symbolized External. resource[3] = new TestResource(AsciiToTwoByteString("Some other string")); v8::Local<v8::String> string3 = v8::String::NewExternal(resource[3]); - HEAP->CollectAllAvailableGarbage(); // Tenure string. + CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string. // Turn into a symbol. i::Handle<i::String> string3_i = v8::Utils::OpenHandle(*string3); - CHECK(!HEAP->InternalizeString(*string3_i)->IsFailure()); + CHECK(!CcTest::heap()->InternalizeString(*string3_i)->IsFailure()); CHECK(string3_i->IsInternalizedString()); // We need to add usages for string* to avoid warnings in GCC 4.7 @@ -17327,7 +17356,7 @@ static void SpaghettiIncident( // Test that an exception can be propagated down through a spaghetti // stack using ReThrow. THREADED_TEST(SpaghettiStackReThrow) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); LocalContext context; context->Global()->Set( v8::String::New("s"), @@ -17354,7 +17383,7 @@ THREADED_TEST(SpaghettiStackReThrow) { TEST(Regress528) { v8::V8::Initialize(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> other_context; int gc_count; @@ -17381,7 +17410,7 @@ TEST(Regress528) { other_context->Enter(); CompileRun(source_simple); other_context->Exit(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); if (GetGlobalObjectsCount() == 1) break; } CHECK_GE(2, gc_count); @@ -17403,7 +17432,7 @@ TEST(Regress528) { other_context->Enter(); CompileRun(source_eval); other_context->Exit(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); if (GetGlobalObjectsCount() == 1) break; } CHECK_GE(2, gc_count); @@ -17430,7 +17459,7 @@ TEST(Regress528) { other_context->Enter(); CompileRun(source_exception); other_context->Exit(); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); if (GetGlobalObjectsCount() == 1) break; } CHECK_GE(2, gc_count); @@ -17475,6 +17504,70 @@ THREADED_TEST(FunctionGetInferredName) { } +THREADED_TEST(FunctionGetDisplayName) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + const char* code = "var error = false;" + "function a() { this.x = 1; };" + "a.displayName = 'display_a';" + "var b = (function() {" + " var f = function() { this.x = 2; };" + " f.displayName = 'display_b';" + " return f;" + "})();" + "var c = function() {};" + "c.__defineGetter__('displayName', function() {" + " error = true;" + " throw new Error();" + "});" + "function d() {};" + "d.__defineGetter__('displayName', function() {" + " error = true;" + " return 'wrong_display_name';" + "});" + "function e() {};" + "e.displayName = 'wrong_display_name';" + "e.__defineSetter__('displayName', function() {" + " error = true;" + " throw new Error();" + "});" + "function f() {};" + "f.displayName = { 'foo': 6, toString: function() {" + " error = true;" + " return 'wrong_display_name';" + "}};" + "var g = function() {" + " arguments.callee.displayName = 'set_in_runtime';" + "}; g();" + ; + v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); + v8::Script::Compile(v8::String::New(code), &origin)->Run(); + v8::Local<v8::Value> error = env->Global()->Get(v8::String::New("error")); + v8::Local<v8::Function> a = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("a"))); + v8::Local<v8::Function> b = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("b"))); + v8::Local<v8::Function> c = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("c"))); + v8::Local<v8::Function> d = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("d"))); + v8::Local<v8::Function> e = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("e"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::New("g"))); + CHECK_EQ(false, error->BooleanValue()); + CHECK_EQ("display_a", *v8::String::Utf8Value(a->GetDisplayName())); + CHECK_EQ("display_b", *v8::String::Utf8Value(b->GetDisplayName())); + CHECK(c->GetDisplayName()->IsUndefined()); + CHECK(d->GetDisplayName()->IsUndefined()); + CHECK(e->GetDisplayName()->IsUndefined()); + CHECK(f->GetDisplayName()->IsUndefined()); + CHECK_EQ("set_in_runtime", *v8::String::Utf8Value(g->GetDisplayName())); +} + + THREADED_TEST(ScriptLineNumber) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -17508,6 +17601,23 @@ THREADED_TEST(ScriptColumnNumber) { } +THREADED_TEST(FunctionIsBuiltin) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Function> f; + f = v8::Local<v8::Function>::Cast(CompileRun("Math.floor")); + CHECK(f->IsBuiltin()); + f = v8::Local<v8::Function>::Cast(CompileRun("Object")); + CHECK(f->IsBuiltin()); + f = v8::Local<v8::Function>::Cast(CompileRun("Object.__defineSetter__")); + CHECK(f->IsBuiltin()); + f = v8::Local<v8::Function>::Cast(CompileRun("Array.prototype.toString")); + CHECK(f->IsBuiltin()); + f = v8::Local<v8::Function>::Cast(CompileRun("function a() {}; a;")); + CHECK(!f->IsBuiltin()); +} + + THREADED_TEST(FunctionGetScriptId) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -17566,7 +17676,7 @@ void FooSetInterceptor(Local<String> name, TEST(SetterOnConstructorPrototype) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), GetterWhichReturns42, @@ -17618,7 +17728,7 @@ static void NamedPropertySetterWhichSetsYOnThisTo23( THREADED_TEST(InterceptorOnConstructorPrototype) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42, NamedPropertySetterWhichSetsYOnThisTo23); @@ -17696,58 +17806,134 @@ TEST(Regress618) { } } +v8::Isolate* gc_callbacks_isolate = NULL; int prologue_call_count = 0; int epilogue_call_count = 0; int prologue_call_count_second = 0; int epilogue_call_count_second = 0; -void PrologueCallback(v8::GCType, v8::GCCallbackFlags) { +void PrologueCallback(v8::GCType, v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); ++prologue_call_count; } -void EpilogueCallback(v8::GCType, v8::GCCallbackFlags) { +void PrologueCallback(v8::Isolate* isolate, + v8::GCType, + v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); + CHECK_EQ(gc_callbacks_isolate, isolate); + ++prologue_call_count; +} + + +void EpilogueCallback(v8::GCType, v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); ++epilogue_call_count; } -void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags) { +void EpilogueCallback(v8::Isolate* isolate, + v8::GCType, + v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); + CHECK_EQ(gc_callbacks_isolate, isolate); + ++epilogue_call_count; +} + + +void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); + ++prologue_call_count_second; +} + + +void PrologueCallbackSecond(v8::Isolate* isolate, + v8::GCType, + v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); + CHECK_EQ(gc_callbacks_isolate, isolate); ++prologue_call_count_second; } -void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags) { +void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); ++epilogue_call_count_second; } -TEST(GCCallbacks) { +void EpilogueCallbackSecond(v8::Isolate* isolate, + v8::GCType, + v8::GCCallbackFlags flags) { + CHECK_EQ(flags, v8::kNoGCCallbackFlags); + CHECK_EQ(gc_callbacks_isolate, isolate); + ++epilogue_call_count_second; +} + + +TEST(GCCallbacksOld) { LocalContext context; v8::V8::AddGCPrologueCallback(PrologueCallback); v8::V8::AddGCEpilogueCallback(EpilogueCallback); CHECK_EQ(0, prologue_call_count); CHECK_EQ(0, epilogue_call_count); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(1, prologue_call_count); CHECK_EQ(1, epilogue_call_count); v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(2, prologue_call_count); CHECK_EQ(2, epilogue_call_count); CHECK_EQ(1, prologue_call_count_second); CHECK_EQ(1, epilogue_call_count_second); v8::V8::RemoveGCPrologueCallback(PrologueCallback); v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(2, prologue_call_count); CHECK_EQ(2, epilogue_call_count); CHECK_EQ(2, prologue_call_count_second); CHECK_EQ(2, epilogue_call_count_second); v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CHECK_EQ(2, prologue_call_count); + CHECK_EQ(2, epilogue_call_count); + CHECK_EQ(2, prologue_call_count_second); + CHECK_EQ(2, epilogue_call_count_second); +} + + +TEST(GCCallbacks) { + LocalContext context; + v8::Isolate* isolate = context->GetIsolate(); + gc_callbacks_isolate = isolate; + isolate->AddGCPrologueCallback(PrologueCallback); + isolate->AddGCEpilogueCallback(EpilogueCallback); + CHECK_EQ(0, prologue_call_count); + CHECK_EQ(0, epilogue_call_count); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CHECK_EQ(1, prologue_call_count); + CHECK_EQ(1, epilogue_call_count); + isolate->AddGCPrologueCallback(PrologueCallbackSecond); + isolate->AddGCEpilogueCallback(EpilogueCallbackSecond); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CHECK_EQ(2, prologue_call_count); + CHECK_EQ(2, epilogue_call_count); + CHECK_EQ(1, prologue_call_count_second); + CHECK_EQ(1, epilogue_call_count_second); + isolate->RemoveGCPrologueCallback(PrologueCallback); + isolate->RemoveGCEpilogueCallback(EpilogueCallback); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CHECK_EQ(2, prologue_call_count); + CHECK_EQ(2, epilogue_call_count); + CHECK_EQ(2, prologue_call_count_second); + CHECK_EQ(2, epilogue_call_count_second); + isolate->RemoveGCPrologueCallback(PrologueCallbackSecond); + isolate->RemoveGCEpilogueCallback(EpilogueCallbackSecond); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK_EQ(2, prologue_call_count); CHECK_EQ(2, epilogue_call_count); CHECK_EQ(2, prologue_call_count_second); @@ -17758,7 +17944,7 @@ TEST(GCCallbacks) { THREADED_TEST(AddToJSFunctionResultCache) { i::FLAG_stress_compaction = false; i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); LocalContext context; @@ -17776,7 +17962,7 @@ THREADED_TEST(AddToJSFunctionResultCache) { " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" " return 'PASSED';" "})()"; - HEAP->ClearJSFunctionResultCaches(); + CcTest::heap()->ClearJSFunctionResultCaches(); ExpectString(code, "PASSED"); } @@ -17799,7 +17985,7 @@ THREADED_TEST(FillJSFunctionResultCache) { " return 'FAILED: k0CacheSize is too small';" " return 'PASSED';" "})()"; - HEAP->ClearJSFunctionResultCaches(); + CcTest::heap()->ClearJSFunctionResultCaches(); ExpectString(code, "PASSED"); } @@ -17823,7 +18009,7 @@ THREADED_TEST(RoundRobinGetFromCache) { " };" " return 'PASSED';" "})()"; - HEAP->ClearJSFunctionResultCaches(); + CcTest::heap()->ClearJSFunctionResultCaches(); ExpectString(code, "PASSED"); } @@ -17847,7 +18033,7 @@ THREADED_TEST(ReverseGetFromCache) { " };" " return 'PASSED';" "})()"; - HEAP->ClearJSFunctionResultCaches(); + CcTest::heap()->ClearJSFunctionResultCaches(); ExpectString(code, "PASSED"); } @@ -17864,7 +18050,7 @@ THREADED_TEST(TestEviction) { " };" " return 'PASSED';" "})()"; - HEAP->ClearJSFunctionResultCaches(); + CcTest::heap()->ClearJSFunctionResultCaches(); ExpectString(code, "PASSED"); } @@ -17961,7 +18147,7 @@ THREADED_TEST(TwoByteStringInAsciiCons) { TEST(ContainsOnlyOneByte) { v8::V8::Initialize(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); // Make a buffer long enough that it won't automatically be converted. const int length = 512; @@ -18030,7 +18216,7 @@ TEST(ContainsOnlyOneByte) { void FailedAccessCheckCallbackGC(Local<v8::Object> target, v8::AccessType type, Local<v8::Value> data) { - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } @@ -18041,7 +18227,7 @@ TEST(GCInFailedAccessCheckCallback) { v8::V8::Initialize(); v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. @@ -18112,116 +18298,28 @@ TEST(GCInFailedAccessCheckCallback) { } -TEST(DefaultIsolateGetCurrent) { - CHECK(v8::Isolate::GetCurrent() != NULL); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); - printf("*** %s\n", "DefaultIsolateGetCurrent success"); -} - - TEST(IsolateNewDispose) { - v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); + v8::Isolate* current_isolate = CcTest::isolate(); v8::Isolate* isolate = v8::Isolate::New(); CHECK(isolate != NULL); CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); CHECK(current_isolate != isolate); - CHECK(current_isolate == v8::Isolate::GetCurrent()); - - v8::V8::SetFatalErrorHandler(StoringErrorCallback); - last_location = last_message = NULL; - isolate->Dispose(); - CHECK_EQ(last_location, NULL); - CHECK_EQ(last_message, NULL); -} - - -TEST(IsolateEnterExitDefault) { - v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); - CHECK(current_isolate != NULL); // Default isolate. - v8::HandleScope scope(current_isolate); - LocalContext context; - ExpectString("'hello'", "hello"); - current_isolate->Enter(); - ExpectString("'still working'", "still working"); - current_isolate->Exit(); - ExpectString("'still working 2'", "still working 2"); - current_isolate->Exit(); - // Default isolate is always, well, 'default current'. - CHECK_EQ(v8::Isolate::GetCurrent(), current_isolate); - // Still working since default isolate is auto-entering any thread - // that has no isolate and attempts to execute V8 APIs. - ExpectString("'still working 3'", "still working 3"); -} - - -TEST(DisposeDefaultIsolate) { - v8::V8::SetFatalErrorHandler(StoringErrorCallback); - - // Run some V8 code to trigger default isolate to become 'current'. - v8::HandleScope scope(v8::Isolate::GetCurrent()); - LocalContext context; - ExpectString("'run some V8'", "run some V8"); - - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); - last_location = last_message = NULL; - isolate->Dispose(); - // It is not possible to dispose default isolate via Isolate API. - CHECK_NE(last_location, NULL); - CHECK_NE(last_message, NULL); -} - - -TEST(RunDefaultAndAnotherIsolate) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - LocalContext context; - - // Enter new isolate. - v8::Isolate* isolate = v8::Isolate::New(); - CHECK(isolate); - isolate->Enter(); - { // Need this block because subsequent Exit() will deallocate Heap, - // so we need all scope objects to be deconstructed when it happens. - v8::HandleScope scope_new(isolate); - LocalContext context_new; - - // Run something in new isolate. - CompileRun("var foo = 153;"); - ExpectTrue("function f() { return foo == 153; }; f()"); - } - isolate->Exit(); - - // This runs automatically in default isolate. - // Variables in another isolate should be not available. - ExpectTrue("function f() {" - " try {" - " foo;" - " return false;" - " } catch(e) {" - " return true;" - " }" - "};" - "var bar = 371;" - "f()"); + CHECK(current_isolate == CcTest::isolate()); v8::V8::SetFatalErrorHandler(StoringErrorCallback); last_location = last_message = NULL; isolate->Dispose(); CHECK_EQ(last_location, NULL); CHECK_EQ(last_message, NULL); - - // Check that default isolate still runs. - ExpectTrue("function f() { return bar == 371; }; f()"); } -TEST(DisposeIsolateWhenInUse) { +UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { v8::Isolate* isolate = v8::Isolate::New(); CHECK(isolate); isolate->Enter(); v8::HandleScope scope(isolate); - LocalContext context; + LocalContext context(isolate); // Run something in this isolate. ExpectTrue("true"); v8::V8::SetFatalErrorHandler(StoringErrorCallback); @@ -18284,16 +18382,16 @@ TEST(RunTwoIsolatesOnSingleThread) { // Run some stuff in default isolate. v8::Persistent<v8::Context> context_default; { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::Isolate::Scope iscope(isolate); v8::HandleScope scope(isolate); context_default.Reset(isolate, Context::New(isolate)); } { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = - v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context_default); + v8::Local<v8::Context>::New(CcTest::isolate(), context_default); v8::Context::Scope context_scope(context); // Variables in other isolates should be not available, verify there // is an exception. @@ -18313,7 +18411,7 @@ TEST(RunTwoIsolatesOnSingleThread) { { v8::Isolate::Scope iscope(isolate2); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(isolate2); v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate2, context2); v8::Context::Scope context_scope(context); @@ -18349,9 +18447,9 @@ TEST(RunTwoIsolatesOnSingleThread) { // Check that default isolate still runs. { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = - v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context_default); + v8::Local<v8::Context>::New(CcTest::isolate(), context_default); v8::Context::Scope context_scope(context); ExpectTrue("function f() { return isDefaultIsolate; }; f()"); } @@ -18361,7 +18459,7 @@ TEST(RunTwoIsolatesOnSingleThread) { static int CalcFibonacci(v8::Isolate* isolate, int limit) { v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope scope(isolate); - LocalContext context; + LocalContext context(isolate); i::ScopedVector<char> code(1024); i::OS::SNPrintF(code, "function fib(n) {" " if (n <= 2) return 1;" @@ -18405,8 +18503,8 @@ TEST(MultipleIsolatesOnIndividualThreads) { thread1.Start(); thread2.Start(); - int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21); - int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12); + int result1 = CalcFibonacci(CcTest::isolate(), 21); + int result2 = CalcFibonacci(CcTest::isolate(), 12); thread1.Join(); thread2.Join(); @@ -18463,6 +18561,8 @@ class InitDefaultIsolateThread : public v8::internal::Thread { result_(false) { } void Run() { + v8::Isolate* isolate = v8::Isolate::New(); + isolate->Enter(); switch (testCase_) { case IgnoreOOM: v8::V8::IgnoreOutOfMemoryException(); @@ -18493,6 +18593,8 @@ class InitDefaultIsolateThread : public v8::internal::Thread { v8::V8::SetAddHistogramSampleFunction(NULL); break; } + isolate->Exit(); + isolate->Dispose(); result_ = true; } @@ -18644,7 +18746,7 @@ TEST(DontDeleteCellLoadIC) { "})()", "ReferenceError: cell is not defined"); CompileRun("cell = \"new_second\";"); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); ExpectString("readCell()", "new_second"); ExpectString("readCell()", "new_second"); } @@ -18716,7 +18818,7 @@ class Visitor42 : public v8::PersistentHandleVisitor { uint16_t class_id) { if (class_id != 42) return; CHECK_EQ(42, value->WrapperClassId()); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::Value> handle = v8::Local<v8::Value>::New(isolate, *value); v8::Handle<v8::Value> object = @@ -18769,7 +18871,7 @@ TEST(PersistentHandleInNewSpaceVisitor) { object1.SetWrapperClassId(42); CHECK_EQ(42, object1.WrapperClassId()); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); v8::Persistent<v8::Object> object2(isolate, v8::Object::New()); CHECK_EQ(0, object2.WrapperClassId()); @@ -18931,12 +19033,12 @@ static void CheckContextId(v8::Handle<Object> object, int expected) { THREADED_TEST(CreationContext) { - HandleScope handle_scope(v8::Isolate::GetCurrent()); - Handle<Context> context1 = Context::New(v8::Isolate::GetCurrent()); + HandleScope handle_scope(CcTest::isolate()); + Handle<Context> context1 = Context::New(CcTest::isolate()); InstallContextId(context1, 1); - Handle<Context> context2 = Context::New(v8::Isolate::GetCurrent()); + Handle<Context> context2 = Context::New(CcTest::isolate()); InstallContextId(context2, 2); - Handle<Context> context3 = Context::New(v8::Isolate::GetCurrent()); + Handle<Context> context3 = Context::New(CcTest::isolate()); InstallContextId(context3, 3); Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New(); @@ -19014,8 +19116,8 @@ THREADED_TEST(CreationContext) { THREADED_TEST(CreationContextOfJsFunction) { - HandleScope handle_scope(v8::Isolate::GetCurrent()); - Handle<Context> context = Context::New(v8::Isolate::GetCurrent()); + HandleScope handle_scope(CcTest::isolate()); + Handle<Context> context = Context::New(CcTest::isolate()); InstallContextId(context, 1); Local<Object> function; @@ -19144,7 +19246,7 @@ TEST(HasOwnProperty) { TEST(IndexedInterceptorWithStringProto) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetIndexedPropertyHandler(NULL, NULL, @@ -19270,7 +19372,7 @@ THREADED_TEST(CallAPIFunctionOnNonObject) { // Regression test for issue 1470. THREADED_TEST(ReadOnlyIndexedProperties) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Local<ObjectTemplate> templ = ObjectTemplate::New(); LocalContext context; @@ -19300,15 +19402,15 @@ THREADED_TEST(Regress1516) { int elements; { i::MapCache* map_cache = - i::MapCache::cast(i::Isolate::Current()->context()->map_cache()); + i::MapCache::cast(CcTest::i_isolate()->context()->map_cache()); elements = map_cache->NumberOfElements(); CHECK_LE(1, elements); } - i::Isolate::Current()->heap()->CollectAllGarbage( + CcTest::heap()->CollectAllGarbage( i::Heap::kAbortIncrementalMarkingMask); - { i::Object* raw_map_cache = i::Isolate::Current()->context()->map_cache(); - if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value()) { + { i::Object* raw_map_cache = CcTest::i_isolate()->context()->map_cache(); + if (raw_map_cache != CcTest::heap()->undefined_value()) { i::MapCache* map_cache = i::MapCache::cast(raw_map_cache); CHECK_GT(elements, map_cache->NumberOfElements()); } @@ -19335,7 +19437,7 @@ static bool BlockProtoNamedSecurityTestCallback(Local<v8::Object> global, THREADED_TEST(Regress93759) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); // Template for object with security check. @@ -19407,25 +19509,25 @@ THREADED_TEST(Regress93759) { CHECK(result1->Equals(simple_object->GetPrototype())); Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)"); - CHECK(result2->Equals(Undefined())); + CHECK(result2->Equals(Undefined(isolate))); Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)"); CHECK(result3->Equals(global_object->GetPrototype())); Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)"); - CHECK(result4->Equals(Undefined())); + CHECK(result4->Equals(Undefined(isolate))); Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); CHECK(result5->Equals( object_with_hidden->GetPrototype()->ToObject()->GetPrototype())); Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); - CHECK(result6->Equals(Undefined())); + CHECK(result6->Equals(Undefined(isolate))); } THREADED_TEST(Regress125988) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> intercept = FunctionTemplate::New(); AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; @@ -19459,7 +19561,7 @@ static void TestReceiver(Local<Value> expected_result, THREADED_TEST(ForeignFunctionReceiver) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); // Create two contexts with different "id" properties ('i' and 'o'). @@ -19618,13 +19720,13 @@ TEST(CallCompletedCallback) { void CallCompletedCallbackNoException() { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CompileRun("1+1;"); } void CallCompletedCallbackException() { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CompileRun("throw 'second exception';"); } @@ -19715,26 +19817,24 @@ TEST(PrimaryStubCache) { TEST(StaticGetters) { LocalContext context; - i::Factory* factory = i::Isolate::Current()->factory(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + i::Factory* factory = CcTest::i_isolate()->factory(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); i::Handle<i::Object> undefined_value = factory->undefined_value(); - CHECK(*v8::Utils::OpenHandle(*v8::Undefined()) == *undefined_value); CHECK(*v8::Utils::OpenHandle(*v8::Undefined(isolate)) == *undefined_value); i::Handle<i::Object> null_value = factory->null_value(); - CHECK(*v8::Utils::OpenHandle(*v8::Null()) == *null_value); CHECK(*v8::Utils::OpenHandle(*v8::Null(isolate)) == *null_value); i::Handle<i::Object> true_value = factory->true_value(); - CHECK(*v8::Utils::OpenHandle(*v8::True()) == *true_value); CHECK(*v8::Utils::OpenHandle(*v8::True(isolate)) == *true_value); i::Handle<i::Object> false_value = factory->false_value(); - CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value); CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value); } -TEST(IsolateEmbedderData) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); +UNINITIALIZED_TEST(IsolateEmbedderData) { + CcTest::DisableAutomaticDispose(); + v8::Isolate* isolate = v8::Isolate::New(); + isolate->Enter(); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); CHECK_EQ(NULL, isolate->GetData()); CHECK_EQ(NULL, i_isolate->GetData()); @@ -19746,16 +19846,15 @@ TEST(IsolateEmbedderData) { i_isolate->SetData(data2); CHECK_EQ(data2, isolate->GetData()); CHECK_EQ(data2, i_isolate->GetData()); - i_isolate->TearDown(); - CHECK_EQ(data2, isolate->GetData()); - CHECK_EQ(data2, i_isolate->GetData()); + isolate->Exit(); + isolate->Dispose(); } TEST(StringEmpty) { LocalContext context; - i::Factory* factory = i::Isolate::Current()->factory(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + i::Factory* factory = CcTest::i_isolate()->factory(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); i::Handle<i::Object> empty_string = factory->empty_string(); CHECK(*v8::Utils::OpenHandle(*v8::String::Empty()) == *empty_string); @@ -20029,7 +20128,7 @@ static void Helper137002(bool do_store, THREADED_TEST(Regress137002a) { i::FLAG_allow_natives_syntax = true; i::FLAG_compilation_cache = false; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); for (int i = 0; i < 16; i++) { Helper137002(i & 8, i & 4, i & 2, i & 1); } @@ -20170,10 +20269,11 @@ THREADED_TEST(Regress2535) { THREADED_TEST(Regress2746) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); Local<Object> obj = Object::New(); Local<String> key = String::New("key"); - obj->SetHiddenValue(key, v8::Undefined()); + obj->SetHiddenValue(key, v8::Undefined(isolate)); Local<Value> value = obj->GetHiddenValue(key); CHECK(!value.IsEmpty()); CHECK(value->IsUndefined()); @@ -20297,7 +20397,7 @@ void UnreachableCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(JSONStringifyAccessCheck) { v8::V8::Initialize(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. @@ -20353,7 +20453,8 @@ void FailedAccessCheckThrows(Local<v8::Object> target, Local<v8::Value> data) { access_check_fail_thrown = true; i::PrintF("Access check failed. Error thrown.\n"); - v8::ThrowException(v8::Exception::Error(v8_str("cross context"))); + CcTest::isolate()->ThrowException( + v8::Exception::Error(v8_str("cross context"))); } @@ -20394,7 +20495,7 @@ TEST(AccessCheckThrows) { i::FLAG_allow_natives_syntax = true; v8::V8::Initialize(); v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. @@ -20470,7 +20571,7 @@ THREADED_TEST(Regress256330) { THREADED_TEST(CrankshaftInterceptorSetter) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -20496,7 +20597,7 @@ THREADED_TEST(CrankshaftInterceptorSetter) { THREADED_TEST(CrankshaftInterceptorGetter) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -20519,7 +20620,7 @@ THREADED_TEST(CrankshaftInterceptorGetter) { THREADED_TEST(CrankshaftInterceptorFieldRead) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -20539,7 +20640,7 @@ THREADED_TEST(CrankshaftInterceptorFieldRead) { THREADED_TEST(CrankshaftInterceptorFieldWrite) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); Handle<FunctionTemplate> templ = FunctionTemplate::New(); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -20584,6 +20685,36 @@ THREADED_TEST(FunctionNew) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Object* elm = i_isolate->native_context()->function_cache() ->GetElementNoExceptionThrown(i_isolate, serial_number); - CHECK(elm->IsNull()); + CHECK(elm->IsUndefined()); + // Verify that each Function::New creates a new function instance + Local<Object> data2 = v8::Object::New(); + function_new_expected_env = data2; + Local<Function> func2 = Function::New(isolate, FunctionNewCallback, data2); + CHECK(!func2->IsNull()); + CHECK_NE(func, func2); + env->Global()->Set(v8_str("func2"), func2); + Local<Value> result2 = CompileRun("func2();"); + CHECK_EQ(v8::Integer::New(17, isolate), result2); } + +TEST(EscapeableHandleScope) { + HandleScope outer_scope(CcTest::isolate()); + LocalContext context; + const int runs = 10; + Local<String> values[runs]; + for (int i = 0; i < runs; i++) { + v8::EscapableHandleScope inner_scope(CcTest::isolate()); + Local<String> value; + if (i != 0) value = v8_str("escape value"); + values[i] = inner_scope.Escape(value); + } + for (int i = 0; i < runs; i++) { + Local<String> expected; + if (i != 0) { + CHECK_EQ(v8_str("escape value"), values[i]); + } else { + CHECK(values[i].IsEmpty()); + } + } +} diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc index 1a4c1ae369..69ea6f4742 100644 --- a/deps/v8/test/cctest/test-assembler-arm.cc +++ b/deps/v8/test/cctest/test-assembler-arm.cc @@ -47,7 +47,7 @@ typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4); TEST(0) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -74,7 +74,7 @@ TEST(0) { TEST(1) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -112,7 +112,7 @@ TEST(1) { TEST(2) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -159,7 +159,7 @@ TEST(2) { TEST(3) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -215,7 +215,7 @@ TEST(3) { TEST(4) { // Test the VFP floating point instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -363,7 +363,7 @@ TEST(4) { TEST(5) { // Test the ARMv7 bitfield instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -400,7 +400,7 @@ TEST(5) { TEST(6) { // Test saturating instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -443,8 +443,7 @@ static void TestRoundingMode(VCVTTypes types, double value, int expected, bool expected_exception = false) { - CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -511,6 +510,7 @@ static void TestRoundingMode(VCVTTypes types, TEST(7) { + CcTest::InitializeVM(); // Test vfp rounding modes. // s32_f64 (double to integer). @@ -623,7 +623,7 @@ TEST(7) { TEST(8) { // Test VFP multi load/store with ia_w. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -731,7 +731,7 @@ TEST(8) { TEST(9) { // Test VFP multi load/store with ia. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -843,7 +843,7 @@ TEST(9) { TEST(10) { // Test VFP multi load/store with db_w. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -951,7 +951,7 @@ TEST(10) { TEST(11) { // Test instructions using the carry flag. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1017,7 +1017,7 @@ TEST(11) { TEST(12) { // Test chaining of label usages within instructions (issue 1644). CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -1032,7 +1032,7 @@ TEST(12) { TEST(13) { // Test VFP instructions using registers d16-d31. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); if (!CpuFeatures::IsSupported(VFP32DREGS)) { @@ -1160,7 +1160,7 @@ TEST(13) { TEST(14) { // Test the VFP Canonicalized Nan mode. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1240,7 +1240,7 @@ TEST(14) { TEST(15) { // Test the Neon instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1347,7 +1347,7 @@ TEST(15) { TEST(16) { // Test the pkh, uxtb, uxtab and uxtb16 instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1423,7 +1423,7 @@ TEST(17) { // Test generating labels at high addresses. // Should not assert. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); // Generate a code segment that will be longer than 2^24 bytes. @@ -1443,7 +1443,7 @@ TEST(code_relative_offset) { // Test extracting the offset of a label from the beginning of the code // in a register. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); // Initialize a code object that will contain the code. Handle<Object> code_object(isolate->heap()->undefined_value(), isolate); diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc index 76eecc02e7..d40156841e 100644 --- a/deps/v8/test/cctest/test-assembler-ia32.cc +++ b/deps/v8/test/cctest/test-assembler-ia32.cc @@ -264,15 +264,15 @@ TEST(AssemblerIa326) { Assembler assm(isolate, buffer, sizeof buffer); CpuFeatureScope fscope(&assm, SSE2); - __ movdbl(xmm0, Operand(esp, 1 * kPointerSize)); - __ movdbl(xmm1, Operand(esp, 3 * kPointerSize)); + __ movsd(xmm0, Operand(esp, 1 * kPointerSize)); + __ movsd(xmm1, Operand(esp, 3 * kPointerSize)); __ addsd(xmm0, xmm1); __ mulsd(xmm0, xmm1); __ subsd(xmm0, xmm1); __ divsd(xmm0, xmm1); // Copy xmm0 to st(0) using eight bytes of stack. __ sub(esp, Immediate(8)); - __ movdbl(Operand(esp, 0), xmm0); + __ movsd(Operand(esp, 0), xmm0); __ fld_d(Operand(esp, 0)); __ add(esp, Immediate(8)); __ ret(0); @@ -313,7 +313,7 @@ TEST(AssemblerIa328) { __ cvtsi2sd(xmm0, eax); // Copy xmm0 to st(0) using eight bytes of stack. __ sub(esp, Immediate(8)); - __ movdbl(Operand(esp, 0), xmm0); + __ movsd(Operand(esp, 0), xmm0); __ fld_d(Operand(esp, 0)); __ add(esp, Immediate(8)); __ ret(0); @@ -532,7 +532,7 @@ TEST(StackAlignmentForSSE2) { CHECK_EQ(0, OS::ActivationFrameAlignment() % 16); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2)); @@ -564,4 +564,39 @@ TEST(StackAlignmentForSSE2) { #endif // __GNUC__ +TEST(AssemblerIa32Extractps) { + CcTest::InitializeVM(); + if (!CpuFeatures::IsSupported(SSE2) || + !CpuFeatures::IsSupported(SSE4_1)) return; + + Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); + HandleScope scope(isolate); + v8::internal::byte buffer[256]; + MacroAssembler assm(isolate, buffer, sizeof buffer); + { CpuFeatureScope fscope2(&assm, SSE2); + CpuFeatureScope fscope41(&assm, SSE4_1); + __ movsd(xmm1, Operand(esp, 4)); + __ extractps(eax, xmm1, 0x1); + __ ret(0); + } + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = Code::cast(isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked()); + CHECK(code->IsCode()); +#ifdef OBJECT_PRINT + Code::cast(code)->Print(); +#endif + + F4 f = FUNCTION_CAST<F4>(Code::cast(code)->entry()); + uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321); + CHECK_EQ(0x12345678, f(uint64_to_double(value1))); + uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678); + CHECK_EQ(0x87654321, f(uint64_to_double(value2))); +} + + #undef __ diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc index 54ec43f18b..e8e724c052 100644 --- a/deps/v8/test/cctest/test-assembler-mips.cc +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -49,7 +49,7 @@ typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); TEST(MIPS0) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); MacroAssembler assm(isolate, NULL, 0); @@ -61,7 +61,7 @@ TEST(MIPS0) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -75,7 +75,7 @@ TEST(MIPS0) { TEST(MIPS1) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); MacroAssembler assm(isolate, NULL, 0); @@ -100,7 +100,7 @@ TEST(MIPS1) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -114,7 +114,7 @@ TEST(MIPS1) { TEST(MIPS2) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); MacroAssembler assm(isolate, NULL, 0); @@ -241,7 +241,7 @@ TEST(MIPS2) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -256,7 +256,7 @@ TEST(MIPS2) { TEST(MIPS3) { // Test floating point instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -314,7 +314,7 @@ TEST(MIPS3) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -346,7 +346,7 @@ TEST(MIPS3) { TEST(MIPS4) { // Test moves between floating point and integer registers. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -382,7 +382,7 @@ TEST(MIPS4) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -403,7 +403,7 @@ TEST(MIPS4) { TEST(MIPS5) { // Test conversions between doubles and integers. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -448,7 +448,7 @@ TEST(MIPS5) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -471,7 +471,7 @@ TEST(MIPS5) { TEST(MIPS6) { // Test simple memory loads and stores. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -521,7 +521,7 @@ TEST(MIPS6) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -544,7 +544,7 @@ TEST(MIPS6) { TEST(MIPS7) { // Test floating point compare and branch instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -598,7 +598,7 @@ TEST(MIPS7) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -622,7 +622,7 @@ TEST(MIPS7) { TEST(MIPS8) { // Test ROTR and ROTRV instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -697,7 +697,7 @@ TEST(MIPS8) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -727,7 +727,7 @@ TEST(MIPS8) { TEST(MIPS9) { // Test BRANCH improvements. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); MacroAssembler assm(isolate, NULL, 0); @@ -745,7 +745,7 @@ TEST(MIPS9) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -757,7 +757,7 @@ TEST(MIPS10) { // Test conversions between doubles and long integers. // Test hos the long ints map to FP regs pairs. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -805,7 +805,7 @@ TEST(MIPS10) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -830,7 +830,7 @@ TEST(MIPS10) { TEST(MIPS11) { // Test LWL, LWR, SWL and SWR instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -938,7 +938,7 @@ TEST(MIPS11) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -974,7 +974,7 @@ TEST(MIPS11) { TEST(MIPS12) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1043,7 +1043,7 @@ TEST(MIPS12) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -1066,7 +1066,7 @@ TEST(MIPS12) { TEST(MIPS13) { // Test Cvt_d_uw and Trunc_uw_d macros. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1100,7 +1100,7 @@ TEST(MIPS13) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -1125,7 +1125,7 @@ TEST(MIPS13) { TEST(MIPS14) { // Test round, floor, ceil, trunc, cvt. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); #define ROUND_STRUCT_ELEMENT(x) \ @@ -1221,7 +1221,7 @@ TEST(MIPS14) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); @@ -1258,7 +1258,7 @@ TEST(MIPS14) { TEST(MIPS15) { // Test chaining of label usages within instructions (issue 1644). CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc index f7d2311192..cd1ed2823b 100644 --- a/deps/v8/test/cctest/test-assembler-x64.cc +++ b/deps/v8/test/cctest/test-assembler-x64.cc @@ -35,34 +35,7 @@ #include "serialize.h" #include "cctest.h" -using v8::internal::Assembler; -using v8::internal::Code; -using v8::internal::CodeDesc; -using v8::internal::FUNCTION_CAST; -using v8::internal::Immediate; -using v8::internal::Isolate; -using v8::internal::Label; -using v8::internal::OS; -using v8::internal::Operand; -using v8::internal::byte; -using v8::internal::greater; -using v8::internal::less_equal; -using v8::internal::equal; -using v8::internal::not_equal; -using v8::internal::r13; -using v8::internal::r15; -using v8::internal::r8; -using v8::internal::r9; -using v8::internal::rax; -using v8::internal::rbx; -using v8::internal::rbp; -using v8::internal::rcx; -using v8::internal::rdi; -using v8::internal::rdx; -using v8::internal::rsi; -using v8::internal::rsp; -using v8::internal::times_1; -using v8::internal::xmm0; +using namespace v8::internal; // Test the x64 assembler by compiling some simple functions into // a buffer and executing them. These tests do not initialize the @@ -77,13 +50,16 @@ using v8::internal::xmm0; typedef int (*F0)(); typedef int (*F1)(int64_t x); typedef int (*F2)(int64_t x, int64_t y); +typedef int (*F3)(double x); +typedef int64_t (*F4)(int64_t* x, int64_t* y); +typedef int64_t (*F5)(int64_t x); #ifdef _WIN64 -static const v8::internal::Register arg1 = rcx; -static const v8::internal::Register arg2 = rdx; +static const Register arg1 = rcx; +static const Register arg2 = rdx; #else -static const v8::internal::Register arg1 = rdi; -static const v8::internal::Register arg2 = rsi; +static const Register arg1 = rdi; +static const Register arg2 = rsi; #endif #define __ assm. @@ -96,7 +72,7 @@ TEST(AssemblerX64ReturnOperation) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 2 and returns it. __ movq(rax, arg2); @@ -118,7 +94,7 @@ TEST(AssemblerX64StackOperations) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 2 and returns it. // We compile without stack frame pointers, so the gdb debugger shows @@ -150,7 +126,7 @@ TEST(AssemblerX64ArithmeticOperations) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble a simple function that adds arguments returning the sum. __ movq(rax, arg2); @@ -172,7 +148,7 @@ TEST(AssemblerX64ImulOperation) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble a simple function that multiplies arguments returning the high // word. @@ -193,6 +169,157 @@ TEST(AssemblerX64ImulOperation) { } +TEST(AssemblerX64XchglOperations) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); + + __ movq(rax, Operand(arg1, 0)); + __ movq(rbx, Operand(arg2, 0)); + __ xchgl(rax, rbx); + __ movq(Operand(arg1, 0), rax); + __ movq(Operand(arg2, 0), rbx); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + // Call the function from C++. + int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); + int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); + int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); + CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left); + CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right); + USE(result); +} + + +TEST(AssemblerX64OrlOperations) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); + + __ movq(rax, Operand(arg2, 0)); + __ orl(Operand(arg1, 0), rax); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + // Call the function from C++. + int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); + int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); + int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); + CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left); + USE(result); +} + + +TEST(AssemblerX64RollOperations) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); + + __ movq(rax, arg1); + __ roll(rax, Immediate(1)); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + // Call the function from C++. + int64_t src = V8_2PART_UINT64_C(0x10000000, C0000000); + int64_t result = FUNCTION_CAST<F5>(buffer)(src); + CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result); +} + + +TEST(AssemblerX64SublOperations) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); + + __ movq(rax, Operand(arg2, 0)); + __ subl(Operand(arg1, 0), rax); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + // Call the function from C++. + int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); + int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); + int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); + CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left); + USE(result); +} + + +TEST(AssemblerX64TestlOperations) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); + + // Set rax with the ZF flag of the testl instruction. + Label done; + __ movq(rax, Immediate(1)); + __ movq(rbx, Operand(arg2, 0)); + __ testl(Operand(arg1, 0), rbx); + __ j(zero, &done, Label::kNear); + __ movq(rax, Immediate(0)); + __ bind(&done); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + // Call the function from C++. + int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); + int64_t right = V8_2PART_UINT64_C(0x30000000, 00000000); + int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); + CHECK_EQ(static_cast<int64_t>(1), result); +} + + +TEST(AssemblerX64XorlOperations) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); + + __ movq(rax, Operand(arg2, 0)); + __ xorl(Operand(arg1, 0), rax); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + // Call the function from C++. + int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); + int64_t right = V8_2PART_UINT64_C(0x30000000, 60000000); + int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); + CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left); + USE(result); +} + + TEST(AssemblerX64MemoryOperands) { // Allocate an executable page of memory. size_t actual_size; @@ -200,7 +327,7 @@ TEST(AssemblerX64MemoryOperands) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 2 and returns it. __ push(rbp); @@ -234,7 +361,7 @@ TEST(AssemblerX64ControlFlow) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 1 and returns it. __ push(rbp); @@ -263,7 +390,7 @@ TEST(AssemblerX64LoopImmediates) { &actual_size, true)); CHECK(buffer); - Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); + Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); // Assemble two loops using rax as counter, and verify the ending counts. Label Fail; __ movq(rax, Immediate(-3)); @@ -353,7 +480,7 @@ TEST(AssemblerX64LabelChaining) { // Test chaining of label usages within instructions (issue 1644). CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - Assembler assm(Isolate::Current(), NULL, 0); + Assembler assm(CcTest::i_isolate(), NULL, 0); Label target; __ j(equal, &target); @@ -366,8 +493,8 @@ TEST(AssemblerX64LabelChaining) { TEST(AssemblerMultiByteNop) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::internal::byte buffer[1024]; - Isolate* isolate = Isolate::Current(); + byte buffer[1024]; + Isolate* isolate = CcTest::i_isolate(); Assembler assm(isolate, buffer, sizeof(buffer)); __ push(rbx); __ push(rcx); @@ -420,7 +547,7 @@ TEST(AssemblerMultiByteNop) { Code* code = Code::cast(isolate->heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), - v8::internal::Handle<Code>())->ToObjectChecked()); + Handle<Code>())->ToObjectChecked()); CHECK(code->IsCode()); F0 f = FUNCTION_CAST<F0>(code->entry()); @@ -433,15 +560,14 @@ TEST(AssemblerMultiByteNop) { #define ELEMENT_COUNT 4 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { - CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::internal::byte buffer[1024]; + byte buffer[1024]; CHECK(args[0]->IsArray()); v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); CHECK_EQ(ELEMENT_COUNT, vec->Length()); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Assembler assm(isolate, buffer, sizeof(buffer)); // Remove return address from the stack for fix stack frame alignment. @@ -473,7 +599,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { Code* code = Code::cast(isolate->heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), - v8::internal::Handle<Code>())->ToObjectChecked()); + Handle<Code>())->ToObjectChecked()); CHECK(code->IsCode()); F0 f = FUNCTION_CAST<F0>(code->entry()); @@ -483,9 +609,10 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(StackAlignmentForSSE2) { + CcTest::InitializeVM(); CHECK_EQ(0, OS::ActivationFrameAlignment() % 16); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2)); @@ -517,4 +644,36 @@ TEST(StackAlignmentForSSE2) { #endif // __GNUC__ +TEST(AssemblerX64Extractps) { + CcTest::InitializeVM(); + if (!CpuFeatures::IsSupported(SSE4_1)) return; + + v8::HandleScope scope(CcTest::isolate()); + byte buffer[256]; + Isolate* isolate = CcTest::i_isolate(); + Assembler assm(isolate, buffer, sizeof(buffer)); + { CpuFeatureScope fscope2(&assm, SSE4_1); + __ extractps(rax, xmm0, 0x1); + __ ret(0); + } + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = Code::cast(isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked()); + CHECK(code->IsCode()); +#ifdef OBJECT_PRINT + Code::cast(code)->Print(); +#endif + + F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); + uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321); + CHECK_EQ(0x12345678, f(uint64_to_double(value1))); + uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678); + CHECK_EQ(0x87654321, f(uint64_to_double(value2))); +} + + #undef __ diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc index 9f20110801..299f2a8960 100644 --- a/deps/v8/test/cctest/test-ast.cc +++ b/deps/v8/test/cctest/test-ast.cc @@ -39,10 +39,10 @@ TEST(List) { List<AstNode*>* list = new List<AstNode*>(0); CHECK_EQ(0, list->length()); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Zone zone(isolate); AstNodeFactory<AstNullVisitor> factory(isolate, &zone); - AstNode* node = factory.NewEmptyStatement(); + AstNode* node = factory.NewEmptyStatement(RelocInfo::kNoPosition); list->Add(node); CHECK_EQ(1, list->length()); CHECK_EQ(node, list->at(0)); diff --git a/deps/v8/test/cctest/test-code-stubs-arm.cc b/deps/v8/test/cctest/test-code-stubs-arm.cc index c99433edad..54eaa58318 100644 --- a/deps/v8/test/cctest/test-code-stubs-arm.cc +++ b/deps/v8/test/cctest/test-code-stubs-arm.cc @@ -143,7 +143,7 @@ static Isolate* GetIsolateFrom(LocalContext* context) { int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, double from) { #ifdef USE_SIMULATOR - return reinterpret_cast<int32_t>(CALL_GENERATED_CODE(func, from, 0, 0, 0, 0)); + return CALL_GENERATED_FP_INT(func, from, 0); #else return (*func)(from); #endif diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index 7e87e10991..9fd68e5222 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -79,7 +79,7 @@ v8::DeclareExtension kPrintExtensionDeclaration(&kPrintExtension); static MaybeObject* GetGlobalProperty(const char* name) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Handle<String> internalized_name = isolate->factory()->InternalizeUtf8String(name); return isolate->context()->global_object()->GetProperty(*internalized_name); @@ -87,7 +87,7 @@ static MaybeObject* GetGlobalProperty(const char* name) { static void SetGlobalProperty(const char* name, Object* value) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Handle<Object> object(value, isolate); Handle<String> internalized_name = isolate->factory()->InternalizeUtf8String(name); @@ -97,7 +97,7 @@ static void SetGlobalProperty(const char* name, Object* value) { static Handle<JSFunction> Compile(const char* source) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Handle<String> source_code( isolate->factory()->NewStringFromUtf8(CStrVector(source))); Handle<SharedFunctionInfo> shared_function = @@ -202,8 +202,9 @@ TEST(Sum) { TEST(Print) { - CcTest::InitializeVM(PRINT_EXTENSION); v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION); + v8::Context::Scope context_scope(context); const char* source = "for (n = 0; n < 100; ++n) print(n, 1, 2);"; Handle<JSFunction> fun = Compile(source); if (fun.is_null()) return; @@ -273,8 +274,10 @@ TEST(UncaughtThrow) { // | JS | // | C-to-JS | TEST(C2JSFrames) { - CcTest::InitializeVM(PRINT_EXTENSION | GC_EXTENSION); v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = + CcTest::NewContext(PRINT_EXTENSION | GC_EXTENSION); + v8::Context::Scope context_scope(context); const char* source = "function foo(a) { gc(), print(a); }"; @@ -312,12 +315,12 @@ TEST(C2JSFrames) { // source resulted in crash. TEST(Regression236) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); Handle<Script> script = factory->NewScript(factory->empty_string()); - script->set_source(HEAP->undefined_value()); + script->set_source(CcTest::heap()->undefined_value()); CHECK_EQ(-1, GetScriptLineNumber(script, 0)); CHECK_EQ(-1, GetScriptLineNumber(script, 100)); CHECK_EQ(-1, GetScriptLineNumber(script, -1)); @@ -325,7 +328,7 @@ TEST(Regression236) { TEST(GetScriptLineNumber) { - CcTest::InitializeVM(); + LocalContext context; v8::HandleScope scope(CcTest::isolate()); v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); const char function_f[] = "function f() {}"; @@ -342,7 +345,7 @@ TEST(GetScriptLineNumber) { v8::Handle<v8::String> script_body = v8::String::New(buffer.start()); v8::Script::Compile(script_body, &origin)->Run(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - CcTest::env()->Global()->Get(v8::String::New("f"))); + context->Global()->Get(v8::String::New("f"))); CHECK_EQ(i, f->GetScriptLineNumber()); } } @@ -374,8 +377,10 @@ TEST(OptimizedCodeSharing) { *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1")))); Handle<JSFunction> fun2 = v8::Utils::OpenHandle( *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2")))); - CHECK(fun1->IsOptimized() || !fun1->IsOptimizable()); - CHECK(fun2->IsOptimized() || !fun2->IsOptimizable()); + CHECK(fun1->IsOptimized() + || !CcTest::i_isolate()->use_crankshaft() || !fun1->IsOptimizable()); + CHECK(fun2->IsOptimized() + || !CcTest::i_isolate()->use_crankshaft() || !fun2->IsOptimizable()); CHECK_EQ(fun1->code(), fun2->code()); } } @@ -420,16 +425,16 @@ static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) { TEST(SplitConstantsInFullCompiler) { - CcTest::InitializeVM(); + LocalContext context; v8::HandleScope scope(CcTest::isolate()); CompileRun("function f() { a = 12345678 }; f();"); - CheckCodeForUnsafeLiteral(GetJSFunction(CcTest::env()->Global(), "f")); + CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); CompileRun("function f(x) { a = 12345678 + x}; f(1);"); - CheckCodeForUnsafeLiteral(GetJSFunction(CcTest::env()->Global(), "f")); + CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);"); - CheckCodeForUnsafeLiteral(GetJSFunction(CcTest::env()->Global(), "f")); + CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);"); - CheckCodeForUnsafeLiteral(GetJSFunction(CcTest::env()->Global(), "f")); + CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); } #endif diff --git a/deps/v8/test/cctest/test-constantpool.cc b/deps/v8/test/cctest/test-constantpool.cc new file mode 100644 index 0000000000..9f2436c034 --- /dev/null +++ b/deps/v8/test/cctest/test-constantpool.cc @@ -0,0 +1,50 @@ +// Copyright 2013 the V8 project authors. All rights reserved. + +// Test constant pool array code. + +#include "v8.h" + +#include "factory.h" +#include "objects.h" +#include "cctest.h" + +using namespace v8::internal; + + +TEST(ConstantPool) { + LocalContext context; + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + Factory* factory = isolate->factory(); + v8::HandleScope scope(context->GetIsolate()); + + // Check construction. + Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(3, 2, 1); + CHECK_EQ(array->count_of_int64_entries(), 3); + CHECK_EQ(array->count_of_ptr_entries(), 2); + CHECK_EQ(array->count_of_int32_entries(), 1); + CHECK_EQ(array->length(), 6); + CHECK_EQ(array->first_int64_index(), 0); + CHECK_EQ(array->first_ptr_index(), 3); + CHECK_EQ(array->first_int32_index(), 5); + + // Check getters and setters. + int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0); + Handle<Object> object = factory->NewHeapNumber(4.0); + array->set(0, big_number); + array->set(1, 0.5); + array->set(3, *object); + array->set(5, 50); + CHECK_EQ(array->get_int64_entry(0), big_number); + CHECK_EQ(array->get_int64_entry_as_double(1), 0.5); + CHECK_EQ(array->get_ptr_entry(3), *object); + CHECK_EQ(array->get_int32_entry(5), 50); + + // Check pointers are updated on GC. + Object* old_ptr = array->get_ptr_entry(3); + CHECK_EQ(*object, old_ptr); + heap->CollectGarbage(NEW_SPACE); + Object* new_ptr = array->get_ptr_entry(3); + CHECK_NE(*object, old_ptr); + CHECK_EQ(*object, new_ptr); +} diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index 4708f506d2..9ef307c6f4 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -127,7 +127,7 @@ i::Code* CreateCode(LocalContext* env) { TEST(CodeEvents) { CcTest::InitializeVM(); LocalContext env; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); TestSetup test_setup; @@ -196,7 +196,7 @@ static int CompareProfileNodes(const T* p1, const T* p2) { TEST(TickEvents) { TestSetup test_setup; LocalContext env; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::HandleScope scope(isolate); i::Code* frame1_code = CreateCode(&env); @@ -254,7 +254,7 @@ TEST(TickEvents) { TEST(CrashIfStoppingLastNonExistentProfile) { CcTest::InitializeVM(); TestSetup test_setup; - CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler(); + CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); profiler->StartProfiling("1"); profiler->StopProfiling("2"); profiler->StartProfiling("1"); @@ -267,7 +267,7 @@ TEST(CrashIfStoppingLastNonExistentProfile) { TEST(Issue1398) { TestSetup test_setup; LocalContext env; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::HandleScope scope(isolate); i::Code* code = CreateCode(&env); @@ -309,7 +309,7 @@ TEST(Issue1398) { TEST(DeleteAllCpuProfiles) { CcTest::InitializeVM(); TestSetup test_setup; - CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler(); + CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); CHECK_EQ(0, profiler->GetProfilesCount()); profiler->DeleteAllProfiles(); CHECK_EQ(0, profiler->GetProfilesCount()); @@ -396,26 +396,6 @@ TEST(DeleteCpuProfile) { } -TEST(GetProfilerWhenIsolateIsNotInitialized) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK(i::Isolate::Current()->IsDefaultIsolate()); - CHECK(!i::Isolate::Current()->IsInitialized()); - CHECK_EQ(NULL, isolate->GetCpuProfiler()); - { - v8::Isolate::Scope isolateScope(isolate); - LocalContext env; - v8::HandleScope scope(isolate); - CHECK_NE(NULL, isolate->GetCpuProfiler()); - isolate->GetCpuProfiler()->StartCpuProfiling(v8::String::New("Test")); - isolate->GetCpuProfiler()->StopCpuProfiling(v8::String::New("Test")); - } - CHECK(i::Isolate::Current()->IsInitialized()); - CHECK_NE(NULL, isolate->GetCpuProfiler()); - isolate->Dispose(); - CHECK_EQ(NULL, isolate->GetCpuProfiler()); -} - - TEST(ProfileStartEndTime) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -495,7 +475,12 @@ static const v8::CpuProfileNode* FindChild(const v8::CpuProfileNode* node, static const v8::CpuProfileNode* GetChild(const v8::CpuProfileNode* node, const char* name) { const v8::CpuProfileNode* result = FindChild(node, name); - CHECK(result); + if (!result) { + char buffer[100]; + i::OS::SNPrintF(Vector<char>(buffer, ARRAY_SIZE(buffer)), + "Failed to GetChild: %s", name); + FATAL(buffer); + } return result; } @@ -610,7 +595,7 @@ static const char* cpu_profiler_test_source2 = "function loop() {}\n" " } while (++k < count*100*1000);\n" "}\n"; -// Check that the profile tree doesn't contain unexpecte traces: +// Check that the profile tree doesn't contain unexpected traces: // - 'loop' can be called only by 'delay' // - 'delay' may be called only by 'start' // The profile will look like the following: @@ -973,7 +958,7 @@ TEST(FunctionCallSample) { v8::HandleScope scope(env->GetIsolate()); // Collect garbage that might have be generated while installing extensions. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); v8::Script::Compile(v8::String::New(call_function_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( @@ -1101,7 +1086,13 @@ TEST(FunctionApplySample) { } -static const char* js_native_js_test_source = "function foo(iterations) {\n" +static const char* js_native_js_test_source = +"var is_profiling = false;\n" +"function foo(iterations) {\n" +" if (!is_profiling) {\n" +" is_profiling = true;\n" +" startProfiling('my_profile');\n" +" }\n" " var r = 0;\n" " for (var i = 0; i < iterations; i++) { r += i; }\n" " return r;\n" @@ -1133,7 +1124,9 @@ static void CallJsFunction(const v8::FunctionCallbackInfo<v8::Value>& info) { // 55 1 bar #16 5 // 54 54 foo #16 6 TEST(JsNativeJsSample) { - LocalContext env; + const char* extensions[] = { "v8/profiler" }; + v8::ExtensionConfiguration config(1, extensions); + LocalContext env(&config); v8::HandleScope scope(env->GetIsolate()); v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( @@ -1149,7 +1142,7 @@ TEST(JsNativeJsSample) { int32_t duration_ms = 20; v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 50); + RunProfiler(env, function, args, ARRAY_SIZE(args), 10); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { @@ -1177,7 +1170,12 @@ TEST(JsNativeJsSample) { static const char* js_native_js_runtime_js_test_source = +"var is_profiling = false;\n" "function foo(iterations) {\n" +" if (!is_profiling) {\n" +" is_profiling = true;\n" +" startProfiling('my_profile');\n" +" }\n" " var r = 0;\n" " for (var i = 0; i < iterations; i++) { r += i; }\n" " return r;\n" @@ -1204,7 +1202,9 @@ static const char* js_native_js_runtime_js_test_source = // 51 51 foo #16 6 // 2 2 (program) #0 2 TEST(JsNativeJsRuntimeJsSample) { - LocalContext env; + const char* extensions[] = { "v8/profiler" }; + v8::ExtensionConfiguration config(1, extensions); + LocalContext env(&config); v8::HandleScope scope(env->GetIsolate()); v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( @@ -1221,7 +1221,7 @@ TEST(JsNativeJsRuntimeJsSample) { int32_t duration_ms = 20; v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 50); + RunProfiler(env, function, args, ARRAY_SIZE(args), 10); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); @@ -1252,7 +1252,12 @@ static void CallJsFunction2(const v8::FunctionCallbackInfo<v8::Value>& info) { static const char* js_native1_js_native2_js_test_source = +"var is_profiling = false;\n" "function foo(iterations) {\n" +" if (!is_profiling) {\n" +" is_profiling = true;\n" +" startProfiling('my_profile');\n" +" }\n" " var r = 0;\n" " for (var i = 0; i < iterations; i++) { r += i; }\n" " return r;\n" @@ -1279,7 +1284,9 @@ static const char* js_native1_js_native2_js_test_source = // 54 54 foo #16 7 // 2 2 (program) #0 2 TEST(JsNative1JsNative2JsSample) { - LocalContext env; + const char* extensions[] = { "v8/profiler" }; + v8::ExtensionConfiguration config(1, extensions); + LocalContext env(&config); v8::HandleScope scope(env->GetIsolate()); v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( @@ -1301,7 +1308,7 @@ TEST(JsNative1JsNative2JsSample) { int32_t duration_ms = 20; v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 50); + RunProfiler(env, function, args, ARRAY_SIZE(args), 10); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); @@ -1341,7 +1348,7 @@ TEST(IdleTime) { v8::Local<v8::String> profile_name = v8::String::New("my_profile"); cpu_profiler->StartCpuProfiling(profile_name); - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::ProfilerEventsProcessor* processor = isolate->cpu_profiler()->processor(); processor->AddCurrentStack(isolate); @@ -1380,3 +1387,56 @@ TEST(IdleTime) { cpu_profiler->DeleteAllCpuProfiles(); } + + +static void CheckFunctionDetails(const v8::CpuProfileNode* node, + const char* name, const char* script_name, int script_id, + int line, int column) { + CHECK_EQ(v8::String::New(name), node->GetFunctionName()); + CHECK_EQ(v8::String::New(script_name), node->GetScriptResourceName()); + CHECK_EQ(script_id, node->GetScriptId()); + CHECK_EQ(line, node->GetLineNumber()); + CHECK_EQ(column, node->GetColumnNumber()); +} + + +TEST(FunctionDetails) { + const char* extensions[] = { "v8/profiler" }; + v8::ExtensionConfiguration config(1, extensions); + LocalContext env(&config); + v8::HandleScope handleScope(env->GetIsolate()); + + v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler(); + CHECK_EQ(0, profiler->GetProfileCount()); + v8::Handle<v8::Script> script_a = v8::Script::Compile(v8::String::New( + " function foo\n() { try { bar(); } catch(e) {} }\n" + " function bar() { startProfiling(); }\n"), v8::String::New("script_a")); + script_a->Run(); + v8::Handle<v8::Script> script_b = v8::Script::Compile(v8::String::New( + "\n\n function baz() { try { foo(); } catch(e) {} }\n" + "\n\nbaz();\n" + "stopProfiling();\n"), v8::String::New("script_b")); + script_b->Run(); + CHECK_EQ(1, profiler->GetProfileCount()); + const v8::CpuProfile* profile = profiler->GetCpuProfile(0); + const v8::CpuProfileNode* current = profile->GetTopDownRoot(); + reinterpret_cast<ProfileNode*>( + const_cast<v8::CpuProfileNode*>(current))->Print(0); + // The tree should look like this: + // 0 (root) 0 #1 + // 0 (anonymous function) 19 #2 no reason script_b:1 + // 0 baz 19 #3 TryCatchStatement script_b:3 + // 0 foo 18 #4 TryCatchStatement script_a:2 + // 1 bar 18 #5 no reason script_a:3 + const v8::CpuProfileNode* root = profile->GetTopDownRoot(); + const v8::CpuProfileNode* script = GetChild(root, + ProfileGenerator::kAnonymousFunctionName); + CheckFunctionDetails(script, ProfileGenerator::kAnonymousFunctionName, + "script_b", script_b->GetId(), 1, 1); + const v8::CpuProfileNode* baz = GetChild(script, "baz"); + CheckFunctionDetails(baz, "baz", "script_b", script_b->GetId(), 3, 16); + const v8::CpuProfileNode* foo = GetChild(baz, "foo"); + CheckFunctionDetails(foo, "foo", "script_a", script_a->GetId(), 2, 1); + const v8::CpuProfileNode* bar = GetChild(foo, "bar"); + CheckFunctionDetails(bar, "bar", "script_a", script_a->GetId(), 3, 14); +} diff --git a/deps/v8/test/cctest/test-dataflow.cc b/deps/v8/test/cctest/test-dataflow.cc index f3f0308236..532c9207b6 100644 --- a/deps/v8/test/cctest/test-dataflow.cc +++ b/deps/v8/test/cctest/test-dataflow.cc @@ -36,7 +36,7 @@ using namespace v8::internal; TEST(BitVector) { v8::internal::V8::Initialize(NULL); - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); { BitVector v(15, &zone); v.Add(1); diff --git a/deps/v8/test/cctest/test-date.cc b/deps/v8/test/cctest/test-date.cc index 6336481dcc..460c07e5aa 100644 --- a/deps/v8/test/cctest/test-date.cc +++ b/deps/v8/test/cctest/test-date.cc @@ -109,7 +109,7 @@ static int64_t TimeFromYearMonthDay(DateCache* date_cache, static void CheckDST(int64_t time) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); DateCache* date_cache = isolate->date_cache(); int64_t actual = date_cache->ToLocal(time); int64_t expected = time + date_cache->GetLocalOffsetFromOS() + diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index 2540a3dfe5..1bd1dc3a0d 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -29,7 +29,6 @@ #include <stdlib.h> -#define V8_DISABLE_DEPRECATIONS 1 #include "v8.h" #include "api.h" @@ -43,7 +42,6 @@ #include "platform/socket.h" #include "stub-cache.h" #include "utils.h" -#undef V8_DISABLE_DEPRECATIONS using ::v8::internal::Mutex; @@ -142,9 +140,9 @@ class DebugLocalContext { v8::Handle<v8::ObjectTemplate> global_template = v8::Handle<v8::ObjectTemplate>(), v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) - : scope_(v8::Isolate::GetCurrent()), + : scope_(CcTest::isolate()), context_( - v8::Context::New(v8::Isolate::GetCurrent(), + v8::Context::New(CcTest::isolate(), extensions, global_template, global_object)) { @@ -200,8 +198,10 @@ static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, static v8::Local<v8::Function> CompileFunction(const char* source, const char* function_name) { v8::Script::Compile(v8::String::New(source))->Run(); + v8::Local<v8::Object> global = + CcTest::isolate()->GetCurrentContext()->Global(); return v8::Local<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8::String::New(function_name))); + global->Get(v8::String::New(function_name))); } @@ -302,7 +302,7 @@ static int SetScriptBreakPointByNameFromJS(const char* script_name, // Clear a break point. static void ClearBreakPoint(int break_point) { - v8::internal::Isolate* isolate = v8::internal::Isolate::Current(); + v8::internal::Isolate* isolate = CcTest::i_isolate(); v8::internal::Debug* debug = isolate->debug(); debug->ClearBreakPoint( Handle<Object>(v8::internal::Smi::FromInt(break_point), isolate)); @@ -364,7 +364,7 @@ static void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number, // Change break on exception. static void ChangeBreakOnException(bool caught, bool uncaught) { - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); debug->ChangeBreakOnException(v8::internal::BreakException, caught); debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); } @@ -391,7 +391,7 @@ static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) { // Prepare to step to next break location. static void PrepareStep(StepAction step_action) { - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); debug->PrepareStep(step_action, 1, StackFrame::NO_ID); } @@ -403,7 +403,7 @@ namespace internal { // Collect the currently debugged functions. Handle<FixedArray> GetDebuggedFunctions() { - Debug* debug = Isolate::Current()->debug(); + Debug* debug = CcTest::i_isolate()->debug(); v8::internal::DebugInfoListNode* node = debug->debug_info_list_; @@ -416,7 +416,7 @@ Handle<FixedArray> GetDebuggedFunctions() { // Allocate array for the debugged functions Handle<FixedArray> debugged_functions = - Isolate::Current()->factory()->NewFixedArray(count); + CcTest::i_isolate()->factory()->NewFixedArray(count); // Run through the debug info objects and collect all functions. count = 0; @@ -430,7 +430,7 @@ Handle<FixedArray> GetDebuggedFunctions() { static Handle<Code> ComputeCallDebugBreak(int argc) { - return Isolate::Current()->stub_cache()->ComputeCallDebugBreak(argc, + return CcTest::i_isolate()->stub_cache()->ComputeCallDebugBreak(argc, Code::CALL_IC); } @@ -439,15 +439,15 @@ static Handle<Code> ComputeCallDebugBreak(int argc) { void CheckDebuggerUnloaded(bool check_functions) { // Check that the debugger context is cleared and that there is no debug // information stored for the debugger. - CHECK(Isolate::Current()->debug()->debug_context().is_null()); - CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_); + CHECK(CcTest::i_isolate()->debug()->debug_context().is_null()); + CHECK_EQ(NULL, CcTest::i_isolate()->debug()->debug_info_list_); // Collect garbage to ensure weak handles are cleared. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask); // Iterate the head and check that there are no debugger related objects left. - HeapIterator iterator(HEAP); + HeapIterator iterator(CcTest::heap()); for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { CHECK(!obj->IsDebugInfo()); CHECK(!obj->IsBreakPointInfo()); @@ -472,8 +472,8 @@ void CheckDebuggerUnloaded(bool check_functions) { void ForceUnloadDebugger() { - Isolate::Current()->debugger()->never_unload_debugger_ = false; - Isolate::Current()->debugger()->UnloadDebugger(); + CcTest::i_isolate()->debugger()->never_unload_debugger_ = false; + CcTest::i_isolate()->debugger()->UnloadDebugger(); } @@ -508,7 +508,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env, const char* source, const char* name, int position, v8::internal::RelocInfo::Mode mode, Code* debug_break) { - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // Create function and set the break point. Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle( @@ -674,7 +674,7 @@ static void DebugEventBreakPointHitCount( v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); v8::Handle<v8::Object> event_data = event_details.GetEventData(); - v8::internal::Isolate* isolate = v8::internal::Isolate::Current(); + v8::internal::Isolate* isolate = CcTest::i_isolate(); Debug* debug = isolate->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -787,7 +787,7 @@ static void DebugEventCounter( v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); v8::Handle<v8::Object> event_data = event_details.GetEventData(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -849,7 +849,7 @@ static void DebugEventEvaluate( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -876,7 +876,7 @@ static void DebugEventRemoveBreakPoint( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Value> data = event_details.GetCallbackData(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -894,7 +894,7 @@ StepAction step_action = StepIn; // Step action to perform when stepping. static void DebugEventStep( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -921,7 +921,7 @@ static void DebugEventStepSequence( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -950,7 +950,7 @@ static void DebugEventStepSequence( static void DebugEventBreakPointCollectGarbage( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -961,10 +961,10 @@ static void DebugEventBreakPointCollectGarbage( break_point_hit_count++; if (break_point_hit_count % 2 == 0) { // Scavenge. - HEAP->CollectGarbage(v8::internal::NEW_SPACE); + CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); } else { // Mark sweep compact. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); } } } @@ -975,7 +975,7 @@ static void DebugEventBreakPointCollectGarbage( static void DebugEventBreak( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -985,10 +985,10 @@ static void DebugEventBreak( // Run the garbage collector to enforce heap verification if option // --verify-heap is set. - HEAP->CollectGarbage(v8::internal::NEW_SPACE); + CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); // Set the break flag again to come back here as soon as possible. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(CcTest::isolate()); } } @@ -1001,7 +1001,8 @@ static void DebugEventBreakMax( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); - v8::internal::Isolate* isolate = v8::internal::Isolate::Current(); + v8::Isolate* v8_isolate = CcTest::isolate(); + v8::internal::Isolate* isolate = CcTest::i_isolate(); v8::internal::Debug* debug = isolate->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -1023,11 +1024,11 @@ static void DebugEventBreakMax( } // Set the break flag again to come back here as soon as possible. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(v8_isolate); } else if (terminate_after_max_break_point_hit) { // Terminate execution after the last break if requested. - v8::V8::TerminateExecution(); + v8::V8::TerminateExecution(v8_isolate); } // Perform a full deoptimization when the specified number of @@ -1075,13 +1076,13 @@ TEST(DebugStub) { "function f2(){x=1;}", "f2", 0, v8::internal::RelocInfo::CODE_TARGET_CONTEXT, - Isolate::Current()->builtins()->builtin( + CcTest::i_isolate()->builtins()->builtin( Builtins::kStoreIC_DebugBreak)); CheckDebugBreakFunction(&env, "function f3(){var a=x;}", "f3", 0, v8::internal::RelocInfo::CODE_TARGET_CONTEXT, - Isolate::Current()->builtins()->builtin( + CcTest::i_isolate()->builtins()->builtin( Builtins::kLoadIC_DebugBreak)); // TODO(1240753): Make the test architecture independent or split @@ -1095,7 +1096,7 @@ TEST(DebugStub) { "f4", 0, v8::internal::RelocInfo::CODE_TARGET, - Isolate::Current()->builtins()->builtin( + CcTest::i_isolate()->builtins()->builtin( Builtins::kKeyedStoreIC_DebugBreak)); CheckDebugBreakFunction( &env, @@ -1103,7 +1104,7 @@ TEST(DebugStub) { "f5", 0, v8::internal::RelocInfo::CODE_TARGET, - Isolate::Current()->builtins()->builtin( + CcTest::i_isolate()->builtins()->builtin( Builtins::kKeyedLoadIC_DebugBreak)); #endif @@ -1113,7 +1114,7 @@ TEST(DebugStub) { "f6", 0, v8::internal::RelocInfo::CODE_TARGET, - Isolate::Current()->builtins()->builtin( + CcTest::i_isolate()->builtins()->builtin( Builtins::kCompareNilIC_DebugBreak)); // Check the debug break code stubs for call ICs with different number of @@ -1449,12 +1450,12 @@ static void CallAndGC(v8::Local<v8::Object> recv, CHECK_EQ(1 + i * 3, break_point_hit_count); // Scavenge and call function. - HEAP->CollectGarbage(v8::internal::NEW_SPACE); + CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); f->Call(recv, 0, NULL); CHECK_EQ(2 + i * 3, break_point_hit_count); // Mark sweep (and perhaps compact) and call function. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); f->Call(recv, 0, NULL); CHECK_EQ(3 + i * 3, break_point_hit_count); } @@ -2258,7 +2259,7 @@ TEST(ScriptBreakPointLineTopLevel) { } f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); SetScriptBreakPointByNameFromJS("test.html", 3, -1); @@ -2397,7 +2398,8 @@ TEST(DebuggerStatementBreakpoint) { // the correct results. TEST(DebugEvaluate) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); // Create a function for checking the evaluation when hitting a break point. @@ -2410,13 +2412,13 @@ TEST(DebugEvaluate) { // Different expected vaules of x and a when in a break point (u = undefined, // d = Hello, world!). struct EvaluateCheck checks_uu[] = { - {"x", v8::Undefined()}, - {"a", v8::Undefined()}, + {"x", v8::Undefined(isolate)}, + {"a", v8::Undefined(isolate)}, {NULL, v8::Handle<v8::Value>()} }; struct EvaluateCheck checks_hu[] = { {"x", v8::String::New("Hello, world!")}, - {"a", v8::Undefined()}, + {"a", v8::Undefined(isolate)}, {NULL, v8::Handle<v8::Value>()} }; struct EvaluateCheck checks_hh[] = { @@ -2482,7 +2484,7 @@ TEST(DebugEvaluate) { // parameter. checks = checks_uu; v8::Handle<v8::Value> argv_bar_1[2] = { - v8::Undefined(), + v8::Undefined(isolate), v8::Number::New(barbar_break_position) }; bar->Call(env->Global(), 2, argv_bar_1); @@ -2551,7 +2553,7 @@ v8::Handle<v8::Function> checkFrameEvalFunction; static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) { if (eventDetails.GetEvent() == v8::Break) { ++debugEventCount; - v8::HandleScope handleScope(v8::Isolate::GetCurrent()); + v8::HandleScope handleScope(CcTest::isolate()); v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() }; CHECK(checkGlobalEvalFunction->Call( @@ -2726,7 +2728,8 @@ TEST(DebugEvaluateWithoutStack) { " \"expression\":\"v1\",\"disable_break\":true" "}}"; - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_111, buffer)); + v8::Isolate* isolate = CcTest::isolate(); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_111, buffer)); const char* command_112 = "{\"seq\":112," "\"type\":\"request\"," @@ -2736,7 +2739,7 @@ TEST(DebugEvaluateWithoutStack) { " \"expression\":\"getAnimal()\",\"disable_break\":true" "}}"; - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_112, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_112, buffer)); const char* command_113 = "{\"seq\":113," "\"type\":\"request\"," @@ -2746,7 +2749,7 @@ TEST(DebugEvaluateWithoutStack) { " \"expression\":\"239 + 566\",\"disable_break\":true" "}}"; - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_113, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_113, buffer)); v8::Debug::ProcessDebugMessages(); @@ -2847,7 +2850,7 @@ TEST(DebugStepKeyedLoadLoop) { foo->Call(env->Global(), kArgc, args); // With stepping all break locations are hit. - CHECK_EQ(34, break_point_hit_count); + CHECK_EQ(35, break_point_hit_count); v8::Debug::SetDebugEventListener2(NULL); CheckDebuggerUnloaded(); @@ -2894,7 +2897,7 @@ TEST(DebugStepKeyedStoreLoop) { foo->Call(env->Global(), kArgc, args); // With stepping all break locations are hit. - CHECK_EQ(33, break_point_hit_count); + CHECK_EQ(34, break_point_hit_count); v8::Debug::SetDebugEventListener2(NULL); CheckDebuggerUnloaded(); @@ -2938,7 +2941,7 @@ TEST(DebugStepNamedLoadLoop) { foo->Call(env->Global(), 0, NULL); // With stepping all break locations are hit. - CHECK_EQ(54, break_point_hit_count); + CHECK_EQ(55, break_point_hit_count); v8::Debug::SetDebugEventListener2(NULL); CheckDebuggerUnloaded(); @@ -2982,7 +2985,7 @@ static void DoDebugStepNamedStoreLoop(int expected) { // Test of the stepping mechanism for named load in a loop. TEST(DebugStepNamedStoreLoop) { - DoDebugStepNamedStoreLoop(23); + DoDebugStepNamedStoreLoop(24); } @@ -3101,7 +3104,8 @@ TEST(DebugStepLocals) { TEST(DebugStepIf) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3125,14 +3129,14 @@ TEST(DebugStepIf) { // Stepping through the true part. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_true[argc] = { v8::True() }; + v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; foo->Call(env->Global(), argc, argv_true); CHECK_EQ(4, break_point_hit_count); // Stepping through the false part. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_false[argc] = { v8::False() }; + v8::Handle<v8::Value> argv_false[argc] = { v8::False(isolate) }; foo->Call(env->Global(), argc, argv_false); CHECK_EQ(5, break_point_hit_count); @@ -3354,7 +3358,7 @@ TEST(DebugStepForContinue) { v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; result = foo->Call(env->Global(), argc, argv_10); CHECK_EQ(5, result->Int32Value()); - CHECK_EQ(51, break_point_hit_count); + CHECK_EQ(52, break_point_hit_count); // Looping 100 times. step_action = StepIn; @@ -3362,7 +3366,7 @@ TEST(DebugStepForContinue) { v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; result = foo->Call(env->Global(), argc, argv_100); CHECK_EQ(50, result->Int32Value()); - CHECK_EQ(456, break_point_hit_count); + CHECK_EQ(457, break_point_hit_count); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener2(NULL); @@ -3406,7 +3410,7 @@ TEST(DebugStepForBreak) { v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; result = foo->Call(env->Global(), argc, argv_10); CHECK_EQ(9, result->Int32Value()); - CHECK_EQ(54, break_point_hit_count); + CHECK_EQ(55, break_point_hit_count); // Looping 100 times. step_action = StepIn; @@ -3414,7 +3418,7 @@ TEST(DebugStepForBreak) { v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; result = foo->Call(env->Global(), argc, argv_100); CHECK_EQ(99, result->Int32Value()); - CHECK_EQ(504, break_point_hit_count); + CHECK_EQ(505, break_point_hit_count); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener2(NULL); @@ -3503,7 +3507,8 @@ TEST(DebugStepWith) { TEST(DebugConditional) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3527,7 +3532,7 @@ TEST(DebugConditional) { step_action = StepIn; break_point_hit_count = 0; const int argc = 1; - v8::Handle<v8::Value> argv_true[argc] = { v8::True() }; + v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; foo->Call(env->Global(), argc, argv_true); CHECK_EQ(5, break_point_hit_count); @@ -3755,7 +3760,8 @@ TEST(DebugStepFunctionApply) { // Test that step in works with function.call. TEST(DebugStepFunctionCall) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Create a function for testing stepping. v8::Local<v8::Function> foo = CompileFunction( @@ -3782,7 +3788,7 @@ TEST(DebugStepFunctionCall) { // Check stepping where the if condition in bar is true. break_point_hit_count = 0; const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { v8::True() }; + v8::Handle<v8::Value> argv[argc] = { v8::True(isolate) }; foo->Call(env->Global(), argc, argv); CHECK_EQ(8, break_point_hit_count); @@ -3845,7 +3851,7 @@ TEST(BreakOnException) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::internal::Isolate::Current()->TraceException(false); + CcTest::i_isolate()->TraceException(false); // Create functions for testing break on exception. CompileFunction(&env, "function throws(){throw 1;}", "throws"); @@ -3991,7 +3997,7 @@ TEST(BreakOnCompileException) { // For this test, we want to break on uncaught exceptions: ChangeBreakOnException(false, true); - v8::internal::Isolate::Current()->TraceException(false); + CcTest::i_isolate()->TraceException(false); // Create a function for checking the function when hitting a break point. frame_count = CompileFunction(&env, frame_count_source, "frame_count"); @@ -4162,7 +4168,7 @@ TEST(DebugBreak) { f3->Call(env->Global(), 0, NULL); // Set the debug break flag. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); // Call all functions with different argument count. break_point_hit_count = 0; @@ -4196,7 +4202,7 @@ TEST(DisableBreak) { v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); // Set the debug break flag. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); // Call all functions with different argument count. break_point_hit_count = 0; @@ -4204,7 +4210,7 @@ TEST(DisableBreak) { CHECK_EQ(1, break_point_hit_count); { - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); v8::internal::DisableBreak disable_break(isolate, true); f->Call(env->Global(), 0, NULL); @@ -4227,14 +4233,14 @@ static const char* kSimpleExtensionSource = // http://crbug.com/28933 // Test that debug break is disabled when bootstrapper is active. TEST(NoBreakWhenBootstrapping) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); // Register a debug event listener which sets the break flag and counts. v8::Debug::SetDebugEventListener2(DebugEventCounter); // Set the debug break flag. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(isolate); break_point_hit_count = 0; { // Create a context with an extension to make sure that some JavaScript @@ -4889,11 +4895,12 @@ void MessageQueueDebuggerThread::Run() { // until the execution of source_2. // Note: AsciiToUtf16 executes before SendCommand, so command is copied // to buffer before buffer is sent to SendCommand. - v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); + v8::Isolate* isolate = CcTest::isolate(); + v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1)); + v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2)); + v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); + v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); + v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); message_queue_barriers.barrier_2.Wait(); // Main thread compiles and runs source_2. // Queued commands are executed at the start of compilation of source_2( @@ -4913,18 +4920,20 @@ void MessageQueueDebuggerThread::Run() { // Wait on break event from hitting "debugger" statement message_queue_barriers.semaphore_2.Wait(); // These should execute after the "debugger" statement in source_2 - v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2)); + v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1)); + v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2)); + v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); + v8::Debug::SendCommand( + isolate, buffer_2, AsciiToUtf16(command_single_step, buffer_2)); // Run after 2 break events, 4 responses. for (int i = 0; i < 6 ; ++i) { message_queue_barriers.semaphore_1.Signal(); } // Wait on break event after a single step executes. message_queue_barriers.semaphore_2.Wait(); - v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); - v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); + v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_2, buffer_1)); + v8::Debug::SendCommand( + isolate, buffer_2, AsciiToUtf16(command_continue, buffer_2)); // Run after 2 responses. for (int i = 0; i < 2 ; ++i) { message_queue_barriers.semaphore_1.Signal(); @@ -5030,7 +5039,8 @@ static void MessageHandlerCountingClientData( TEST(SendClientDataToHandler) { // Create a V8 environment DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); TestClientData::ResetCounters(); handled_client_data_instances_count = 0; v8::Debug::SetMessageHandler2(MessageHandlerCountingClientData); @@ -5052,16 +5062,18 @@ TEST(SendClientDataToHandler) { "\"type\":\"request\"," "\"command\":\"continue\"}"; - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer), + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer), new TestClientData()); - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), NULL); - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), + v8::Debug::SendCommand( + isolate, buffer, AsciiToUtf16(command_2, buffer), NULL); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer), new TestClientData()); - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer), new TestClientData()); // All the messages will be processed on beforeCompile event. CompileRun(source_1); - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer)); + v8::Debug::SendCommand( + isolate, buffer, AsciiToUtf16(command_continue, buffer)); CHECK_EQ(3, TestClientData::constructor_call_counter); CHECK_EQ(TestClientData::constructor_call_counter, handled_client_data_instances_count); @@ -5134,14 +5146,14 @@ void V8Thread::Run() { "\n" "foo();\n"; - v8::V8::Initialize(); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetMessageHandler2(&ThreadedMessageHandler); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->Set(v8::String::New("ThreadedAtBarrier1"), v8::FunctionTemplate::New(ThreadedAtBarrier1)); - v8::Handle<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent(), + v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), NULL, global_template); v8::Context::Scope context_scope(context); @@ -5162,11 +5174,12 @@ void DebuggerThread::Run() { "\"type\":\"request\"," "\"command\":\"continue\"}"; + v8::Isolate* isolate = CcTest::isolate(); threaded_debugging_barriers.barrier_1.Wait(); - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(isolate); threaded_debugging_barriers.barrier_2.Wait(); - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer)); } @@ -5249,9 +5262,10 @@ void BreakpointsV8Thread::Run() { const char* source_2 = "cat(17);\n" "cat(19);\n"; - v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); + v8::Isolate::Scope isolate_scope(isolate); DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::HandleScope scope(isolate); v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler); CompileRun(source_1); @@ -5323,12 +5337,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(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(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 @@ -5340,38 +5356,38 @@ 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(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(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(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(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(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(buffer, AsciiToUtf16(command_8, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_8, buffer)); } @@ -5422,19 +5438,6 @@ TEST(SetMessageHandlerOnUninitializedVM) { } -TEST(DebugBreakOnUninitializedVM) { - v8::Debug::DebugBreak(); -} - - -TEST(SendCommandToUninitializedVM) { - const char* dummy_command = "{}"; - uint16_t dummy_buffer[80]; - int dummy_length = AsciiToUtf16(dummy_command, dummy_buffer); - v8::Debug::SendCommand(dummy_buffer, dummy_length); -} - - // Source for a JavaScript function which returns the data parameter of a // function called in the context of the debugger. If no data parameter is // passed it throws an exception. @@ -5505,7 +5508,7 @@ static void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(CallFunctionInDebugger) { // Create and enter a context with the functions CheckFrameCount, // CheckSourceLine and CheckDataParameter installed. - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->Set(v8::String::New("CheckFrameCount"), v8::FunctionTemplate::New(CheckFrameCount)); @@ -5515,7 +5518,7 @@ TEST(CallFunctionInDebugger) { v8::FunctionTemplate::New(CheckDataParameter)); global_template->Set(v8::String::New("CheckClosure"), v8::FunctionTemplate::New(CheckClosure)); - v8::Handle<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent(), + v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), NULL, global_template); v8::Context::Scope context_scope(context); @@ -5664,7 +5667,8 @@ static void SendContinueCommand() { "\"type\":\"request\"," "\"command\":\"continue\"}"; - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer)); + v8::Debug::SendCommand( + CcTest::isolate(), buffer, AsciiToUtf16(command_continue, buffer)); } @@ -5791,7 +5795,7 @@ void HostDispatchV8Thread::Run() { "\n"; const char* source_2 = "cat(17);\n"; - v8::V8::Initialize(); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -5818,10 +5822,11 @@ void HostDispatchDebuggerThread::Run() { "\"type\":\"request\"," "\"command\":\"continue\"}"; + v8::Isolate* isolate = CcTest::isolate(); // v8 thread initializes, runs source_1 host_dispatch_barriers->barrier_1.Wait(); // 1: Set breakpoint in cat(). - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer)); host_dispatch_barriers->barrier_2.Wait(); // v8 thread starts compiling source_2. @@ -5829,7 +5834,7 @@ void HostDispatchDebuggerThread::Run() { // Wait for host dispatch to be processed. host_dispatch_barriers->semaphore_1.Wait(); // 2: Continue evaluation - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); + v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer)); } @@ -5878,7 +5883,7 @@ static void DebugMessageHandler() { void DebugMessageDispatchV8Thread::Run() { - v8::V8::Initialize(); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -5920,7 +5925,7 @@ TEST(DebuggerDebugMessageDispatch) { TEST(DebuggerAgent) { v8::V8::Initialize(); - i::Debugger* debugger = i::Isolate::Current()->debugger(); + i::Debugger* debugger = CcTest::i_isolate()->debugger(); // Make sure these ports is not used by other tests to allow tests to run in // parallel. const int kPort1 = 5858 + FlagDependentPortOffset(); @@ -6235,7 +6240,7 @@ static void ContextCheckMessageHandler(const v8::Debug::Message& message) { // Checks that this data is set correctly and that when the debug message // handler is called the expected context is the one active. TEST(ContextData) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); // Create two contexts. @@ -6298,7 +6303,7 @@ static void DebugBreakMessageHandler(const v8::Debug::Message& message) { if (message.IsEvent() && message.GetEvent() == v8::Break) { message_handler_break_hit_count++; if (message_handler_break_hit_count == 1) { - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(message.GetIsolate()); } } @@ -6364,7 +6369,7 @@ static void DebugEventDebugBreak( // Keep forcing breaks. if (break_point_hit_count < 20) { - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(CcTest::isolate()); } } } @@ -6393,7 +6398,7 @@ TEST(RegExpDebugBreak) { CHECK_EQ(12, result->Int32Value()); v8::Debug::SetDebugEventListener2(DebugEventDebugBreak); - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); result = f->Call(env->Global(), argc, argv); // Check that there was only one break event. Matching RegExp should not @@ -6412,7 +6417,7 @@ static void ExecuteScriptForContextCheck( v8::Handle<v8::ObjectTemplate> global_template = v8::Handle<v8::ObjectTemplate>(); context_1 = - v8::Context::New(v8::Isolate::GetCurrent(), NULL, global_template); + v8::Context::New(CcTest::isolate(), NULL, global_template); v8::Debug::SetMessageHandler2(message_handler); @@ -6445,7 +6450,7 @@ static void ExecuteScriptForContextCheck( // break event in an eval statement the expected context is the one returned by // Message.GetEventContext. TEST(EvalContextData) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); ExecuteScriptForContextCheck(ContextCheckMessageHandler); @@ -6471,6 +6476,7 @@ static void DebugEvalContextCheckMessageHandler( v8::String::Value json(message.GetJSON()); Utf16ToAscii(*json, json.length(), print_buffer); + v8::Isolate* isolate = message.GetIsolate(); if (IsBreakEventMessage(print_buffer)) { break_count++; if (!sent_eval) { @@ -6486,7 +6492,8 @@ static void DebugEvalContextCheckMessageHandler( "\"global\":true,\"disable_break\":false}}"; // Send evaluate command. - v8::Debug::SendCommand(buffer, AsciiToUtf16(eval_command, buffer)); + v8::Debug::SendCommand( + isolate, buffer, AsciiToUtf16(eval_command, buffer)); return; } else { // It's a break event caused by the evaluation request above. @@ -6506,7 +6513,7 @@ static void DebugEvalContextCheckMessageHandler( // Tests that context returned for break event is correct when the event occurs // in 'evaluate' debugger request. TEST(NestedBreakEventContextData) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); break_count = 0; message_handler_hit_count = 0; @@ -6535,7 +6542,7 @@ static void DebugEventScriptCollectedEvent( // Test that scripts collected are reported through the debug event listener. TEST(ScriptCollectedEvent) { - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); break_point_hit_count = 0; script_collected_count = 0; DebugLocalContext env; @@ -6546,7 +6553,7 @@ TEST(ScriptCollectedEvent) { // Do garbage collection to ensure that only the script in this test will be // collected afterwards. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); script_collected_count = 0; v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent); @@ -6557,7 +6564,7 @@ TEST(ScriptCollectedEvent) { // Do garbage collection to collect the script above which is no longer // referenced. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); CHECK_EQ(2, script_collected_count); @@ -6582,7 +6589,7 @@ static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) { // ScriptCollected events. TEST(ScriptCollectedEventContext) { i::FLAG_stress_compaction = false; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::internal::Debug* debug = reinterpret_cast<v8::internal::Isolate*>(isolate)->debug(); script_collected_message_count = 0; @@ -6608,7 +6615,7 @@ TEST(ScriptCollectedEventContext) { // Do garbage collection to ensure that only the script in this test will be // collected afterwards. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); @@ -6625,7 +6632,7 @@ TEST(ScriptCollectedEventContext) { // Do garbage collection to collect the script above which is no longer // referenced. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); CHECK_EQ(2, script_collected_message_count); @@ -6660,7 +6667,7 @@ TEST(AfterCompileMessageWhenMessageHandlerIsReset) { v8::Debug::SetMessageHandler2(NULL); v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); v8::Script::Compile(v8::String::New(script))->Run(); // Setting listener to NULL should cause debugger unload. @@ -6684,7 +6691,7 @@ TEST(BreakMessageWhenMessageHandlerIsReset) { v8::Debug::SetMessageHandler2(NULL); v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); f->Call(env->Global(), 0, NULL); @@ -6773,7 +6780,7 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) { static void BreakMessageHandler(const v8::Debug::Message& message) { - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); if (message.IsEvent() && message.GetEvent() == v8::Break) { // Count the number of breaks. break_point_hit_count++; @@ -6812,7 +6819,7 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) { v8::Debug::SetMessageHandler2(BreakMessageHandler); // Set the debug break flag. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); // Create a function for testing stepping. const char* src = "function f() { eval('var x = 10;'); } "; @@ -6822,7 +6829,7 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) { CHECK_EQ(1, break_point_hit_count); // Set the debug break flag again. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); f->Call(env->Global(), 0, NULL); // There should be one more break event when the script is evaluated in 'f'. CHECK_EQ(2, break_point_hit_count); @@ -6843,7 +6850,8 @@ static void CountingMessageHandler(const v8::Debug::Message& message) { // Test that debug messages get processed when ProcessDebugMessages is called. TEST(ProcessDebugMessages) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); counting_message_handler_counter = 0; @@ -6857,7 +6865,8 @@ TEST(ProcessDebugMessages) { "\"command\":\"scripts\"}"; // Send scripts command. - v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); + v8::Debug::SendCommand( + isolate, buffer, AsciiToUtf16(scripts_command, buffer)); CHECK_EQ(0, counting_message_handler_counter); v8::Debug::ProcessDebugMessages(); @@ -6866,8 +6875,10 @@ TEST(ProcessDebugMessages) { counting_message_handler_counter = 0; - v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); - v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); + v8::Debug::SendCommand( + isolate, buffer, AsciiToUtf16(scripts_command, buffer)); + v8::Debug::SendCommand( + isolate, buffer, AsciiToUtf16(scripts_command, buffer)); CHECK_EQ(0, counting_message_handler_counter); v8::Debug::ProcessDebugMessages(); // At least two messages should come @@ -6899,7 +6910,8 @@ int BacktraceData::frame_counter; // Test that debug messages get processed when ProcessDebugMessages is called. TEST(Backtrace) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); v8::Debug::SetMessageHandler2(BacktraceData::MessageHandler); @@ -6912,7 +6924,11 @@ TEST(Backtrace) { // Check backtrace from ProcessDebugMessages. BacktraceData::frame_counter = -10; - v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); + v8::Debug::SendCommand( + isolate, + buffer, + AsciiToUtf16(scripts_command, buffer), + NULL); v8::Debug::ProcessDebugMessages(); CHECK_EQ(BacktraceData::frame_counter, 0); @@ -6921,7 +6937,11 @@ TEST(Backtrace) { // Check backtrace from "void(0)" script. BacktraceData::frame_counter = -10; - v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); + v8::Debug::SendCommand( + isolate, + buffer, + AsciiToUtf16(scripts_command, buffer), + NULL); script->Run(); CHECK_EQ(BacktraceData::frame_counter, 1); @@ -6965,7 +6985,7 @@ TEST(DebugBreakFunctionApply) { v8::Debug::SetDebugEventListener2(DebugEventBreakMax); // Set the debug break flag before calling the code using function.apply. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); // Limit the number of debug breaks. This is a regression test for issue 493 // where this test would enter an infinite loop. @@ -6991,10 +7011,10 @@ static void NamedGetterWithCallingContextCheck( v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { CHECK_EQ(0, strcmp(*v8::String::Utf8Value(name), "a")); - v8::Handle<v8::Context> current = v8::Context::GetCurrent(); + v8::Handle<v8::Context> current = info.GetIsolate()->GetCurrentContext(); CHECK(current == debugee_context); CHECK(current != debugger_context); - v8::Handle<v8::Context> calling = v8::Context::GetCalling(); + v8::Handle<v8::Context> calling = info.GetIsolate()->GetCallingContext(); CHECK(calling == debugee_context); CHECK(calling != debugger_context); info.GetReturnValue().Set(1); @@ -7010,7 +7030,7 @@ static void DebugEventGetAtgumentPropertyValue( v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); if (event == v8::Break) { break_point_hit_count++; - CHECK(debugger_context == v8::Context::GetCurrent()); + CHECK(debugger_context == CcTest::isolate()->GetCurrentContext()); v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(CompileRun( "(function(exec_state) {\n" " return (exec_state.frame(0).argumentValue(0).property('a').\n" @@ -7025,7 +7045,7 @@ static void DebugEventGetAtgumentPropertyValue( TEST(CallingContextIsNotDebugContext) { - v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); + v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // Create and enter a debugee context. DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -7065,7 +7085,7 @@ TEST(CallingContextIsNotDebugContext) { TEST(DebugContextIsPreservedBetweenAccesses) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); CHECK_EQ(*context1, *context2); @@ -7081,7 +7101,7 @@ static void DebugEventContextChecker(const v8::Debug::EventDetails& details) { // Check that event details contain context where debug event occured. TEST(DebugEventContext) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); expected_callback_data = v8::Int32::New(2010); expected_context = v8::Context::New(isolate); @@ -7112,7 +7132,8 @@ static void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) { // Check that event details contain context where debug event occured. TEST(DebugEventBreakData) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker); TestClientData::constructor_call_counter = 0; @@ -7121,7 +7142,7 @@ TEST(DebugEventBreakData) { expected_break_data = NULL; was_debug_event_called = false; was_debug_break_called = false; - v8::Debug::DebugBreakForCommand(); + v8::Debug::DebugBreakForCommand(NULL, isolate); v8::Script::Compile(v8::String::New("(function(x){return x;})(1);"))->Run(); CHECK(was_debug_event_called); CHECK(!was_debug_break_called); @@ -7130,7 +7151,7 @@ TEST(DebugEventBreakData) { expected_break_data = data1; was_debug_event_called = false; was_debug_break_called = false; - v8::Debug::DebugBreakForCommand(data1); + v8::Debug::DebugBreakForCommand(data1, isolate); v8::Script::Compile(v8::String::New("(function(x){return x+1;})(1);"))->Run(); CHECK(was_debug_event_called); CHECK(!was_debug_break_called); @@ -7138,7 +7159,7 @@ TEST(DebugEventBreakData) { expected_break_data = NULL; was_debug_event_called = false; was_debug_break_called = false; - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(isolate); v8::Script::Compile(v8::String::New("(function(x){return x+2;})(1);"))->Run(); CHECK(!was_debug_event_called); CHECK(was_debug_break_called); @@ -7147,8 +7168,8 @@ TEST(DebugEventBreakData) { expected_break_data = data2; was_debug_event_called = false; was_debug_break_called = false; - v8::Debug::DebugBreak(); - v8::Debug::DebugBreakForCommand(data2); + v8::Debug::DebugBreak(isolate); + v8::Debug::DebugBreakForCommand(data2, isolate); v8::Script::Compile(v8::String::New("(function(x){return x+3;})(1);"))->Run(); CHECK(was_debug_event_called); CHECK(was_debug_break_called); @@ -7180,13 +7201,13 @@ static void DebugEventBreakDeoptimize( v8::Handle<v8::String> function_name(result->ToString()); function_name->WriteUtf8(fn); if (strcmp(fn, "bar") == 0) { - i::Deoptimizer::DeoptimizeAll(v8::internal::Isolate::Current()); + i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate()); debug_event_break_deoptimize_done = true; } } } - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(CcTest::isolate()); } } @@ -7215,7 +7236,7 @@ TEST(DeoptimizeDuringDebugBreak) { v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run(); // Set debug break and call bar again. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(env->GetIsolate()); v8::Script::Compile(v8::String::New("bar()"))->Run(); CHECK(debug_event_break_deoptimize_done); @@ -7273,7 +7294,7 @@ static void DebugEventBreakWithOptimizedStack( static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::Debug::SetDebugEventListener2(DebugEventBreakWithOptimizedStack); - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(args.GetIsolate()); } @@ -7338,7 +7359,7 @@ static void TestDebugBreakInLoop(const char* loop_head, CompileRun(buffer.start()); // Set the debug break to enter the debugger as soon as possible. - v8::Debug::DebugBreak(); + v8::Debug::DebugBreak(CcTest::isolate()); // Call function with infinite loop. CompileRun("f();"); @@ -7408,7 +7429,7 @@ static void DebugBreakInlineListener( i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast( i::JSFunction::cast(*compiled_script)->shared()->script())); - int break_id = v8::internal::Isolate::Current()->debug()->break_id(); + int break_id = CcTest::i_isolate()->debug()->break_id(); char script[128]; i::Vector<char> script_vector(script, sizeof(script)); OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); @@ -7426,7 +7447,7 @@ static void DebugBreakInlineListener( i::GetScriptLineNumber(source_script, result->Int32Value())); } v8::Debug::SetDebugEventListener2(NULL); - v8::V8::TerminateExecution(); + v8::V8::TerminateExecution(CcTest::isolate()); } @@ -7526,7 +7547,7 @@ TEST(LiveEditEnabled) { v8::internal::FLAG_allow_natives_syntax = true; LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetLiveEditEnabled(true); + v8::Debug::SetLiveEditEnabled(true, env->GetIsolate()); CompileRun("%LiveEditCompareStrings('', '')"); } @@ -7535,7 +7556,7 @@ TEST(LiveEditDisabled) { v8::internal::FLAG_allow_natives_syntax = true; LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetLiveEditEnabled(false); + v8::Debug::SetLiveEditEnabled(false), env->GetIsolate(); CompileRun("%LiveEditCompareStrings('', '')"); } diff --git a/deps/v8/test/cctest/test-declarative-accessors.cc b/deps/v8/test/cctest/test-declarative-accessors.cc index fa5a0452fd..fb22ccdbab 100644 --- a/deps/v8/test/cctest/test-declarative-accessors.cc +++ b/deps/v8/test/cctest/test-declarative-accessors.cc @@ -78,7 +78,7 @@ class DescriptorTestHelper { DescriptorTestHelper() : isolate_(NULL), array_(new AlignedArray), handle_array_(new HandleArray) { v8::V8::Initialize(); - isolate_ = v8::Isolate::GetCurrent(); + isolate_ = CcTest::isolate(); } v8::Isolate* isolate_; // Data objects. diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc index 18f142061b..de27286dac 100644 --- a/deps/v8/test/cctest/test-decls.cc +++ b/deps/v8/test/cctest/test-decls.cc @@ -52,7 +52,7 @@ class DeclarationContext { virtual ~DeclarationContext() { if (is_initialized_) { - Isolate* isolate = Isolate::GetCurrent(); + Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); Local<Context> context = Local<Context>::New(isolate, context_); context->Exit(); @@ -116,7 +116,7 @@ DeclarationContext::DeclarationContext() void DeclarationContext::InitializeIfNeeded() { if (is_initialized_) return; - Isolate* isolate = Isolate::GetCurrent(); + Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); Local<FunctionTemplate> function = FunctionTemplate::New(); Local<Value> data = External::New(this); @@ -143,8 +143,8 @@ void DeclarationContext::Check(const char* source, InitializeIfNeeded(); // A retry after a GC may pollute the counts, so perform gc now // to avoid that. - HEAP->CollectGarbage(v8::internal::NEW_SPACE); - HandleScope scope(Isolate::GetCurrent()); + CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); + HandleScope scope(CcTest::isolate()); TryCatch catcher; catcher.SetVerbose(true); Local<Script> script = Script::Compile(String::New(source)); @@ -169,7 +169,8 @@ void DeclarationContext::Check(const char* source, CHECK_EQ(value, catcher.Exception()); } } - HEAP->CollectAllAvailableGarbage(); // Clean slate for the next test. + // Clean slate for the next test. + CcTest::heap()->CollectAllAvailableGarbage(); } @@ -226,14 +227,15 @@ v8::Handle<Integer> DeclarationContext::Query(Local<String> key) { // Test global declaration of a property the interceptor doesn't know // about and doesn't handle. TEST(Unknown) { - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); + v8::V8::Initialize(); { DeclarationContext context; context.Check("var x; x", 1, // access 1, // declaration 2, // declaration + initialization - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { DeclarationContext context; @@ -257,15 +259,16 @@ TEST(Unknown) { 1, // access 2, // declaration + initialization 1, // declaration - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { DeclarationContext context; + // SB 0 - BUG 1213579 context.Check("const x = 0; x", 1, // access 2, // declaration + initialization 1, // declaration - EXPECT_RESULT, Undefined()); // SB 0 - BUG 1213579 + EXPECT_RESULT, Undefined(CcTest::isolate())); } } @@ -281,7 +284,7 @@ class PresentPropertyContext: public DeclarationContext { TEST(Present) { - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); { PresentPropertyContext context; context.Check("var x; x", @@ -312,7 +315,7 @@ TEST(Present) { 1, // access 1, // initialization 1, // (re-)declaration - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { PresentPropertyContext context; @@ -335,14 +338,16 @@ class AbsentPropertyContext: public DeclarationContext { TEST(Absent) { - HandleScope scope(Isolate::GetCurrent()); + v8::Isolate* isolate = CcTest::isolate(); + v8::V8::Initialize(); + HandleScope scope(isolate); { AbsentPropertyContext context; context.Check("var x; x", 1, // access 1, // declaration 2, // declaration + initialization - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(isolate)); } { AbsentPropertyContext context; @@ -366,7 +371,7 @@ TEST(Absent) { 1, // access 2, // declaration + initialization 1, // declaration - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(isolate)); } { AbsentPropertyContext context; @@ -374,7 +379,7 @@ TEST(Absent) { 1, // access 2, // declaration + initialization 1, // declaration - EXPECT_RESULT, Undefined()); // SB 0 - BUG 1213579 + EXPECT_RESULT, Undefined(isolate)); // SB 0 - BUG 1213579 } { AbsentPropertyContext context; @@ -382,7 +387,7 @@ TEST(Absent) { 1, // access 1, // declaration 1, // declaration + initialization - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(isolate)); } } @@ -425,14 +430,15 @@ class AppearingPropertyContext: public DeclarationContext { TEST(Appearing) { - HandleScope scope(Isolate::GetCurrent()); + v8::V8::Initialize(); + HandleScope scope(CcTest::isolate()); { AppearingPropertyContext context; context.Check("var x; x", 1, // access 1, // declaration 2, // declaration + initialization - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { AppearingPropertyContext context; @@ -456,7 +462,7 @@ TEST(Appearing) { 1, // access 2, // declaration + initialization 1, // declaration - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { AppearingPropertyContext context; @@ -464,7 +470,7 @@ TEST(Appearing) { 1, // access 2, // declaration + initialization 1, // declaration - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); // Result is undefined because declaration succeeded but // initialization to 0 failed (due to context behavior). } @@ -517,14 +523,15 @@ class ReappearingPropertyContext: public DeclarationContext { TEST(Reappearing) { - HandleScope scope(Isolate::GetCurrent()); + v8::V8::Initialize(); + HandleScope scope(CcTest::isolate()); { ReappearingPropertyContext context; context.Check("const x; var x = 0", 0, 3, // const declaration+initialization, var initialization 3, // 2 x declaration + var initialization - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } } @@ -546,7 +553,7 @@ class ExistsInPrototypeContext: public DeclarationContext { TEST(ExistsInPrototype) { i::FLAG_es52_globals = true; - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); // Sanity check to make sure that the holder of the interceptor // really is the prototype object. @@ -563,7 +570,7 @@ TEST(ExistsInPrototype) { 0, 0, 0, - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { ExistsInPrototypeContext context; @@ -579,7 +586,7 @@ TEST(ExistsInPrototype) { 0, 0, 0, - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } { ExistsInPrototypeContext context; @@ -609,14 +616,15 @@ class AbsentInPrototypeContext: public DeclarationContext { TEST(AbsentInPrototype) { i::FLAG_es52_globals = true; - HandleScope scope(Isolate::GetCurrent()); + v8::V8::Initialize(); + HandleScope scope(CcTest::isolate()); { AbsentInPrototypeContext context; context.Check("if (false) { var x = 0; }; x", 0, 0, 0, - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } } @@ -656,7 +664,7 @@ class ExistsInHiddenPrototypeContext: public DeclarationContext { TEST(ExistsInHiddenPrototype) { i::FLAG_es52_globals = true; - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); { ExistsInHiddenPrototypeContext context; context.Check("var x; x", @@ -688,7 +696,7 @@ TEST(ExistsInHiddenPrototype) { 0, 0, 1, // (re-)declaration - EXPECT_RESULT, Undefined()); + EXPECT_RESULT, Undefined(CcTest::isolate())); } // TODO(mstarzinger): The semantics of global const is vague. @@ -706,8 +714,8 @@ TEST(ExistsInHiddenPrototype) { class SimpleContext { public: SimpleContext() - : handle_scope_(Isolate::GetCurrent()), - context_(Context::New(Isolate::GetCurrent())) { + : handle_scope_(CcTest::isolate()), + context_(Context::New(CcTest::isolate())) { context_->Enter(); } @@ -749,7 +757,7 @@ class SimpleContext { TEST(CrossScriptReferences) { - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); { SimpleContext context; context.Check("var x = 1; x", @@ -794,7 +802,7 @@ TEST(CrossScriptReferencesHarmony) { i::FLAG_harmony_scoping = true; i::FLAG_harmony_modules = true; - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); const char* decs[] = { "var x = 1; x", "x", "this.x", @@ -822,7 +830,7 @@ TEST(CrossScriptConflicts) { i::FLAG_harmony_scoping = true; i::FLAG_harmony_modules = true; - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); const char* firsts[] = { "var x = 1; x", diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc index 83a6354b2f..765b1ce55f 100644 --- a/deps/v8/test/cctest/test-deoptimization.cc +++ b/deps/v8/test/cctest/test-deoptimization.cc @@ -104,7 +104,7 @@ class AllowNativesSyntaxNoInliningNoConcurrent { // Abort any ongoing incremental marking to make sure that all weak global // handle callbacks are processed. static void NonIncrementalGC() { - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); } @@ -134,7 +134,7 @@ TEST(DeoptimizeSimple) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); // Test lazy deoptimization of a simple function. Call the function after the // deoptimization while it is still activated further down the stack. @@ -150,7 +150,7 @@ TEST(DeoptimizeSimple) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -172,7 +172,7 @@ TEST(DeoptimizeSimpleWithArguments) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); // Test lazy deoptimization of a simple function with some arguments. Call the // function after the deoptimization while it is still activated further down @@ -189,7 +189,7 @@ TEST(DeoptimizeSimpleWithArguments) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -213,7 +213,7 @@ TEST(DeoptimizeSimpleNested) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } } @@ -237,7 +237,7 @@ TEST(DeoptimizeRecursive) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); @@ -269,7 +269,7 @@ TEST(DeoptimizeMultiple) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -290,7 +290,7 @@ TEST(DeoptimizeConstructor) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); { AlwaysOptimizeAllowNativesSyntaxNoInlining options; @@ -307,7 +307,7 @@ TEST(DeoptimizeConstructor) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -336,7 +336,7 @@ TEST(DeoptimizeConstructorMultiple) { CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -367,7 +367,7 @@ TEST(DeoptimizeBinaryOperationADDString) { i::FLAG_always_opt = true; CompileRun(f_source); CompileRun("f('a+', new X());"); - CHECK(!i::Isolate::Current()->use_crankshaft() || + CHECK(!CcTest::i_isolate()->use_crankshaft() || GetJSFunction(env->Global(), "f")->IsOptimized()); // Call f and force deoptimization while processing the binary operation. @@ -382,7 +382,7 @@ TEST(DeoptimizeBinaryOperationADDString) { CHECK(result->IsString()); v8::String::Utf8Value utf8(result); CHECK_EQ("a+an X", *utf8); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -419,7 +419,7 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env, i::FLAG_always_opt = true; CompileRun(f_source); CompileRun("f(7, new X());"); - CHECK(!i::Isolate::Current()->use_crankshaft() || + CHECK(!CcTest::i_isolate()->use_crankshaft() || GetJSFunction((*env)->Global(), "f")->IsOptimized()); // Call f and force deoptimization while processing the binary operation. @@ -438,7 +438,7 @@ TEST(DeoptimizeBinaryOperationADD) { 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(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -450,7 +450,7 @@ TEST(DeoptimizeBinaryOperationSUB) { 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(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -462,7 +462,7 @@ TEST(DeoptimizeBinaryOperationMUL) { 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(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -474,7 +474,7 @@ TEST(DeoptimizeBinaryOperationDIV) { 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(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -486,7 +486,7 @@ TEST(DeoptimizeBinaryOperationMOD) { 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(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -517,7 +517,7 @@ TEST(DeoptimizeCompare) { i::FLAG_always_opt = true; CompileRun(f_source); CompileRun("f('a', new X());"); - CHECK(!i::Isolate::Current()->use_crankshaft() || + CHECK(!CcTest::i_isolate()->use_crankshaft() || GetJSFunction(env->Global(), "f")->IsOptimized()); // Call f and force deoptimization while processing the comparison. @@ -529,7 +529,7 @@ TEST(DeoptimizeCompare) { 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(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -587,7 +587,7 @@ TEST(DeoptimizeLoadICStoreIC) { CompileRun("g1(new X());"); CompileRun("f2(new X(), 'z');"); CompileRun("g2(new X(), 'z');"); - if (i::Isolate::Current()->use_crankshaft()) { + if (CcTest::i_isolate()->use_crankshaft()) { CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); @@ -609,7 +609,7 @@ TEST(DeoptimizeLoadICStoreIC) { 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()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -671,7 +671,7 @@ TEST(DeoptimizeLoadICStoreICNested) { CompileRun("g1(new X());"); CompileRun("f2(new X(), 'z');"); CompileRun("g2(new X(), 'z');"); - if (i::Isolate::Current()->use_crankshaft()) { + if (CcTest::i_isolate()->use_crankshaft()) { CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); @@ -690,5 +690,5 @@ TEST(DeoptimizeLoadICStoreICNested) { 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()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc index b9e8b1ec06..44f64f7881 100644 --- a/deps/v8/test/cctest/test-dictionary.cc +++ b/deps/v8/test/cctest/test-dictionary.cc @@ -41,7 +41,7 @@ using namespace v8::internal; TEST(ObjectHashTable) { LocalContext context; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(context->GetIsolate()); Handle<ObjectHashTable> table = factory->NewObjectHashTable(23); @@ -50,13 +50,13 @@ TEST(ObjectHashTable) { table = PutIntoObjectHashTable(table, a, b); CHECK_EQ(table->NumberOfElements(), 1); CHECK_EQ(table->Lookup(*a), *b); - CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value()); + CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value()); // Keys still have to be valid after objects were moved. - HEAP->CollectGarbage(NEW_SPACE); + CcTest::heap()->CollectGarbage(NEW_SPACE); CHECK_EQ(table->NumberOfElements(), 1); CHECK_EQ(table->Lookup(*a), *b); - CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value()); + CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value()); // Keys that are overwritten should not change number of elements. table = PutIntoObjectHashTable(table, a, factory->NewJSArray(13)); @@ -67,7 +67,7 @@ TEST(ObjectHashTable) { table = PutIntoObjectHashTable(table, a, factory->the_hole_value()); CHECK_EQ(table->NumberOfElements(), 0); CHECK_EQ(table->NumberOfDeletedElements(), 1); - CHECK_EQ(table->Lookup(*a), HEAP->the_hole_value()); + CHECK_EQ(table->Lookup(*a), CcTest::heap()->the_hole_value()); // Keys should map back to their respective values and also should get // an identity hash code generated. @@ -87,7 +87,7 @@ TEST(ObjectHashTable) { Handle<JSReceiver> key = factory->NewJSArray(7); CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi()); CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound); - CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value()); + CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value()); CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi()); } @@ -95,8 +95,9 @@ TEST(ObjectHashTable) { // should not get an identity hash code generated. for (int i = 0; i < 100; i++) { Handle<JSReceiver> key = factory->NewJSArray(7); - CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value()); - CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value()); + CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value()); + CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), + CcTest::heap()->undefined_value()); } } @@ -120,7 +121,7 @@ class ObjectHashTableTest: public ObjectHashTable { TEST(HashTableRehash) { LocalContext context; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(context->GetIsolate()); // Test almost filled table. @@ -156,7 +157,7 @@ TEST(HashTableRehash) { TEST(ObjectHashSetCausesGC) { i::FLAG_stress_compaction = false; LocalContext context; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(context->GetIsolate()); Handle<ObjectHashSet> table = factory->NewObjectHashSet(1); @@ -170,8 +171,8 @@ TEST(ObjectHashSetCausesGC) { // Simulate a full heap so that generating an identity hash code // in subsequent calls will request GC. - SimulateFullSpace(HEAP->new_space()); - SimulateFullSpace(HEAP->old_pointer_space()); + SimulateFullSpace(CcTest::heap()->new_space()); + SimulateFullSpace(CcTest::heap()->old_pointer_space()); // Calling Contains() should not cause GC ever. CHECK(!table->Contains(*key)); @@ -189,7 +190,7 @@ TEST(ObjectHashSetCausesGC) { TEST(ObjectHashTableCausesGC) { i::FLAG_stress_compaction = false; LocalContext context; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(context->GetIsolate()); Handle<ObjectHashTable> table = factory->NewObjectHashTable(1); @@ -203,8 +204,8 @@ TEST(ObjectHashTableCausesGC) { // Simulate a full heap so that generating an identity hash code // in subsequent calls will request GC. - SimulateFullSpace(HEAP->new_space()); - SimulateFullSpace(HEAP->old_pointer_space()); + SimulateFullSpace(CcTest::heap()->new_space()); + SimulateFullSpace(CcTest::heap()->old_pointer_space()); // Calling Lookup() should not cause GC ever. CHECK(table->Lookup(*key)->IsTheHole()); diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc index 2a53d43d41..cb1b1c798b 100644 --- a/deps/v8/test/cctest/test-disasm-arm.cc +++ b/deps/v8/test/cctest/test-disasm-arm.cc @@ -65,7 +65,7 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) { // in the rest of the macros. #define SET_UP() \ CcTest::InitializeVM(); \ - Isolate* isolate = Isolate::Current(); \ + Isolate* isolate = CcTest::i_isolate(); \ HandleScope scope(isolate); \ byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \ Assembler assm(isolate, buffer, 4*1024); \ diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc index 1b6af47233..301545c6c4 100644 --- a/deps/v8/test/cctest/test-disasm-ia32.cc +++ b/deps/v8/test/cctest/test-disasm-ia32.cc @@ -354,19 +354,29 @@ TEST(DisasmIa320) { CpuFeatureScope fscope(&assm, SSE2); __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000)); __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1); + __ movaps(xmm0, xmm1); + // 128 bit move instructions. + __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0); + __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0); + __ addsd(xmm1, xmm0); __ mulsd(xmm1, xmm0); __ subsd(xmm1, xmm0); __ divsd(xmm1, xmm0); - __ movdbl(xmm1, Operand(ebx, ecx, times_4, 10000)); - __ movdbl(Operand(ebx, ecx, times_4, 10000), xmm1); __ ucomisd(xmm0, xmm1); + __ cmpltsd(xmm0, xmm1); - // 128 bit move instructions. - __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000)); - __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0); - __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000)); - __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0); + __ andps(xmm0, xmm1); + __ andpd(xmm0, xmm1); + __ psllq(xmm0, 17); + __ psllq(xmm0, xmm1); + __ psrlq(xmm0, 17); + __ psrlq(xmm0, xmm1); + __ por(xmm0, xmm1); } } @@ -393,42 +403,13 @@ TEST(DisasmIa320) { } } - // andpd, cmpltsd, movaps, psllq, psrlq, por. - { - if (CpuFeatures::IsSupported(SSE2)) { - CpuFeatureScope fscope(&assm, SSE2); - __ andpd(xmm0, xmm1); - __ andpd(xmm1, xmm2); - - __ cmpltsd(xmm0, xmm1); - __ cmpltsd(xmm1, xmm2); - - __ movaps(xmm0, xmm1); - __ movaps(xmm1, xmm2); - - __ psllq(xmm0, 17); - __ psllq(xmm1, 42); - - __ psllq(xmm0, xmm1); - __ psllq(xmm1, xmm2); - - __ psrlq(xmm0, 17); - __ psrlq(xmm1, 42); - - __ psrlq(xmm0, xmm1); - __ psrlq(xmm1, xmm2); - - __ por(xmm0, xmm1); - __ por(xmm1, xmm2); - } - } - { if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(SSE4_1)) { CpuFeatureScope scope(&assm, SSE4_1); __ pextrd(eax, xmm0, 1); __ pinsrd(xmm1, eax, 0); + __ extractps(eax, xmm1, 0); } } diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc index 0e79a580f2..725b3a5674 100644 --- a/deps/v8/test/cctest/test-disasm-mips.cc +++ b/deps/v8/test/cctest/test-disasm-mips.cc @@ -65,7 +65,7 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) { // in the rest of the macros. #define SET_UP() \ CcTest::InitializeVM(); \ - Isolate* isolate = Isolate::Current(); \ + Isolate* isolate = CcTest::i_isolate(); \ HandleScope scope(isolate); \ byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \ Assembler assm(isolate, buffer, 4*1024); \ diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index 1ff9fd336b..8fd036956f 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -50,7 +50,7 @@ TEST(DisasmX64) { CcTest::InitializeVM(); v8::HandleScope scope; v8::internal::byte buffer[2048]; - Assembler assm(Isolate::Current(), buffer, sizeof buffer); + Assembler assm(CcTest::i_isolate(), buffer, sizeof buffer); DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging) // Short immediate instructions @@ -239,7 +239,7 @@ TEST(DisasmX64) { __ bind(&L2); __ call(Operand(rbx, rcx, times_4, 10000)); __ nop(); - Handle<Code> ic(Isolate::Current()->builtins()->builtin( + Handle<Code> ic(CcTest::i_isolate()->builtins()->builtin( Builtins::kLoadIC_Initialize)); __ call(ic, RelocInfo::CODE_TARGET); __ nop(); @@ -335,60 +335,59 @@ TEST(DisasmX64) { __ fcompp(); __ fwait(); __ nop(); + + // SSE instruction { - if (CpuFeatures::IsSupported(SSE2)) { - CpuFeatures::Scope fscope(SSE2); - __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000)); - __ cvttss2si(rdx, xmm1); - __ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000)); - __ cvttsd2si(rdx, xmm1); - __ cvttsd2siq(rdx, xmm1); - __ addsd(xmm1, xmm0); - __ mulsd(xmm1, xmm0); - __ subsd(xmm1, xmm0); - __ divsd(xmm1, xmm0); - __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000)); - __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1); - __ ucomisd(xmm0, xmm1); - - // 128 bit move instructions. - __ movdqa(xmm0, Operand(rbx, rcx, times_4, 10000)); - __ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0); - } + __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000)); + __ cvttss2si(rdx, xmm1); + __ movaps(xmm0, xmm1); + + __ andps(xmm0, xmm1); + } + // SSE 2 instructions + { + __ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000)); + __ cvttsd2si(rdx, xmm1); + __ cvttsd2siq(rdx, xmm1); + __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000)); + __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1); + // 128 bit move instructions. + __ movdqa(xmm0, Operand(rbx, rcx, times_4, 10000)); + __ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0); + + __ addsd(xmm1, xmm0); + __ mulsd(xmm1, xmm0); + __ subsd(xmm1, xmm0); + __ divsd(xmm1, xmm0); + __ ucomisd(xmm0, xmm1); + + __ andpd(xmm0, xmm1); } // cmov. { - if (CpuFeatures::IsSupported(CMOV)) { - CpuFeatures::Scope use_cmov(CMOV); - __ cmovq(overflow, rax, Operand(rax, 0)); - __ cmovq(no_overflow, rax, Operand(rax, 1)); - __ cmovq(below, rax, Operand(rax, 2)); - __ cmovq(above_equal, rax, Operand(rax, 3)); - __ cmovq(equal, rax, Operand(rbx, 0)); - __ cmovq(not_equal, rax, Operand(rbx, 1)); - __ cmovq(below_equal, rax, Operand(rbx, 2)); - __ cmovq(above, rax, Operand(rbx, 3)); - __ cmovq(sign, rax, Operand(rcx, 0)); - __ cmovq(not_sign, rax, Operand(rcx, 1)); - __ cmovq(parity_even, rax, Operand(rcx, 2)); - __ cmovq(parity_odd, rax, Operand(rcx, 3)); - __ cmovq(less, rax, Operand(rdx, 0)); - __ cmovq(greater_equal, rax, Operand(rdx, 1)); - __ cmovq(less_equal, rax, Operand(rdx, 2)); - __ cmovq(greater, rax, Operand(rdx, 3)); - } + __ cmovq(overflow, rax, Operand(rax, 0)); + __ cmovq(no_overflow, rax, Operand(rax, 1)); + __ cmovq(below, rax, Operand(rax, 2)); + __ cmovq(above_equal, rax, Operand(rax, 3)); + __ cmovq(equal, rax, Operand(rbx, 0)); + __ cmovq(not_equal, rax, Operand(rbx, 1)); + __ cmovq(below_equal, rax, Operand(rbx, 2)); + __ cmovq(above, rax, Operand(rbx, 3)); + __ cmovq(sign, rax, Operand(rcx, 0)); + __ cmovq(not_sign, rax, Operand(rcx, 1)); + __ cmovq(parity_even, rax, Operand(rcx, 2)); + __ cmovq(parity_odd, rax, Operand(rcx, 3)); + __ cmovq(less, rax, Operand(rdx, 0)); + __ cmovq(greater_equal, rax, Operand(rdx, 1)); + __ cmovq(less_equal, rax, Operand(rdx, 2)); + __ cmovq(greater, rax, Operand(rdx, 3)); } - // andpd, etc. { - if (CpuFeatures::IsSupported(SSE2)) { - CpuFeatures::Scope fscope(SSE2); - __ andpd(xmm0, xmm1); - __ andpd(xmm1, xmm2); - - __ movaps(xmm0, xmm1); - __ movaps(xmm1, xmm2); + if (CpuFeatures::IsSupported(SSE4_1)) { + CpuFeatureScope scope(&assm, SSE4_1); + __ extractps(rax, xmm1, 0); } } @@ -401,7 +400,7 @@ TEST(DisasmX64) { CodeDesc desc; assm.GetCode(&desc); - Object* code = HEAP->CreateCode( + Object* code = CcTest::heap()->CreateCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>())->ToObjectChecked(); diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc index 9cb12c4787..a1d2405ad5 100644 --- a/deps/v8/test/cctest/test-flags.cc +++ b/deps/v8/test/cctest/test-flags.cc @@ -54,15 +54,18 @@ TEST(Flags1) { TEST(Flags2) { SetFlagsToDefault(); - int argc = 7; - const char* argv[] = { "Test2", "-notesting-bool-flag", "notaflag", + int argc = 8; + const char* argv[] = { "Test2", "-notesting-bool-flag", + "--notesting-maybe-bool-flag", "notaflag", "--testing_int_flag=77", "-testing_float_flag=.25", "--testing_string_flag", "no way!" }; CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc, const_cast<char **>(argv), false)); - CHECK_EQ(7, argc); + CHECK_EQ(8, argc); CHECK(!FLAG_testing_bool_flag); + CHECK(FLAG_testing_maybe_bool_flag.has_value); + CHECK(!FLAG_testing_maybe_bool_flag.value); CHECK_EQ(77, FLAG_testing_int_flag); CHECK_EQ(.25, FLAG_testing_float_flag); CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "no way!")); @@ -73,10 +76,13 @@ TEST(Flags2b) { SetFlagsToDefault(); const char* str = " -notesting-bool-flag notaflag --testing_int_flag=77 " + "-notesting-maybe-bool-flag " "-testing_float_flag=.25 " "--testing_string_flag no_way! "; CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK(!FLAG_testing_bool_flag); + CHECK(FLAG_testing_maybe_bool_flag.has_value); + CHECK(!FLAG_testing_maybe_bool_flag.value); CHECK_EQ(77, FLAG_testing_int_flag); CHECK_EQ(.25, FLAG_testing_float_flag); CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "no_way!")); @@ -85,9 +91,9 @@ TEST(Flags2b) { TEST(Flags3) { SetFlagsToDefault(); - int argc = 8; + int argc = 9; const char* argv[] = - { "Test3", "--testing_bool_flag", "notaflag", + { "Test3", "--testing_bool_flag", "--testing-maybe-bool-flag", "notaflag", "--testing_int_flag", "-666", "--testing_float_flag", "-12E10", "-testing-string-flag=foo-bar" }; CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc, @@ -95,6 +101,8 @@ TEST(Flags3) { true)); CHECK_EQ(2, argc); CHECK(FLAG_testing_bool_flag); + CHECK(FLAG_testing_maybe_bool_flag.has_value); + CHECK(FLAG_testing_maybe_bool_flag.value); CHECK_EQ(-666, FLAG_testing_int_flag); CHECK_EQ(-12E10, FLAG_testing_float_flag); CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "foo-bar")); @@ -104,11 +112,14 @@ TEST(Flags3) { TEST(Flags3b) { SetFlagsToDefault(); const char* str = - "--testing_bool_flag notaflag --testing_int_flag -666 " + "--testing_bool_flag --testing-maybe-bool-flag notaflag " + "--testing_int_flag -666 " "--testing_float_flag -12E10 " "-testing-string-flag=foo-bar"; CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK(FLAG_testing_bool_flag); + CHECK(FLAG_testing_maybe_bool_flag.has_value); + CHECK(FLAG_testing_maybe_bool_flag.value); CHECK_EQ(-666, FLAG_testing_int_flag); CHECK_EQ(-12E10, FLAG_testing_float_flag); CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "foo-bar")); @@ -123,6 +134,7 @@ TEST(Flags4) { const_cast<char **>(argv), true)); CHECK_EQ(2, argc); + CHECK(!FLAG_testing_maybe_bool_flag.has_value); } @@ -130,6 +142,7 @@ TEST(Flags4b) { SetFlagsToDefault(); const char* str = "--testing_bool_flag --foo"; CHECK_EQ(2, FlagList::SetFlagsFromString(str, StrLength(str))); + CHECK(!FLAG_testing_maybe_bool_flag.has_value); } @@ -181,7 +194,7 @@ TEST(FlagsJSArguments1) { true)); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); - CHECK_EQ(2, FLAG_js_arguments.argc()); + CHECK_EQ(2, FLAG_js_arguments.argc); CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag")); CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7")); CHECK_EQ(1, argc); @@ -194,7 +207,7 @@ TEST(FlagsJSArguments1b) { CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); - CHECK_EQ(2, FLAG_js_arguments.argc()); + CHECK_EQ(2, FLAG_js_arguments.argc); CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag")); CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7")); } @@ -206,7 +219,7 @@ TEST(FlagsJSArguments2) { CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); - CHECK_EQ(2, FLAG_js_arguments.argc()); + CHECK_EQ(2, FLAG_js_arguments.argc); CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag")); CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7")); } @@ -218,7 +231,7 @@ TEST(FlagsJSArguments3) { CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); - CHECK_EQ(2, FLAG_js_arguments.argc()); + CHECK_EQ(2, FLAG_js_arguments.argc); CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag")); CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7")); } @@ -229,7 +242,7 @@ TEST(FlagsJSArguments4) { const char* str = "--testing-int-flag 42 --"; CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); - CHECK_EQ(0, FLAG_js_arguments.argc()); + CHECK_EQ(0, FLAG_js_arguments.argc); } diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc index a0c4b1e728..1a000afba2 100644 --- a/deps/v8/test/cctest/test-func-name-inference.cc +++ b/deps/v8/test/cctest/test-func-name-inference.cc @@ -51,7 +51,7 @@ using ::v8::internal::String; static void CheckFunctionName(v8::Handle<v8::Script> script, const char* func_pos_src, const char* ref_inferred_name) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); // Get script source. @@ -82,7 +82,7 @@ static void CheckFunctionName(v8::Handle<v8::Script> script, isolate->debug()->PrepareForBreakPoints(); Object* shared_func_info_ptr = isolate->debug()->FindSharedFunctionInfoInScript(i_script, func_pos); - CHECK(shared_func_info_ptr != HEAP->undefined_value()); + CHECK(shared_func_info_ptr != CcTest::heap()->undefined_value()); Handle<SharedFunctionInfo> shared_func_info( SharedFunctionInfo::cast(shared_func_info_ptr)); diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc index 1d33a8c86b..d0b80d1c8f 100644 --- a/deps/v8/test/cctest/test-global-handles.cc +++ b/deps/v8/test/cctest/test-global-handles.cc @@ -86,19 +86,19 @@ class TestObjectVisitor : public ObjectVisitor { TEST(IterateObjectGroupsOldApi) { CcTest::InitializeVM(); - GlobalHandles* global_handles = Isolate::Current()->global_handles(); - + GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); + Heap* heap = CcTest::heap(); v8::HandleScope handle_scope(CcTest::isolate()); Handle<Object> g1s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); TestRetainedObjectInfo info1; TestRetainedObjectInfo info2; @@ -181,19 +181,20 @@ TEST(IterateObjectGroupsOldApi) { TEST(IterateObjectGroups) { CcTest::InitializeVM(); - GlobalHandles* global_handles = Isolate::Current()->global_handles(); + GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); + Heap* heap = CcTest::heap(); v8::HandleScope handle_scope(CcTest::isolate()); Handle<Object> g1s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); TestRetainedObjectInfo info1; TestRetainedObjectInfo info2; @@ -275,24 +276,25 @@ TEST(IterateObjectGroups) { TEST(ImplicitReferences) { CcTest::InitializeVM(); - GlobalHandles* global_handles = Isolate::Current()->global_handles(); + GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); + Heap* heap = CcTest::heap(); v8::HandleScope handle_scope(CcTest::isolate()); Handle<Object> g1s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1c1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1c2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2c1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); global_handles->SetObjectGroupId(g1s1.location(), UniqueId(1)); global_handles->SetObjectGroupId(g2s1.location(), UniqueId(2)); @@ -319,7 +321,7 @@ TEST(ImplicitReferences) { TEST(EternalHandles) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); EternalHandles* eternal_handles = isolate->eternal_handles(); diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc index b124b2728d..5fe77c2adf 100644 --- a/deps/v8/test/cctest/test-global-object.cc +++ b/deps/v8/test/cctest/test-global-object.cc @@ -34,7 +34,7 @@ using namespace v8; // This test fails if properties on the prototype of the global object appear // as declared globals. TEST(StrictUndeclaredGlobalVariable) { - HandleScope scope(Isolate::GetCurrent()); + HandleScope scope(CcTest::isolate()); v8::Local<v8::String> var_name = v8_str("x"); LocalContext context; v8::TryCatch try_catch; diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc index 65362698ed..3ec844e9c7 100644 --- a/deps/v8/test/cctest/test-hashing.cc +++ b/deps/v8/test/cctest/test-hashing.cc @@ -151,7 +151,7 @@ void generate(MacroAssembler* masm, uint32_t key) { void check(i::Vector<const uint8_t> string) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); HandleScope scope(isolate); @@ -188,12 +188,12 @@ void check(i::Vector<const char> s) { void check(uint32_t key) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); HandleScope scope(isolate); v8::internal::byte buffer[2048]; - MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer); + MacroAssembler masm(CcTest::i_isolate(), buffer, sizeof buffer); generate(&masm, key); @@ -230,7 +230,7 @@ static uint32_t PseudoRandom(uint32_t i, uint32_t j) { TEST(StringHash) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(v8::Context::New(isolate)); @@ -251,7 +251,7 @@ TEST(StringHash) { TEST(NumberHash) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(v8::Context::New(isolate)); diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 0cf9cdaedf..db2243a3f0 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -31,6 +31,7 @@ #include "v8.h" +#include "allocation-tracker.h" #include "cctest.h" #include "hashmap.h" #include "heap-profiler.h" @@ -39,6 +40,12 @@ #include "utils-inl.h" #include "../include/v8-profiler.h" +using i::AllocationTraceNode; +using i::AllocationTraceTree; +using i::AllocationTracker; +using i::HashMap; +using i::Vector; + namespace { class NamedEntriesDetector { @@ -413,7 +420,7 @@ TEST(HeapSnapshotSlicedString) { TEST(HeapSnapshotConsString) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->SetInternalFieldCount(1); @@ -422,7 +429,7 @@ TEST(HeapSnapshotConsString) { v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); CHECK_EQ(1, global->InternalFieldCount()); - i::Factory* factory = i::Isolate::Current()->factory(); + i::Factory* factory = CcTest::i_isolate()->factory(); i::Handle<i::String> first = factory->NewStringFromAscii(i::CStrVector("0123456789")); i::Handle<i::String> second = @@ -456,7 +463,7 @@ TEST(HeapSnapshotConsString) { TEST(HeapSnapshotInternalReferences) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->SetInternalFieldCount(2); @@ -505,7 +512,7 @@ TEST(HeapSnapshotAddressReuse) { CompileRun( "for (var i = 0; i < 10000; ++i)\n" " a[i] = new A();\n"); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); const v8::HeapSnapshot* snapshot2 = heap_profiler->TakeHeapSnapshot(v8_str("snapshot2")); @@ -549,7 +556,7 @@ TEST(HeapEntryIdsAndArrayShift) { "for (var i = 0; i < 1; ++i)\n" " a.shift();\n"); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); const v8::HeapSnapshot* snapshot2 = heap_profiler->TakeHeapSnapshot(v8_str("s2")); @@ -594,7 +601,7 @@ TEST(HeapEntryIdsAndGC) { heap_profiler->TakeHeapSnapshot(s1_str); CHECK(ValidateSnapshot(snapshot1)); - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); const v8::HeapSnapshot* snapshot2 = heap_profiler->TakeHeapSnapshot(s2_str); @@ -901,7 +908,7 @@ TEST(HeapSnapshotObjectsStats) { // We have to call GC 6 times. In other case the garbage will be // the reason of flakiness. for (int i = 0; i < 6; ++i) { - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); } v8::SnapshotObjectId initial_id; @@ -1482,7 +1489,7 @@ TEST(NoHandleLeaks) { CompileRun("document = { URL:\"abcdefgh\" };"); v8::Handle<v8::String> name(v8_str("leakz")); - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); int count_before = i::HandleScope::NumberOfHandles(isolate); heap_profiler->TakeHeapSnapshot(name); int count_after = i::HandleScope::NumberOfHandles(isolate); @@ -1738,7 +1745,7 @@ bool HasWeakEdge(const v8::HeapGraphNode* node) { bool HasWeakGlobalHandle() { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(v8_str("weaks")); @@ -1800,7 +1807,7 @@ TEST(NoDebugObjectInSnapshot) { v8::HandleScope scope(env->GetIsolate()); v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); - v8::internal::Isolate::Current()->debug()->Load(); + CcTest::i_isolate()->debug()->Load(); CompileRun("foo = {};"); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); @@ -2005,3 +2012,168 @@ TEST(JSFunctionHasCodeLink) { GetProperty(foo_func, v8::HeapGraphEdge::kInternal, "code"); CHECK_NE(NULL, code); } + + + +class HeapProfilerExtension : public v8::Extension { + public: + static const char* kName; + HeapProfilerExtension() : v8::Extension(kName, kSource) { } + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name); + static void FindUntrackedObjects( + const v8::FunctionCallbackInfo<v8::Value>& args); + private: + static const char* kSource; +}; + +const char* HeapProfilerExtension::kName = "v8/heap-profiler"; + + +const char* HeapProfilerExtension::kSource = + "native function findUntrackedObjects();"; + + +v8::Handle<v8::FunctionTemplate> HeapProfilerExtension::GetNativeFunction( + v8::Handle<v8::String> name) { + if (name->Equals(v8::String::New("findUntrackedObjects"))) { + return v8::FunctionTemplate::New( + HeapProfilerExtension::FindUntrackedObjects); + } else { + CHECK(false); + return v8::Handle<v8::FunctionTemplate>(); + } +} + + +void HeapProfilerExtension::FindUntrackedObjects( + const v8::FunctionCallbackInfo<v8::Value>& args) { + i::HeapProfiler* heap_profiler = + reinterpret_cast<i::HeapProfiler*>(args.GetIsolate()->GetHeapProfiler()); + int untracked_objects = heap_profiler->FindUntrackedObjects(); + args.GetReturnValue().Set(untracked_objects); + CHECK_EQ(0, untracked_objects); +} + + +static HeapProfilerExtension kHeapProfilerExtension; +v8::DeclareExtension kHeapProfilerExtensionDeclaration( + &kHeapProfilerExtension); + + +// This is an example of using checking of JS allocations tracking in a test. +TEST(HeapObjectsTracker) { + const char* extensions[] = { HeapProfilerExtension::kName }; + v8::ExtensionConfiguration config(1, extensions); + LocalContext env(&config); + v8::HandleScope scope(env->GetIsolate()); + HeapObjectsTracker tracker; + CompileRun("var a = 1.2"); + CompileRun("var a = 1.2; var b = 1.0; var c = 1.0;"); + CompileRun( + "var a = [];\n" + "for (var i = 0; i < 5; ++i)\n" + " a[i] = i;\n" + "findUntrackedObjects();\n" + "for (var i = 0; i < 3; ++i)\n" + " a.shift();\n" + "findUntrackedObjects();\n"); +} + + +static const char* record_trace_tree_source = +"var topFunctions = [];\n" +"var global = this;\n" +"function generateFunctions(width, depth) {\n" +" var script = [];\n" +" for (var i = 0; i < width; i++) {\n" +" for (var j = 0; j < depth; j++) {\n" +" script.push('function f_' + i + '_' + j + '(x) {\\n');\n" +" script.push(' try {\\n');\n" +" if (j < depth-2) {\n" +" script.push(' return f_' + i + '_' + (j+1) + '(x+1);\\n');\n" +" } else if (j == depth - 2) {\n" +" script.push(' return new f_' + i + '_' + (depth - 1) + '();\\n');\n" +" } else if (j == depth - 1) {\n" +" script.push(' this.ts = Date.now();\\n');\n" +" }\n" +" script.push(' } catch (e) {}\\n');\n" +" script.push('}\\n');\n" +" \n" +" }\n" +" }\n" +" var script = script.join('');\n" +" // throw script;\n" +" global.eval(script);\n" +" for (var i = 0; i < width; i++) {\n" +" topFunctions.push(this['f_' + i + '_0']);\n" +" }\n" +"}\n" +"\n" +"var width = 3;\n" +"var depth = 3;\n" +"generateFunctions(width, depth);\n" +"var instances = [];\n" +"function start() {\n" +" for (var i = 0; i < width; i++) {\n" +" instances.push(topFunctions[i](0));\n" +" }\n" +"}\n" +"\n" +"for (var i = 0; i < 100; i++) start();\n"; + + +static i::HeapSnapshot* ToInternal(const v8::HeapSnapshot* snapshot) { + return const_cast<i::HeapSnapshot*>( + reinterpret_cast<const i::HeapSnapshot*>(snapshot)); +} + + +static AllocationTraceNode* FindNode( + AllocationTracker* tracker, const Vector<const char*>& names) { + AllocationTraceNode* node = tracker->trace_tree()->root(); + for (int i = 0; node != NULL && i < names.length(); i++) { + const char* name = names[i]; + Vector<AllocationTraceNode*> children = node->children(); + node = NULL; + for (int j = 0; j < children.length(); j++) { + v8::SnapshotObjectId id = children[j]->function_id(); + AllocationTracker::FunctionInfo* info = tracker->GetFunctionInfo(id); + if (info && strcmp(info->name, name) == 0) { + node = children[j]; + break; + } + } + } + return node; +} + + +TEST(TrackHeapAllocations) { + v8::HandleScope scope(v8::Isolate::GetCurrent()); + LocalContext env; + + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + heap_profiler->StartRecordingHeapAllocations(); + + CompileRun(record_trace_tree_source); + + const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( + v8::String::New("Test")); + i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection(); + AllocationTracker* tracker = collection->allocation_tracker(); + CHECK_NE(NULL, tracker); + // Resolve all function locations. + tracker->PrepareForSerialization(); + // Print for better diagnostics in case of failure. + tracker->trace_tree()->Print(tracker); + + const char* names[] = + { "(anonymous function)", "start", "f_0_0", "f_0_1", "f_0_2" }; + AllocationTraceNode* node = + FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); + CHECK_NE(NULL, node); + CHECK_GE(node->allocation_count(), 100); + CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); + heap_profiler->StopRecordingHeapAllocations(); +} diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc index 9d74011fde..74c2b75811 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/test-heap.cc @@ -42,8 +42,8 @@ using namespace v8::internal; // Go through all incremental marking steps in one swoop. static void SimulateIncrementalMarking() { - MarkCompactCollector* collector = HEAP->mark_compact_collector(); - IncrementalMarking* marking = HEAP->incremental_marking(); + MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector(); + IncrementalMarking* marking = CcTest::heap()->incremental_marking(); if (collector->IsConcurrentSweepingInProgress()) { collector->WaitUntilSweepingCompleted(); } @@ -62,9 +62,9 @@ static void SimulateIncrementalMarking() { static void CheckMap(Map* map, int type, int instance_size) { CHECK(map->IsHeapObject()); #ifdef DEBUG - CHECK(HEAP->Contains(map)); + CHECK(CcTest::heap()->Contains(map)); #endif - CHECK_EQ(HEAP->meta_map(), map->map()); + CHECK_EQ(CcTest::heap()->meta_map(), map->map()); CHECK_EQ(type, map->instance_type()); CHECK_EQ(instance_size, map->instance_size()); } @@ -72,10 +72,11 @@ static void CheckMap(Map* map, int type, int instance_size) { TEST(HeapMaps) { CcTest::InitializeVM(); - CheckMap(HEAP->meta_map(), MAP_TYPE, Map::kSize); - CheckMap(HEAP->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); - CheckMap(HEAP->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); - CheckMap(HEAP->string_map(), STRING_TYPE, kVariableSizeSentinel); + Heap* heap = CcTest::heap(); + CheckMap(heap->meta_map(), MAP_TYPE, Map::kSize); + CheckMap(heap->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); + CheckMap(heap->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); + CheckMap(heap->string_map(), STRING_TYPE, kVariableSizeSentinel); } @@ -99,7 +100,7 @@ static void CheckSmi(Isolate* isolate, int value, const char* string) { static void CheckNumber(Isolate* isolate, double value, const char* string) { - Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked(); + Object* obj = CcTest::heap()->NumberFromDouble(value)->ToObjectChecked(); CHECK(obj->IsNumber()); bool exc; Handle<Object> handle(obj, isolate); @@ -148,7 +149,7 @@ static void CheckFindCodeObject(Isolate* isolate) { TEST(HeapObjects) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Heap* heap = isolate->heap(); @@ -209,10 +210,9 @@ TEST(HeapObjects) { CHECK(s->IsString()); CHECK_EQ(10, s->length()); - String* object_string = String::cast(heap->Object_string()); - CHECK( - Isolate::Current()->context()->global_object()->HasLocalProperty( - object_string)); + Handle<String> object_string = Handle<String>::cast(factory->Object_string()); + Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object()); + CHECK(JSReceiver::HasLocalProperty(global, object_string)); // Check ToString for oddballs CheckOddball(isolate, heap->true_value(), "true"); @@ -250,7 +250,7 @@ TEST(Tagging) { TEST(GarbageCollection) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); Factory* factory = isolate->factory(); @@ -258,10 +258,13 @@ TEST(GarbageCollection) { // Check GC. heap->CollectGarbage(NEW_SPACE); + Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object()); Handle<String> name = factory->InternalizeUtf8String("theFunction"); Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); Handle<String> prop_namex = factory->InternalizeUtf8String("theSlotx"); Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); + Handle<Smi> twenty_three(Smi::FromInt(23), isolate); + Handle<Smi> twenty_four(Smi::FromInt(24), isolate); { HandleScope inner_scope(isolate); @@ -271,14 +274,11 @@ TEST(GarbageCollection) { Handle<Map> initial_map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); function->set_initial_map(*initial_map); - Isolate::Current()->context()->global_object()->SetProperty( - *name, *function, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(global, name, function, NONE, kNonStrictMode); // Allocate an object. Unrooted after leaving the scope. Handle<JSObject> obj = factory->NewJSObject(function); - obj->SetProperty( - *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetProperty( - *prop_namex, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); + JSReceiver::SetProperty(obj, prop_namex, twenty_four, NONE, kNonStrictMode); CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); @@ -287,10 +287,9 @@ TEST(GarbageCollection) { heap->CollectGarbage(NEW_SPACE); // Function should be alive. - CHECK(Isolate::Current()->context()->global_object()-> - HasLocalProperty(*name)); + CHECK(JSReceiver::HasLocalProperty(global, name)); // Check function is retained. - Object* func_value = Isolate::Current()->context()->global_object()-> + Object* func_value = CcTest::i_isolate()->context()->global_object()-> GetProperty(*name)->ToObjectChecked(); CHECK(func_value->IsJSFunction()); Handle<JSFunction> function(JSFunction::cast(func_value)); @@ -299,20 +298,17 @@ TEST(GarbageCollection) { HandleScope inner_scope(isolate); // Allocate another object, make it reachable from global. Handle<JSObject> obj = factory->NewJSObject(function); - Isolate::Current()->context()->global_object()->SetProperty( - *obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetProperty( - *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(global, obj_name, obj, NONE, kNonStrictMode); + JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); } // After gc, it should survive. heap->CollectGarbage(NEW_SPACE); - CHECK(Isolate::Current()->context()->global_object()-> - HasLocalProperty(*obj_name)); - CHECK(Isolate::Current()->context()->global_object()-> + CHECK(JSReceiver::HasLocalProperty(global, obj_name)); + CHECK(CcTest::i_isolate()->context()->global_object()-> GetProperty(*obj_name)->ToObjectChecked()->IsJSObject()); - Object* obj = Isolate::Current()->context()->global_object()-> + Object* obj = CcTest::i_isolate()->context()->global_object()-> GetProperty(*obj_name)->ToObjectChecked(); JSObject* js_obj = JSObject::cast(obj); CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name)); @@ -343,7 +339,7 @@ TEST(String) { TEST(LocalHandles) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); @@ -355,7 +351,7 @@ TEST(LocalHandles) { TEST(GlobalHandles) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); Factory* factory = isolate->factory(); GlobalHandles* global_handles = isolate->global_handles(); @@ -408,7 +404,7 @@ static void TestWeakGlobalHandleCallback(v8::Isolate* isolate, TEST(WeakGlobalHandlesScavenge) { i::FLAG_stress_compaction = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); Factory* factory = isolate->factory(); GlobalHandles* global_handles = isolate->global_handles(); @@ -449,7 +445,7 @@ TEST(WeakGlobalHandlesScavenge) { TEST(WeakGlobalHandlesMark) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); Factory* factory = isolate->factory(); GlobalHandles* global_handles = isolate->global_handles(); @@ -495,7 +491,7 @@ TEST(WeakGlobalHandlesMark) { TEST(DeleteWeakGlobalHandle) { i::FLAG_stress_compaction = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); Factory* factory = isolate->factory(); GlobalHandles* global_handles = isolate->global_handles(); @@ -594,12 +590,12 @@ static const char* not_so_random_string_table[] = { static void CheckInternalizedStrings(const char** strings) { for (const char* string = *strings; *strings != 0; string = *strings++) { Object* a; - MaybeObject* maybe_a = HEAP->InternalizeUtf8String(string); + MaybeObject* maybe_a = CcTest::heap()->InternalizeUtf8String(string); // InternalizeUtf8String may return a failure if a GC is needed. if (!maybe_a->ToObject(&a)) continue; CHECK(a->IsInternalizedString()); Object* b; - MaybeObject* maybe_b = HEAP->InternalizeUtf8String(string); + MaybeObject* maybe_b = CcTest::heap()->InternalizeUtf8String(string); if (!maybe_b->ToObject(&b)) continue; CHECK_EQ(b, a); CHECK(String::cast(b)->IsUtf8EqualTo(CStrVector(string))); @@ -617,7 +613,7 @@ TEST(StringTable) { TEST(FunctionAllocation) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope sc(CcTest::isolate()); @@ -628,26 +624,28 @@ TEST(FunctionAllocation) { factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); function->set_initial_map(*initial_map); + Handle<Smi> twenty_three(Smi::FromInt(23), isolate); + Handle<Smi> twenty_four(Smi::FromInt(24), isolate); + Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); Handle<JSObject> obj = factory->NewJSObject(function); - obj->SetProperty( - *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); // Check that we can add properties to function objects. - function->SetProperty( - *prop_name, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(function, prop_name, twenty_four, NONE, + kNonStrictMode); CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); } TEST(ObjectProperties) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope sc(CcTest::isolate()); - String* object_string = String::cast(HEAP->Object_string()); - Object* raw_object = Isolate::Current()->context()->global_object()-> + String* object_string = String::cast(CcTest::heap()->Object_string()); + Object* raw_object = CcTest::i_isolate()->context()->global_object()-> GetProperty(object_string)->ToObjectChecked(); JSFunction* object_function = JSFunction::cast(raw_object); Handle<JSFunction> constructor(object_function); @@ -655,69 +653,65 @@ TEST(ObjectProperties) { Handle<String> first = factory->InternalizeUtf8String("first"); Handle<String> second = factory->InternalizeUtf8String("second"); + Handle<Smi> one(Smi::FromInt(1), isolate); + Handle<Smi> two(Smi::FromInt(2), isolate); + // check for empty - CHECK(!obj->HasLocalProperty(*first)); + CHECK(!JSReceiver::HasLocalProperty(obj, first)); // add first - obj->SetProperty( - *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); - CHECK(obj->HasLocalProperty(*first)); + JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); + CHECK(JSReceiver::HasLocalProperty(obj, first)); // delete first JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); - CHECK(!obj->HasLocalProperty(*first)); + CHECK(!JSReceiver::HasLocalProperty(obj, first)); // add first and then second - obj->SetProperty( - *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetProperty( - *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); - CHECK(obj->HasLocalProperty(*first)); - CHECK(obj->HasLocalProperty(*second)); + JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); + JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); + CHECK(JSReceiver::HasLocalProperty(obj, first)); + CHECK(JSReceiver::HasLocalProperty(obj, second)); // delete first and then second JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); - CHECK(obj->HasLocalProperty(*second)); + CHECK(JSReceiver::HasLocalProperty(obj, second)); JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); - CHECK(!obj->HasLocalProperty(*first)); - CHECK(!obj->HasLocalProperty(*second)); + CHECK(!JSReceiver::HasLocalProperty(obj, first)); + CHECK(!JSReceiver::HasLocalProperty(obj, second)); // add first and then second - obj->SetProperty( - *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetProperty( - *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); - CHECK(obj->HasLocalProperty(*first)); - CHECK(obj->HasLocalProperty(*second)); + JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); + JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); + CHECK(JSReceiver::HasLocalProperty(obj, first)); + CHECK(JSReceiver::HasLocalProperty(obj, second)); // delete second and then first JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); - CHECK(obj->HasLocalProperty(*first)); + CHECK(JSReceiver::HasLocalProperty(obj, first)); JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); - CHECK(!obj->HasLocalProperty(*first)); - CHECK(!obj->HasLocalProperty(*second)); + CHECK(!JSReceiver::HasLocalProperty(obj, first)); + CHECK(!JSReceiver::HasLocalProperty(obj, second)); // check string and internalized string match const char* string1 = "fisk"; Handle<String> s1 = factory->NewStringFromAscii(CStrVector(string1)); - obj->SetProperty( - *s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(obj, s1, one, NONE, kNonStrictMode); Handle<String> s1_string = factory->InternalizeUtf8String(string1); - CHECK(obj->HasLocalProperty(*s1_string)); + CHECK(JSReceiver::HasLocalProperty(obj, s1_string)); // check internalized string and string match const char* string2 = "fugl"; Handle<String> s2_string = factory->InternalizeUtf8String(string2); - obj->SetProperty( - *s2_string, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(obj, s2_string, one, NONE, kNonStrictMode); Handle<String> s2 = factory->NewStringFromAscii(CStrVector(string2)); - CHECK(obj->HasLocalProperty(*s2)); + CHECK(JSReceiver::HasLocalProperty(obj, s2)); } TEST(JSObjectMaps) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope sc(CcTest::isolate()); @@ -732,8 +726,8 @@ TEST(JSObjectMaps) { Handle<JSObject> obj = factory->NewJSObject(function); // Set a propery - obj->SetProperty( - *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked(); + Handle<Smi> twenty_three(Smi::FromInt(23), isolate); + JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode); CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); // Check the map has changed @@ -743,12 +737,12 @@ TEST(JSObjectMaps) { TEST(JSArray) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope sc(CcTest::isolate()); Handle<String> name = factory->InternalizeUtf8String("Array"); - Object* raw_object = Isolate::Current()->context()->global_object()-> + Object* raw_object = CcTest::i_isolate()->context()->global_object()-> GetProperty(*name)->ToObjectChecked(); Handle<JSFunction> function = Handle<JSFunction>( JSFunction::cast(raw_object)); @@ -792,12 +786,12 @@ TEST(JSArray) { TEST(JSObjectCopy) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope sc(CcTest::isolate()); - String* object_string = String::cast(HEAP->Object_string()); - Object* raw_object = Isolate::Current()->context()->global_object()-> + String* object_string = String::cast(CcTest::heap()->Object_string()); + Object* raw_object = CcTest::i_isolate()->context()->global_object()-> GetProperty(object_string)->ToObjectChecked(); JSFunction* object_function = JSFunction::cast(raw_object); Handle<JSFunction> constructor(object_function); @@ -805,16 +799,17 @@ TEST(JSObjectCopy) { Handle<String> first = factory->InternalizeUtf8String("first"); Handle<String> second = factory->InternalizeUtf8String("second"); - obj->SetProperty( - *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetProperty( - *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); + Handle<Smi> one(Smi::FromInt(1), isolate); + Handle<Smi> two(Smi::FromInt(2), isolate); + + JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); + JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked(); obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); // Make the clone. - Handle<JSObject> clone = Copy(obj); + Handle<JSObject> clone = JSObject::Copy(obj); CHECK(!clone.is_identical_to(obj)); CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 0)); @@ -824,10 +819,8 @@ TEST(JSObjectCopy) { CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); // Flip the values. - clone->SetProperty( - *first, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked(); - clone->SetProperty( - *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty(clone, first, two, NONE, kNonStrictMode); + JSReceiver::SetProperty(clone, second, one, NONE, kNonStrictMode); clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked(); clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked(); @@ -842,7 +835,7 @@ TEST(JSObjectCopy) { TEST(StringAllocation) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 }; @@ -897,7 +890,7 @@ static int ObjectsFoundInHeap(Heap* heap, Handle<Object> objs[], int size) { TEST(Iteration) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); @@ -931,7 +924,7 @@ TEST(Iteration) { objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); CHECK_EQ(objs_count, next_objs_index); - CHECK_EQ(objs_count, ObjectsFoundInHeap(HEAP, objs, objs_count)); + CHECK_EQ(objs_count, ObjectsFoundInHeap(CcTest::heap(), objs, objs_count)); } @@ -959,11 +952,12 @@ static int LenFromSize(int size) { TEST(Regression39128) { // Test case for crbug.com/39128. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); // Increase the chance of 'bump-the-pointer' allocation in old space. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); v8::HandleScope scope(CcTest::isolate()); @@ -973,7 +967,7 @@ TEST(Regression39128) { // Step 1: prepare a map for the object. We add 1 inobject property to it. Handle<JSFunction> object_ctor( - Isolate::Current()->native_context()->object_function()); + CcTest::i_isolate()->native_context()->object_function()); CHECK(object_ctor->has_initial_map()); Handle<Map> object_map(object_ctor->initial_map()); // Create a map with single inobject property. @@ -989,12 +983,12 @@ TEST(Regression39128) { int allocation_amount = Min(FixedArray::kMaxSize, Page::kMaxNonCodeHeapObjectSize + kPointerSize); int allocation_len = LenFromSize(allocation_amount); - NewSpace* new_space = HEAP->new_space(); + NewSpace* new_space = heap->new_space(); Address* top_addr = new_space->allocation_top_address(); Address* limit_addr = new_space->allocation_limit_address(); while ((*limit_addr - *top_addr) > allocation_amount) { - CHECK(!HEAP->always_allocate()); - Object* array = HEAP->AllocateFixedArray(allocation_len)->ToObjectChecked(); + CHECK(!heap->always_allocate()); + Object* array = heap->AllocateFixedArray(allocation_len)->ToObjectChecked(); CHECK(!array->IsFailure()); CHECK(new_space->Contains(array)); } @@ -1004,12 +998,12 @@ TEST(Regression39128) { int fixed_array_len = LenFromSize(to_fill); CHECK(fixed_array_len < FixedArray::kMaxLength); - CHECK(!HEAP->always_allocate()); - Object* array = HEAP->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); + CHECK(!heap->always_allocate()); + Object* array = heap->AllocateFixedArray(fixed_array_len)->ToObjectChecked(); CHECK(!array->IsFailure()); CHECK(new_space->Contains(array)); - Object* object = HEAP->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); + Object* object = heap->AllocateJSObjectFromMap(*my_map)->ToObjectChecked(); CHECK(new_space->Contains(object)); JSObject* jsobject = JSObject::cast(object); CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); @@ -1021,15 +1015,15 @@ TEST(Regression39128) { // Step 4: clone jsobject, but force always allocate first to create a clone // in old pointer space. - Address old_pointer_space_top = HEAP->old_pointer_space()->top(); + Address old_pointer_space_top = heap->old_pointer_space()->top(); AlwaysAllocateScope aa_scope; - Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked(); + Object* clone_obj = heap->CopyJSObject(jsobject)->ToObjectChecked(); JSObject* clone = JSObject::cast(clone_obj); if (clone->address() != old_pointer_space_top) { // Alas, got allocated from free list, we cannot do checks. return; } - CHECK(HEAP->old_pointer_space()->Contains(clone->address())); + CHECK(heap->old_pointer_space()->Contains(clone->address())); } @@ -1037,8 +1031,9 @@ 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; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); const char* source = "function foo() {" @@ -1055,21 +1050,86 @@ TEST(TestCodeFlushing) { } // Check function is compiled. - Object* func_value = Isolate::Current()->context()->global_object()-> + Object* func_value = CcTest::i_isolate()->context()->global_object()-> GetProperty(*foo_name)->ToObjectChecked(); CHECK(func_value->IsJSFunction()); Handle<JSFunction> function(JSFunction::cast(func_value)); CHECK(function->shared()->is_compiled()); // The code will survive at least two GCs. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CHECK(function->shared()->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); + } + + // 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()); +} + + +TEST(TestCodeFlushingPreAged) { + // 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 = true; + CcTest::InitializeVM(); + Isolate* isolate = Isolate::Current(); + 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<String> foo_name = factory->InternalizeUtf8String("foo"); + + // Compile foo, but don't run it. + { v8::HandleScope scope(CcTest::isolate()); + CompileRun(source); + } + + // Check function is compiled. + Object* func_value = Isolate::Current()->context()->global_object()-> + GetProperty(*foo_name)->ToObjectChecked(); + CHECK(func_value->IsJSFunction()); + Handle<JSFunction> function(JSFunction::cast(func_value)); + CHECK(function->shared()->is_compiled()); + + // The code has been run so will survive at least one GC. + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CHECK(function->shared()->is_compiled()); + + // The code was only run once, so it should be pre-aged and collected on the + // next GC. + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CHECK(!function->shared()->is_compiled() || function->IsOptimized()); + + // Execute the function again twice, and ensure it is reset to the young age. + { v8::HandleScope scope(CcTest::isolate()); + CompileRun("foo();" + "foo();"); + } + + // The code will survive at least two GC now that it is young again. + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); CHECK(function->shared()->is_compiled()); // Simulate several GCs that use full marking. const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); } // foo should no longer be in the compilation cache @@ -1086,8 +1146,9 @@ TEST(TestCodeFlushingIncremental) { // If we do not flush code this test is invalid. if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; i::FLAG_allow_natives_syntax = true; + i::FLAG_optimize_for_size = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); const char* source = "function foo() {" @@ -1104,22 +1165,22 @@ TEST(TestCodeFlushingIncremental) { } // Check function is compiled. - Object* func_value = Isolate::Current()->context()->global_object()-> + Object* func_value = CcTest::i_isolate()->context()->global_object()-> GetProperty(*foo_name)->ToObjectChecked(); CHECK(func_value->IsJSFunction()); Handle<JSFunction> function(JSFunction::cast(func_value)); CHECK(function->shared()->is_compiled()); // The code will survive at least two GCs. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); CHECK(function->shared()->is_compiled()); // Simulate several GCs that use incremental marking. const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { SimulateIncrementalMarking(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); } CHECK(!function->shared()->is_compiled() || function->IsOptimized()); CHECK(!function->is_compiled() || function->IsOptimized()); @@ -1134,7 +1195,7 @@ TEST(TestCodeFlushingIncremental) { for (int i = 0; i < kAgingThreshold; i++) { SimulateIncrementalMarking(); if (!function->next_function_link()->IsUndefined()) break; - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); } // Force optimization while incremental marking is active and while @@ -1144,7 +1205,7 @@ TEST(TestCodeFlushingIncremental) { } // Simulate one final GC to make sure the candidate queue is sane. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK(function->shared()->is_compiled() || !function->IsOptimized()); CHECK(function->is_compiled() || !function->IsOptimized()); } @@ -1154,8 +1215,9 @@ TEST(TestCodeFlushingIncrementalScavenge) { // If we do not flush code this test is invalid. if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; i::FLAG_allow_natives_syntax = true; + i::FLAG_optimize_for_size = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); const char* source = "var foo = function() {" @@ -1172,7 +1234,7 @@ TEST(TestCodeFlushingIncrementalScavenge) { Handle<String> bar_name = factory->InternalizeUtf8String("bar"); // Perfrom one initial GC to enable code flushing. - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); // This compile will add the code to the compilation cache. { v8::HandleScope scope(CcTest::isolate()); @@ -1180,12 +1242,12 @@ TEST(TestCodeFlushingIncrementalScavenge) { } // Check functions are compiled. - Object* func_value = Isolate::Current()->context()->global_object()-> + Object* func_value = CcTest::i_isolate()->context()->global_object()-> GetProperty(*foo_name)->ToObjectChecked(); CHECK(func_value->IsJSFunction()); Handle<JSFunction> function(JSFunction::cast(func_value)); CHECK(function->shared()->is_compiled()); - Object* func_value2 = Isolate::Current()->context()->global_object()-> + Object* func_value2 = CcTest::i_isolate()->context()->global_object()-> GetProperty(*bar_name)->ToObjectChecked(); CHECK(func_value2->IsJSFunction()); Handle<JSFunction> function2(JSFunction::cast(func_value2)); @@ -1209,10 +1271,10 @@ TEST(TestCodeFlushingIncrementalScavenge) { // perform a scavenge while incremental marking is still running. SimulateIncrementalMarking(); *function2.location() = NULL; - HEAP->CollectGarbage(NEW_SPACE, "test scavenge while marking"); + CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking"); // Simulate one final GC to make sure the candidate queue is sane. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK(!function->shared()->is_compiled() || function->IsOptimized()); CHECK(!function->is_compiled() || function->IsOptimized()); } @@ -1222,8 +1284,9 @@ TEST(TestCodeFlushingIncrementalAbort) { // If we do not flush code this test is invalid. if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; i::FLAG_allow_natives_syntax = true; + i::FLAG_optimize_for_size = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Heap* heap = isolate->heap(); v8::HandleScope scope(CcTest::isolate()); @@ -1241,7 +1304,7 @@ TEST(TestCodeFlushingIncrementalAbort) { } // Check function is compiled. - Object* func_value = Isolate::Current()->context()->global_object()-> + Object* func_value = CcTest::i_isolate()->context()->global_object()-> GetProperty(*foo_name)->ToObjectChecked(); CHECK(func_value->IsJSFunction()); Handle<JSFunction> function(JSFunction::cast(func_value)); @@ -1287,7 +1350,7 @@ TEST(TestCodeFlushingIncrementalAbort) { // Count the number of native contexts in the weak list of native contexts. int CountNativeContexts() { int count = 0; - Object* object = HEAP->native_contexts_list(); + Object* object = CcTest::heap()->native_contexts_list(); while (!object->IsUndefined()) { count++; object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); @@ -1319,7 +1382,7 @@ TEST(TestInternalWeakLists) { static const int kNumTestContexts = 10; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); v8::Handle<v8::Context> ctx[kNumTestContexts]; @@ -1328,7 +1391,7 @@ TEST(TestInternalWeakLists) { // Create a number of global contests which gets linked together. for (int i = 0; i < kNumTestContexts; i++) { - ctx[i] = v8::Context::New(v8::Isolate::GetCurrent()); + ctx[i] = v8::Context::New(CcTest::isolate()); // Collect garbage that might have been created by one of the // installed extensions. @@ -1367,7 +1430,7 @@ TEST(TestInternalWeakLists) { // Scavenge treats these references as strong. for (int j = 0; j < 10; j++) { - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); } @@ -1379,41 +1442,41 @@ TEST(TestInternalWeakLists) { // Get rid of f3 and f5 in the same way. CompileRun("f3=null"); for (int j = 0; j < 10; j++) { - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); } - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); CompileRun("f5=null"); for (int j = 0; j < 10; j++) { - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); } - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); ctx[i]->Exit(); } // Force compilation cache cleanup. - HEAP->NotifyContextDisposed(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->NotifyContextDisposed(); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); // Dispose the native contexts one by one. for (int i = 0; i < kNumTestContexts; i++) { // TODO(dcarney): is there a better way to do this? i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); - *unsafe = HEAP->undefined_value(); + *unsafe = CcTest::heap()->undefined_value(); ctx[i].Clear(); // Scavenge treats these references as strong. for (int j = 0; j < 10; j++) { - HEAP->PerformScavenge(); + CcTest::heap()->PerformScavenge(); CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); } // Mark compact handles the weak references. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); } @@ -1462,7 +1525,7 @@ static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, TEST(TestInternalWeakListsTraverseWithGC) { v8::V8::Initialize(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); static const int kNumTestContexts = 10; @@ -1474,7 +1537,7 @@ TEST(TestInternalWeakListsTraverseWithGC) { // Create an number of contexts and check the length of the weak list both // with and without GCs while iterating the list. for (int i = 0; i < kNumTestContexts; i++) { - ctx[i] = v8::Context::New(v8::Isolate::GetCurrent()); + ctx[i] = v8::Context::New(CcTest::isolate()); CHECK_EQ(i + 1, CountNativeContexts()); CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); } @@ -1516,13 +1579,13 @@ TEST(TestSizeOfObjects) { // Get initial heap size after several full GCs, which will stabilize // the heap size and return with sweeping finished completely. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - CHECK(HEAP->old_pointer_space()->IsLazySweepingComplete()); - int initial_size = static_cast<int>(HEAP->SizeOfObjects()); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); + CHECK(CcTest::heap()->old_pointer_space()->IsLazySweepingComplete()); + int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects()); { // Allocate objects on several different old-space pages so that @@ -1530,33 +1593,33 @@ TEST(TestSizeOfObjects) { AlwaysAllocateScope always_allocate; int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); for (int i = 1; i <= 100; i++) { - HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); + CcTest::heap()->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); CHECK_EQ(initial_size + i * filler_size, - static_cast<int>(HEAP->SizeOfObjects())); + static_cast<int>(CcTest::heap()->SizeOfObjects())); } } // The heap size should go back to initial size after a full GC, even // though sweeping didn't finish yet. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); // Normally sweeping would not be complete here, but no guarantees. - CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); + CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); // Advancing the sweeper step-wise should not change the heap size. - while (!HEAP->old_pointer_space()->IsLazySweepingComplete()) { - HEAP->old_pointer_space()->AdvanceSweeper(KB); - CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); + while (!CcTest::heap()->old_pointer_space()->IsLazySweepingComplete()) { + CcTest::heap()->old_pointer_space()->AdvanceSweeper(KB); + CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); } } TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { CcTest::InitializeVM(); - HEAP->EnsureHeapIsIterable(); - intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); - HeapIterator iterator(HEAP); + CcTest::heap()->EnsureHeapIsIterable(); + intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects(); + HeapIterator iterator(CcTest::heap()); intptr_t size_of_objects_2 = 0; for (HeapObject* obj = iterator.next(); obj != NULL; @@ -1605,10 +1668,11 @@ static void FillUpNewSpace(NewSpace* new_space) { TEST(GrowAndShrinkNewSpace) { CcTest::InitializeVM(); - NewSpace* new_space = HEAP->new_space(); + Heap* heap = CcTest::heap(); + NewSpace* new_space = heap->new_space(); - if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() || - HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { + if (heap->ReservedSemiSpaceSize() == heap->InitialSemiSpaceSize() || + heap->MaxSemiSpaceSize() == heap->InitialSemiSpaceSize()) { // The max size cannot exceed the reserved size, since semispaces must be // always within the reserved space. We can't test new space growing and // shrinking if the reserved size is the same as the minimum (initial) size. @@ -1634,7 +1698,7 @@ TEST(GrowAndShrinkNewSpace) { CHECK(old_capacity == new_capacity); // Let the scavenger empty the new space. - HEAP->CollectGarbage(NEW_SPACE); + heap->CollectGarbage(NEW_SPACE); CHECK_LE(new_space->Size(), old_capacity); // Explicitly shrinking should halve the space capacity. @@ -1655,9 +1719,9 @@ TEST(GrowAndShrinkNewSpace) { TEST(CollectingAllAvailableGarbageShrinksNewSpace) { CcTest::InitializeVM(); - - if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize() || - HEAP->MaxSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { + Heap* heap = CcTest::heap(); + if (heap->ReservedSemiSpaceSize() == heap->InitialSemiSpaceSize() || + heap->MaxSemiSpaceSize() == heap->InitialSemiSpaceSize()) { // The max size cannot exceed the reserved size, since semispaces must be // always within the reserved space. We can't test new space growing and // shrinking if the reserved size is the same as the minimum (initial) size. @@ -1665,14 +1729,14 @@ TEST(CollectingAllAvailableGarbageShrinksNewSpace) { } v8::HandleScope scope(CcTest::isolate()); - NewSpace* new_space = HEAP->new_space(); + NewSpace* new_space = heap->new_space(); intptr_t old_capacity, new_capacity; old_capacity = new_space->Capacity(); new_space->Grow(); new_capacity = new_space->Capacity(); CHECK(2 * old_capacity == new_capacity); FillUpNewSpace(new_space); - HEAP->CollectAllAvailableGarbage(); + heap->CollectAllAvailableGarbage(); new_capacity = new_space->Capacity(); CHECK(old_capacity == new_capacity); } @@ -1680,7 +1744,7 @@ TEST(CollectingAllAvailableGarbageShrinksNewSpace) { static int NumberOfGlobalObjects() { int count = 0; - HeapIterator iterator(HEAP); + HeapIterator iterator(CcTest::heap()); for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsGlobalObject()) count++; } @@ -1692,7 +1756,7 @@ static int NumberOfGlobalObjects() { // optimized code. TEST(LeakNativeContextViaMap) { i::FLAG_allow_natives_syntax = true; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer_scope(isolate); v8::Persistent<v8::Context> ctx1p; v8::Persistent<v8::Context> ctx2p; @@ -1703,7 +1767,7 @@ TEST(LeakNativeContextViaMap) { v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(4, NumberOfGlobalObjects()); { @@ -1726,10 +1790,10 @@ TEST(LeakNativeContextViaMap) { ctx1p.Dispose(); v8::V8::ContextDisposedNotification(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); ctx2p.Dispose(); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } @@ -1738,7 +1802,7 @@ TEST(LeakNativeContextViaMap) { // optimized code. TEST(LeakNativeContextViaFunction) { i::FLAG_allow_natives_syntax = true; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer_scope(isolate); v8::Persistent<v8::Context> ctx1p; v8::Persistent<v8::Context> ctx2p; @@ -1749,7 +1813,7 @@ TEST(LeakNativeContextViaFunction) { v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(4, NumberOfGlobalObjects()); { @@ -1772,17 +1836,17 @@ TEST(LeakNativeContextViaFunction) { ctx1p.Dispose(); v8::V8::ContextDisposedNotification(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); ctx2p.Dispose(); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } TEST(LeakNativeContextViaMapKeyed) { i::FLAG_allow_natives_syntax = true; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer_scope(isolate); v8::Persistent<v8::Context> ctx1p; v8::Persistent<v8::Context> ctx2p; @@ -1793,7 +1857,7 @@ TEST(LeakNativeContextViaMapKeyed) { v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(4, NumberOfGlobalObjects()); { @@ -1816,17 +1880,17 @@ TEST(LeakNativeContextViaMapKeyed) { ctx1p.Dispose(); v8::V8::ContextDisposedNotification(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); ctx2p.Dispose(); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } TEST(LeakNativeContextViaMapProto) { i::FLAG_allow_natives_syntax = true; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer_scope(isolate); v8::Persistent<v8::Context> ctx1p; v8::Persistent<v8::Context> ctx2p; @@ -1837,7 +1901,7 @@ TEST(LeakNativeContextViaMapProto) { v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(4, NumberOfGlobalObjects()); { @@ -1864,10 +1928,10 @@ TEST(LeakNativeContextViaMapProto) { ctx1p.Dispose(); v8::V8::ContextDisposedNotification(); } - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); ctx2p.Dispose(); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } @@ -1879,12 +1943,12 @@ TEST(InstanceOfStubWriteBarrier) { #endif CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft()) return; + if (!CcTest::i_isolate()->use_crankshaft()) return; if (i::FLAG_force_marking_deque_overflows) return; - v8::HandleScope outer_scope(v8::Isolate::GetCurrent()); + v8::HandleScope outer_scope(CcTest::isolate()); { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CompileRun( "function foo () { }" "function mkbar () { return new (new Function(\"\")) (); }" @@ -1895,14 +1959,14 @@ TEST(InstanceOfStubWriteBarrier) { "f(new foo()); g();"); } - IncrementalMarking* marking = HEAP->incremental_marking(); + IncrementalMarking* marking = CcTest::heap()->incremental_marking(); marking->Abort(); marking->Start(); Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->IsOptimized()); @@ -1916,21 +1980,21 @@ TEST(InstanceOfStubWriteBarrier) { CHECK(marking->IsMarking()); { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); + v8::HandleScope scope(CcTest::isolate()); + v8::Handle<v8::Object> global = CcTest::global(); v8::Handle<v8::Function> g = v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); g->Call(global, 0, NULL); } - HEAP->incremental_marking()->set_should_hurry(true); - HEAP->CollectGarbage(OLD_POINTER_SPACE); + CcTest::heap()->incremental_marking()->set_should_hurry(true); + CcTest::heap()->CollectGarbage(OLD_POINTER_SPACE); } TEST(PrototypeTransitionClearing) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); @@ -1947,11 +2011,11 @@ TEST(PrototypeTransitionClearing) { Handle<JSObject> baseObject = v8::Utils::OpenHandle( *v8::Handle<v8::Object>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("base")))); + CcTest::global()->Get(v8_str("base")))); // Verify that only dead prototype transitions are cleared. CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions()); - HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); const int transitions = 10 - 3; CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions()); @@ -1967,7 +2031,7 @@ TEST(PrototypeTransitionClearing) { // Make sure next prototype is placed on an old-space evacuation candidate. Handle<JSObject> prototype; - PagedSpace* space = HEAP->old_pointer_space(); + PagedSpace* space = CcTest::heap()->old_pointer_space(); { AlwaysAllocateScope always_allocate; SimulateFullSpace(space); @@ -1983,7 +2047,7 @@ TEST(PrototypeTransitionClearing) { CHECK(space->LastPage()->Contains(prototype->address())); JSObject::SetPrototype(baseObject, prototype, false); CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK(Map::GetPrototypeTransition(map, prototype)->IsMap()); } @@ -1996,11 +2060,11 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { #endif CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft()) return; - v8::HandleScope outer_scope(v8::Isolate::GetCurrent()); + if (!CcTest::i_isolate()->use_crankshaft()) return; + v8::HandleScope outer_scope(CcTest::isolate()); { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); CompileRun( "function f () {" " var s = 0;" @@ -2014,14 +2078,14 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->IsOptimized()); - IncrementalMarking* marking = HEAP->incremental_marking(); + IncrementalMarking* marking = CcTest::heap()->incremental_marking(); marking->Abort(); marking->Start(); - // The following two calls will increment HEAP->global_ic_age(). + // The following two calls will increment CcTest::heap()->global_ic_age(). const int kLongIdlePauseInMs = 1000; v8::V8::ContextDisposedNotification(); v8::V8::IdleNotification(kLongIdlePauseInMs); @@ -2035,11 +2099,11 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { // guard interrupt. But here we didn't ask for that, and there is no // JS code running to trigger the interrupt, so we explicitly finalize // here. - HEAP->CollectAllGarbage(Heap::kNoGCFlags, + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags, "Test finalizing incremental mark-sweep"); } - CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); + CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); CHECK_EQ(0, f->shared()->opt_count()); CHECK_EQ(0, f->shared()->code()->profiler_ticks()); } @@ -2053,7 +2117,7 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { #endif CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft()) return; + if (!CcTest::i_isolate()->use_crankshaft()) return; v8::HandleScope outer_scope(CcTest::isolate()); { @@ -2071,18 +2135,18 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->IsOptimized()); - HEAP->incremental_marking()->Abort(); + CcTest::heap()->incremental_marking()->Abort(); - // The following two calls will increment HEAP->global_ic_age(). + // The following two calls will increment CcTest::heap()->global_ic_age(). // Since incremental marking is off, IdleNotification will do full GC. const int kLongIdlePauseInMs = 1000; v8::V8::ContextDisposedNotification(); v8::V8::IdleNotification(kLongIdlePauseInMs); - CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); + CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); CHECK_EQ(0, f->shared()->opt_count()); CHECK_EQ(0, f->shared()->code()->profiler_ticks()); } @@ -2092,11 +2156,11 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { TEST(OptimizedAllocationAlwaysInNewSpace) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - SimulateFullSpace(HEAP->new_space()); + SimulateFullSpace(CcTest::heap()->new_space()); AlwaysAllocateScope always_allocate; v8::Local<v8::Value> res = CompileRun( "function c(x) {" @@ -2114,17 +2178,17 @@ TEST(OptimizedAllocationAlwaysInNewSpace) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InNewSpace(*o)); + CHECK(CcTest::heap()->InNewSpace(*o)); } TEST(OptimizedPretenuringAllocationFolding) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function DataObject() {" @@ -2145,22 +2209,22 @@ TEST(OptimizedPretenuringAllocationFolding) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(0))); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(1))); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(2))); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(3))); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(4))); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(5))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(0))); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2))); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(3))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(4))); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(5))); } TEST(OptimizedPretenuringAllocationFoldingBlocks) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function DataObject() {" @@ -2181,22 +2245,22 @@ TEST(OptimizedPretenuringAllocationFoldingBlocks) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(0))); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(1))); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(2))); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(3))); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(4))); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(5))); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0))); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(1))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(2))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(3))); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(4))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(5))); } TEST(OptimizedPretenuringObjectArrayLiterals) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2210,18 +2274,18 @@ TEST(OptimizedPretenuringObjectArrayLiterals) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(o->elements())); - CHECK(HEAP->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldPointerSpace(o->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); } TEST(OptimizedPretenuringMixedInObjectProperties) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2235,24 +2299,24 @@ TEST(OptimizedPretenuringMixedInObjectProperties) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(*o)); - CHECK(HEAP->InOldPointerSpace(o->RawFastPropertyAt(0))); - CHECK(HEAP->InOldDataSpace(o->RawFastPropertyAt(1))); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(0))); + CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(1))); JSObject* inner_object = reinterpret_cast<JSObject*>(o->RawFastPropertyAt(0)); - CHECK(HEAP->InOldPointerSpace(inner_object)); - CHECK(HEAP->InOldDataSpace(inner_object->RawFastPropertyAt(0))); - CHECK(HEAP->InOldPointerSpace(inner_object->RawFastPropertyAt(1))); + CHECK(CcTest::heap()->InOldPointerSpace(inner_object)); + CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(0))); + CHECK(CcTest::heap()->InOldPointerSpace(inner_object->RawFastPropertyAt(1))); } TEST(OptimizedPretenuringDoubleArrayProperties) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2266,18 +2330,18 @@ TEST(OptimizedPretenuringDoubleArrayProperties) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(*o)); - CHECK(HEAP->InOldDataSpace(o->properties())); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldDataSpace(o->properties())); } TEST(OptimizedPretenuringdoubleArrayLiterals) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2291,18 +2355,18 @@ TEST(OptimizedPretenuringdoubleArrayLiterals) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldDataSpace(o->elements())); - CHECK(HEAP->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldDataSpace(o->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); } TEST(OptimizedPretenuringNestedMixedArrayLiterals) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2322,21 +2386,21 @@ TEST(OptimizedPretenuringNestedMixedArrayLiterals) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(*o)); - CHECK(HEAP->InOldPointerSpace(*int_array_handle)); - CHECK(HEAP->InOldPointerSpace(int_array_handle->elements())); - CHECK(HEAP->InOldPointerSpace(*double_array_handle)); - CHECK(HEAP->InOldDataSpace(double_array_handle->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle)); + CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle)); + CHECK(CcTest::heap()->InOldDataSpace(double_array_handle->elements())); } TEST(OptimizedPretenuringNestedObjectLiterals) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2356,21 +2420,21 @@ TEST(OptimizedPretenuringNestedObjectLiterals) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(*o)); - CHECK(HEAP->InOldPointerSpace(*int_array_handle_1)); - CHECK(HEAP->InOldPointerSpace(int_array_handle_1->elements())); - CHECK(HEAP->InOldPointerSpace(*int_array_handle_2)); - CHECK(HEAP->InOldPointerSpace(int_array_handle_2->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle_1)); + CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle_1->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*int_array_handle_2)); + CHECK(CcTest::heap()->InOldPointerSpace(int_array_handle_2->elements())); } TEST(OptimizedPretenuringNestedDoubleLiterals) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( "function f() {" @@ -2392,11 +2456,11 @@ TEST(OptimizedPretenuringNestedDoubleLiterals) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(*o)); - CHECK(HEAP->InOldPointerSpace(*double_array_handle_1)); - CHECK(HEAP->InOldDataSpace(double_array_handle_1->elements())); - CHECK(HEAP->InOldPointerSpace(*double_array_handle_2)); - CHECK(HEAP->InOldDataSpace(double_array_handle_2->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle_1)); + CHECK(CcTest::heap()->InOldDataSpace(double_array_handle_1->elements())); + CHECK(CcTest::heap()->InOldPointerSpace(*double_array_handle_2)); + CHECK(CcTest::heap()->InOldDataSpace(double_array_handle_2->elements())); } @@ -2404,7 +2468,7 @@ TEST(OptimizedPretenuringNestedDoubleLiterals) { TEST(OptimizedAllocationArrayLiterals) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); @@ -2423,7 +2487,7 @@ TEST(OptimizedAllocationArrayLiterals) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InNewSpace(o->elements())); + CHECK(CcTest::heap()->InNewSpace(o->elements())); } @@ -2431,10 +2495,10 @@ TEST(OptimizedPretenuringCallNew) { i::FLAG_allow_natives_syntax = true; i::FLAG_pretenuring_call_new = true; CcTest::InitializeVM(); - if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return; + if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - HEAP->SetNewSpaceHighPromotionModeActive(true); + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); AlwaysAllocateScope always_allocate; v8::Local<v8::Value> res = CompileRun( @@ -2448,7 +2512,7 @@ TEST(OptimizedPretenuringCallNew) { Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - CHECK(HEAP->InOldPointerSpace(*o)); + CHECK(CcTest::heap()->InOldPointerSpace(*o)); } @@ -2480,7 +2544,7 @@ TEST(Regress1465) { Handle<JSObject> root = v8::Utils::OpenHandle( *v8::Handle<v8::Object>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); + CcTest::global()->Get(v8_str("root")))); // Count number of live transitions before marking. int transitions_before = CountMapTransitions(root->map()); @@ -2488,7 +2552,7 @@ TEST(Regress1465) { CHECK_EQ(transitions_count, transitions_before); SimulateIncrementalMarking(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); // Count number of live transitions after marking. Note that one transition // is left, because 'o' still holds an instance of one transition target. @@ -2522,15 +2586,15 @@ TEST(Regress2143a) { "f(root);"); // This bug only triggers with aggressive IC clearing. - HEAP->AgeInlineCaches(); + CcTest::heap()->AgeInlineCaches(); // Explicitly request GC to perform final marking step and sweeping. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); Handle<JSObject> root = v8::Utils::OpenHandle( *v8::Handle<v8::Object>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); + CcTest::global()->Get(v8_str("root")))); // The root object should be in a sane state. CHECK(root->IsJSObject()); @@ -2566,15 +2630,15 @@ TEST(Regress2143b) { "%DeoptimizeFunction(f);"); // This bug only triggers with aggressive IC clearing. - HEAP->AgeInlineCaches(); + CcTest::heap()->AgeInlineCaches(); // Explicitly request GC to perform final marking step and sweeping. - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); Handle<JSObject> root = v8::Utils::OpenHandle( *v8::Handle<v8::Object>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); + CcTest::global()->Get(v8_str("root")))); // The root object should be in a sane state. CHECK(root->IsJSObject()); @@ -2588,13 +2652,14 @@ TEST(ReleaseOverReservedPages) { i::FLAG_crankshaft = false; i::FLAG_always_opt = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); v8::HandleScope scope(CcTest::isolate()); static const int number_of_test_pages = 20; // Prepare many pages with low live-bytes count. - PagedSpace* old_pointer_space = HEAP->old_pointer_space(); + PagedSpace* old_pointer_space = heap->old_pointer_space(); CHECK_EQ(1, old_pointer_space->CountTotalPages()); for (int i = 0; i < number_of_test_pages; i++) { AlwaysAllocateScope always_allocate; @@ -2605,14 +2670,14 @@ TEST(ReleaseOverReservedPages) { // Triggering one GC will cause a lot of garbage to be discovered but // even spread across all allocated pages. - HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation"); + heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation"); CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); // Triggering subsequent GCs should cause at least half of the pages // to be released to the OS after at most two cycles. - HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); + heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages()); - HEAP->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); + heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); CHECK_GE(number_of_test_pages + 1, old_pointer_space->CountTotalPages() * 2); // Triggering a last-resort GC should cause all pages to be released to the @@ -2622,7 +2687,7 @@ TEST(ReleaseOverReservedPages) { // first page should be small in order to reduce memory used when the VM // boots, but if the 20 small arrays don't fit on the first page then that's // an indication that it is too small. - HEAP->CollectAllAvailableGarbage("triggered really hard"); + heap->CollectAllAvailableGarbage("triggered really hard"); CHECK_EQ(1, old_pointer_space->CountTotalPages()); } @@ -2630,10 +2695,10 @@ TEST(ReleaseOverReservedPages) { TEST(Regress2237) { i::FLAG_stress_compaction = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); - Handle<String> slice(HEAP->empty_string()); + Handle<String> slice(CcTest::heap()->empty_string()); { // Generate a parent that lives in new-space. @@ -2641,20 +2706,20 @@ TEST(Regress2237) { const char* c = "This text is long enough to trigger sliced strings."; Handle<String> s = factory->NewStringFromAscii(CStrVector(c)); CHECK(s->IsSeqOneByteString()); - CHECK(HEAP->InNewSpace(*s)); + CHECK(CcTest::heap()->InNewSpace(*s)); // Generate a sliced string that is based on the above parent and // lives in old-space. - SimulateFullSpace(HEAP->new_space()); + SimulateFullSpace(CcTest::heap()->new_space()); AlwaysAllocateScope always_allocate; Handle<String> t = factory->NewProperSubString(s, 5, 35); CHECK(t->IsSlicedString()); - CHECK(!HEAP->InNewSpace(*t)); + CHECK(!CcTest::heap()->InNewSpace(*t)); *slice.location() = *t.location(); } CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); } @@ -2669,7 +2734,7 @@ TEST(PrintSharedFunctionInfo) { Handle<JSFunction> g = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("g")))); + CcTest::global()->Get(v8_str("g")))); DisallowHeapAllocation no_allocation; g->shared()->PrintLn(); @@ -2683,7 +2748,7 @@ TEST(Regress2211) { v8::Handle<v8::String> value = v8_str("val string"); Smi* hash = Smi::FromInt(321); - Heap* heap = Isolate::Current()->heap(); + Heap* heap = CcTest::heap(); for (int i = 0; i < 2; i++) { // Store identity hash first and common hidden property second. @@ -2732,13 +2797,13 @@ TEST(IncrementalMarkingClearsTypeFeedbackCells) { // Prepare function f that contains type feedback for closures // originating from two different native contexts. - v8::Context::GetCurrent()->Global()->Set(v8_str("fun1"), fun1); - v8::Context::GetCurrent()->Global()->Set(v8_str("fun2"), fun2); + CcTest::global()->Set(v8_str("fun1"), fun1); + CcTest::global()->Set(v8_str("fun2"), fun2); CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( f->shared()->code()->type_feedback_info())->type_feedback_cells()); @@ -2747,7 +2812,7 @@ TEST(IncrementalMarkingClearsTypeFeedbackCells) { CHECK(cells->GetCell(1)->value()->IsJSFunction()); SimulateIncrementalMarking(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK_EQ(2, cells->CellCount()); CHECK(cells->GetCell(0)->value()->IsTheHole()); @@ -2783,13 +2848,13 @@ TEST(IncrementalMarkingPreservesMonomorhpicIC) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); CHECK(ic_before->ic_state() == MONOMORPHIC); SimulateIncrementalMarking(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); CHECK(ic_after->ic_state() == MONOMORPHIC); @@ -2810,12 +2875,12 @@ TEST(IncrementalMarkingClearsMonomorhpicIC) { // Prepare function f that contains a monomorphic IC for object // originating from a different native context. - v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); + CcTest::global()->Set(v8_str("obj1"), obj1); CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); CHECK(ic_before->ic_state() == MONOMORPHIC); @@ -2823,10 +2888,10 @@ TEST(IncrementalMarkingClearsMonomorhpicIC) { // Fire context dispose notification. v8::V8::ContextDisposedNotification(); SimulateIncrementalMarking(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); - CHECK(ic_after->ic_state() == UNINITIALIZED); + CHECK(IC::IsCleared(ic_after)); } @@ -2850,13 +2915,13 @@ TEST(IncrementalMarkingClearsPolymorhpicIC) { // Prepare function f that contains a polymorphic IC for objects // originating from two different native contexts. - v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); - v8::Context::GetCurrent()->Global()->Set(v8_str("obj2"), obj2); + CcTest::global()->Set(v8_str("obj1"), obj1); + CcTest::global()->Set(v8_str("obj2"), obj2); CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); CHECK(ic_before->ic_state() == POLYMORPHIC); @@ -2864,10 +2929,10 @@ TEST(IncrementalMarkingClearsPolymorhpicIC) { // Fire context dispose notification. v8::V8::ContextDisposedNotification(); SimulateIncrementalMarking(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); - CHECK(ic_after->ic_state() == UNINITIALIZED); + CHECK(IC::IsCleared(ic_after)); } @@ -2900,21 +2965,20 @@ void ReleaseStackTraceDataTest(const char* source, const char* accessor) { // resource's callback is fired when the external string is GC'ed. FLAG_use_ic = false; // ICs retain objects. FLAG_concurrent_recompilation = false; - CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); SourceResource* resource = new SourceResource(i::StrDup(source)); { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::String> source_string = v8::String::NewExternal(resource); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); v8::Script::Compile(source_string)->Run(); CHECK(!resource->IsDisposed()); } - // HEAP->CollectAllAvailableGarbage(); + // CcTest::heap()->CollectAllAvailableGarbage(); CHECK(!resource->IsDisposed()); CompileRun(accessor); - HEAP->CollectAllAvailableGarbage(); + CcTest::heap()->CollectAllAvailableGarbage(); // External source has been released. CHECK(resource->IsDisposed()); @@ -2923,6 +2987,7 @@ void ReleaseStackTraceDataTest(const char* source, const char* accessor) { TEST(ReleaseStackTraceData) { + CcTest::InitializeVM(); static const char* source1 = "var error = null; " /* Normal Error */ "try { " " throw new Error(); " @@ -2968,7 +3033,7 @@ TEST(ReleaseStackTraceData) { TEST(Regression144230) { i::FLAG_stress_compaction = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); @@ -3009,9 +3074,10 @@ TEST(Regression144230) { // visited later, causing the CallIC to be cleared. Handle<String> name = isolate->factory()->InternalizeUtf8String("call"); Handle<GlobalObject> global(isolate->context()->global_object()); + Handle<Smi> zero(Smi::FromInt(0), isolate); MaybeObject* maybe_call = global->GetProperty(*name); JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked()); - USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode)); + JSReceiver::SetProperty(global, name, zero, NONE, kNonStrictMode); isolate->compilation_cache()->Clear(); call->shared()->set_ic_age(heap->global_ic_age() + 1); Handle<Object> call_code(call->code(), isolate); @@ -3022,7 +3088,7 @@ TEST(Regression144230) { // Either heap verification caught the problem already or we go kaboom once // the CallIC is executed the next time. - USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); + JSReceiver::SetProperty(global, name, call_function, NONE, kNonStrictMode); CompileRun("call();"); } @@ -3031,7 +3097,7 @@ TEST(Regress159140) { i::FLAG_allow_natives_syntax = true; i::FLAG_flush_code_incrementally = true; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); @@ -3060,14 +3126,14 @@ TEST(Regress159140) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->is_compiled()); CompileRun("f = null;"); Handle<JSFunction> g = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("g")))); + CcTest::global()->Get(v8_str("g")))); CHECK(g->is_compiled()); const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { @@ -3093,7 +3159,7 @@ TEST(Regress165495) { i::FLAG_allow_natives_syntax = true; i::FLAG_flush_code_incrementally = true; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); @@ -3115,7 +3181,7 @@ TEST(Regress165495) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->is_compiled()); const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { @@ -3142,7 +3208,7 @@ TEST(Regress169209) { i::FLAG_flush_code_incrementally = true; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); @@ -3163,7 +3229,7 @@ TEST(Regress169209) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->is_compiled()); const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { @@ -3184,7 +3250,7 @@ TEST(Regress169209) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("flushMe")))); + CcTest::global()->Get(v8_str("flushMe")))); CHECK(f->is_compiled()); const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { @@ -3228,7 +3294,7 @@ TEST(Regress169928) { i::FLAG_allow_natives_syntax = true; i::FLAG_crankshaft = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); v8::HandleScope scope(CcTest::isolate()); @@ -3254,17 +3320,17 @@ TEST(Regress169928) { v8_str("fastliteralcase(mote, 2.5);"); v8::Local<v8::String> array_name = v8_str("mote"); - v8::Context::GetCurrent()->Global()->Set(array_name, v8::Int32::New(0)); + CcTest::global()->Set(array_name, v8::Int32::New(0)); // First make sure we flip spaces - HEAP->CollectGarbage(NEW_SPACE); + CcTest::heap()->CollectGarbage(NEW_SPACE); // Allocate the object. Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); array_data->set(0, Smi::FromInt(1)); array_data->set(1, Smi::FromInt(2)); - AllocateAllButNBytes(HEAP->new_space(), + AllocateAllButNBytes(CcTest::heap()->new_space(), JSArray::kSize + AllocationMemento::kSize + kPointerSize); @@ -3277,18 +3343,18 @@ TEST(Regress169928) { // We need filler the size of AllocationMemento object, plus an extra // fill pointer value. - MaybeObject* maybe_object = HEAP->AllocateRaw( + MaybeObject* maybe_object = CcTest::heap()->AllocateRaw( AllocationMemento::kSize + kPointerSize, NEW_SPACE, OLD_POINTER_SPACE); Object* obj = NULL; CHECK(maybe_object->ToObject(&obj)); Address addr_obj = reinterpret_cast<Address>( reinterpret_cast<byte*>(obj - kHeapObjectTag)); - HEAP->CreateFillerObjectAt(addr_obj, + CcTest::heap()->CreateFillerObjectAt(addr_obj, AllocationMemento::kSize + kPointerSize); // Give the array a name, making sure not to allocate strings. v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); - v8::Context::GetCurrent()->Global()->Set(array_name, array_obj); + CcTest::global()->Set(array_name, array_obj); // This should crash with a protection violation if we are running a build // with the bug. @@ -3303,7 +3369,7 @@ TEST(Regress168801) { i::FLAG_allow_natives_syntax = true; i::FLAG_flush_code_incrementally = true; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); @@ -3326,7 +3392,7 @@ TEST(Regress168801) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->is_compiled()); const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { @@ -3359,7 +3425,7 @@ TEST(Regress173458) { i::FLAG_allow_natives_syntax = true; i::FLAG_flush_code_incrementally = true; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); HandleScope scope(isolate); @@ -3382,7 +3448,7 @@ TEST(Regress173458) { Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( - v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); + CcTest::global()->Get(v8_str("f")))); CHECK(f->is_compiled()); const int kAgingThreshold = 6; for (int i = 0; i < kAgingThreshold; i++) { @@ -3416,7 +3482,7 @@ class DummyVisitor : public ObjectVisitor { TEST(DeferredHandles) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate)); v8::ImplementationUtilities::HandleScopeData* data = @@ -3444,7 +3510,7 @@ TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { " for (var i = 0; i < n; i += 100) a[i] = i;" "};" "f(10 * 1024 * 1024);"); - IncrementalMarking* marking = HEAP->incremental_marking(); + IncrementalMarking* marking = CcTest::heap()->incremental_marking(); if (marking->IsStopped()) marking->Start(); // This big step should be sufficient to mark the whole array. marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc index d02f4f46e8..65a001d4b3 100644 --- a/deps/v8/test/cctest/test-liveedit.cc +++ b/deps/v8/test/cctest/test-liveedit.cc @@ -97,7 +97,7 @@ void CompareStringsOneWay(const char* s1, const char* s2, int expected_diff_parameter = -1) { StringCompareInput input(s1, s2); - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); DiffChunkStruct* first_chunk; ListDiffOutputWriter writer(&first_chunk, &zone); diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index a143d583fd..1094512276 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -183,7 +183,7 @@ class IsolateLockingThreadWithLocalContext : public JoinableThread { v8::Locker locker(isolate_); v8::Isolate::Scope isolate_scope(isolate_); v8::HandleScope handle_scope(isolate_); - LocalContext local_context; + LocalContext local_context(isolate_); CHECK_EQ(isolate_, v8::internal::Isolate::Current()); CalcFibAndCheck(); } @@ -267,7 +267,7 @@ class IsolateNestedLockingThread : public JoinableThread { v8::Locker lock(isolate_); v8::Isolate::Scope isolate_scope(isolate_); v8::HandleScope handle_scope(isolate_); - LocalContext local_context; + LocalContext local_context(isolate_); { v8::Locker another_lock(isolate_); CalcFibAndCheck(); @@ -311,7 +311,7 @@ class SeparateIsolatesLocksNonexclusiveThread : public JoinableThread { v8::Locker lock(isolate1_); v8::Isolate::Scope isolate_scope(isolate1_); v8::HandleScope handle_scope(isolate1_); - LocalContext local_context; + LocalContext local_context(isolate1_); IsolateLockingThreadWithLocalContext threadB(isolate2_); threadB.Start(); @@ -545,7 +545,7 @@ class LockUnlockLockThread : public JoinableThread { virtual void Run() { v8::Locker lock1(isolate_); CHECK(v8::Locker::IsLocked(isolate_)); - CHECK(!v8::Locker::IsLocked(CcTest::default_isolate())); + CHECK(!v8::Locker::IsLocked(CcTest::isolate())); { v8::Isolate::Scope isolate_scope(isolate_); v8::HandleScope handle_scope(isolate_); @@ -557,13 +557,13 @@ class LockUnlockLockThread : public JoinableThread { { v8::Unlocker unlock1(isolate_); CHECK(!v8::Locker::IsLocked(isolate_)); - CHECK(!v8::Locker::IsLocked(CcTest::default_isolate())); + CHECK(!v8::Locker::IsLocked(CcTest::isolate())); { v8::Locker lock2(isolate_); v8::Isolate::Scope isolate_scope(isolate_); v8::HandleScope handle_scope(isolate_); CHECK(v8::Locker::IsLocked(isolate_)); - CHECK(!v8::Locker::IsLocked(CcTest::default_isolate())); + CHECK(!v8::Locker::IsLocked(CcTest::isolate())); v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); @@ -605,24 +605,26 @@ class LockUnlockLockDefaultIsolateThread : public JoinableThread { public: explicit LockUnlockLockDefaultIsolateThread(v8::Handle<v8::Context> context) : JoinableThread("LockUnlockLockDefaultIsolateThread"), - context_(CcTest::default_isolate(), context) {} + context_(CcTest::isolate(), context) {} virtual void Run() { - v8::Locker lock1(CcTest::default_isolate()); + v8::Locker lock1(CcTest::isolate()); { - v8::HandleScope handle_scope(CcTest::default_isolate()); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::Local<v8::Context> context = - v8::Local<v8::Context>::New(CcTest::default_isolate(), context_); + v8::Local<v8::Context>::New(CcTest::isolate(), context_); v8::Context::Scope context_scope(context); CalcFibAndCheck(); } { - v8::Unlocker unlock1(CcTest::default_isolate()); + v8::Unlocker unlock1(CcTest::isolate()); { - v8::Locker lock2(CcTest::default_isolate()); - v8::HandleScope handle_scope(CcTest::default_isolate()); + v8::Locker lock2(CcTest::isolate()); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); + v8::HandleScope handle_scope(CcTest::isolate()); v8::Local<v8::Context> context = - v8::Local<v8::Context>::New(CcTest::default_isolate(), context_); + v8::Local<v8::Context>::New(CcTest::isolate(), context_); v8::Context::Scope context_scope(context); CalcFibAndCheck(); } @@ -644,9 +646,10 @@ TEST(LockUnlockLockDefaultIsolateMultithreaded) { Local<v8::Context> context; i::List<JoinableThread*> threads(kNThreads); { - v8::Locker locker_(CcTest::default_isolate()); - v8::HandleScope handle_scope(CcTest::default_isolate()); - context = v8::Context::New(CcTest::default_isolate()); + v8::Locker locker_(CcTest::isolate()); + v8::Isolate::Scope isolate_scope(CcTest::isolate()); + v8::HandleScope handle_scope(CcTest::isolate()); + context = v8::Context::New(CcTest::isolate()); for (int i = 0; i < kNThreads; i++) { threads.Add(new LockUnlockLockDefaultIsolateThread(context)); } diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc index 09df19e2fc..4a0717d09d 100644 --- a/deps/v8/test/cctest/test-log-stack-tracer.cc +++ b/deps/v8/test/cctest/test-log-stack-tracer.cc @@ -72,7 +72,7 @@ static void DoTrace(Address fp) { // sp is only used to define stack high bound regs.sp = reinterpret_cast<Address>(trace_env.sample) - 10240; - trace_env.sample->Init(Isolate::Current(), regs); + trace_env.sample->Init(CcTest::i_isolate(), regs); } @@ -80,11 +80,11 @@ static void DoTrace(Address fp) { // pure JS code is being executed static void DoTraceHideCEntryFPAddress(Address fp) { v8::internal::Address saved_c_frame_fp = - *(Isolate::Current()->c_entry_fp_address()); + *(CcTest::i_isolate()->c_entry_fp_address()); CHECK(saved_c_frame_fp); - *(Isolate::Current()->c_entry_fp_address()) = 0; + *(CcTest::i_isolate()->c_entry_fp_address()) = 0; DoTrace(fp); - *(Isolate::Current()->c_entry_fp_address()) = saved_c_frame_fp; + *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp; } @@ -156,8 +156,8 @@ void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) { static Address GetJsEntrySp() { - CHECK_NE(NULL, i::Isolate::Current()->thread_local_top()); - return i::Isolate::Current()->js_entry_sp(); + CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top()); + return CcTest::i_isolate()->js_entry_sp(); } @@ -187,8 +187,10 @@ static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) { } -static bool IsAddressWithinFuncCode(const char* func_name, Address addr) { - v8::Local<v8::Value> func = CcTest::env()->Global()->Get(v8_str(func_name)); +static bool IsAddressWithinFuncCode(v8::Local<v8::Context> context, + const char* func_name, + Address addr) { + v8::Local<v8::Value> func = context->Global()->Get(v8_str(func_name)); CHECK(func->IsFunction()); JSFunction* js_func = JSFunction::cast(*v8::Utils::OpenHandle(*func)); return IsAddressWithinFuncCode(js_func, addr); @@ -225,19 +227,21 @@ static void construct_call(const v8::FunctionCallbackInfo<v8::Value>& args) { // Use the API to create a JSFunction object that calls the above C++ function. -void CreateFramePointerGrabberConstructor(const char* constructor_name) { +void CreateFramePointerGrabberConstructor(v8::Local<v8::Context> context, + const char* constructor_name) { Local<v8::FunctionTemplate> constructor_template = v8::FunctionTemplate::New(construct_call); constructor_template->SetClassName(v8_str("FPGrabber")); Local<Function> fun = constructor_template->GetFunction(); - CcTest::env()->Global()->Set(v8_str(constructor_name), fun); + context->Global()->Set(v8_str(constructor_name), fun); } // Creates a global function named 'func_name' that calls the tracing // function 'trace_func_name' with an actual EBP register value, // encoded as one or two Smis. -static void CreateTraceCallerFunction(const char* func_name, +static void CreateTraceCallerFunction(v8::Local<v8::Context> context, + const char* func_name, const char* trace_func_name) { i::EmbeddedVector<char, 256> trace_call_buf; i::OS::SNPrintF(trace_call_buf, @@ -249,7 +253,7 @@ static void CreateTraceCallerFunction(const char* func_name, // Create the FPGrabber function, which grabs the caller's frame pointer // when called as a constructor. - CreateFramePointerGrabberConstructor("FPGrabber"); + CreateFramePointerGrabberConstructor(context, "FPGrabber"); // Compile the script. CompileRun(trace_call_buf.start()); @@ -267,11 +271,13 @@ TEST(CFromJSStackTrace) { TickSample sample; InitTraceEnv(&sample); - CcTest::InitializeVM(TRACE_EXTENSION); v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); + v8::Context::Scope context_scope(context); + // Create global function JSFuncDoTrace which calls // extension function trace() with the current frame pointer value. - CreateTraceCallerFunction("JSFuncDoTrace", "trace"); + CreateTraceCallerFunction(context, "JSFuncDoTrace", "trace"); Local<Value> result = CompileRun( "function JSTrace() {" " JSFuncDoTrace();" @@ -294,8 +300,9 @@ TEST(CFromJSStackTrace) { int base = 0; CHECK_GT(sample.frames_count, base + 1); - CHECK(IsAddressWithinFuncCode("JSFuncDoTrace", sample.stack[base + 0])); - CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 1])); + CHECK(IsAddressWithinFuncCode( + context, "JSFuncDoTrace", sample.stack[base + 0])); + CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 1])); } @@ -312,11 +319,13 @@ TEST(PureJSStackTrace) { TickSample sample; InitTraceEnv(&sample); - CcTest::InitializeVM(TRACE_EXTENSION); v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); + v8::Context::Scope context_scope(context); + // Create global function JSFuncDoTrace which calls // extension function js_trace() with the current frame pointer value. - CreateTraceCallerFunction("JSFuncDoTrace", "js_trace"); + CreateTraceCallerFunction(context, "JSFuncDoTrace", "js_trace"); Local<Value> result = CompileRun( "function JSTrace() {" " JSFuncDoTrace();" @@ -343,8 +352,9 @@ TEST(PureJSStackTrace) { // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" int base = 0; CHECK_GT(sample.frames_count, base + 1); - CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 0])); - CHECK(IsAddressWithinFuncCode("OuterJSTrace", sample.stack[base + 1])); + CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 0])); + CHECK(IsAddressWithinFuncCode( + context, "OuterJSTrace", sample.stack[base + 1])); } @@ -379,15 +389,18 @@ static int CFunc(int depth) { TEST(PureCStackTrace) { TickSample sample; InitTraceEnv(&sample); - CcTest::InitializeVM(TRACE_EXTENSION); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); + v8::Context::Scope context_scope(context); // Check that sampler doesn't crash CHECK_EQ(10, CFunc(10)); } TEST(JsEntrySp) { - CcTest::InitializeVM(TRACE_EXTENSION); v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); + v8::Context::Scope context_scope(context); CHECK_EQ(0, GetJsEntrySp()); CompileRun("a = 1; b = a + 1;"); CHECK_EQ(0, GetJsEntrySp()); diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc index f752c36ccb..2cf2a77445 100644 --- a/deps/v8/test/cctest/test-log.cc +++ b/deps/v8/test/cctest/test-log.cc @@ -60,9 +60,9 @@ class ScopedLoggerInitializer { temp_file_(NULL), // Need to run this prior to creating the scope. trick_to_run_init_flags_(init_flags_()), - scope_(v8::Isolate::GetCurrent()), - env_(v8::Context::New(v8::Isolate::GetCurrent())), - logger_(i::Isolate::Current()->logger()) { + scope_(CcTest::isolate()), + env_(v8::Context::New(CcTest::isolate())), + logger_(CcTest::i_isolate()->logger()) { env_->Enter(); } @@ -91,6 +91,7 @@ class ScopedLoggerInitializer { i::FLAG_log = true; i::FLAG_prof = true; i::FLAG_logfile = i::Log::kLogToTemporaryFile; + i::FLAG_logfile_per_isolate = false; return false; } @@ -169,8 +170,8 @@ class LoopingJsThread : public LoopingThread { : LoopingThread(isolate) { } void RunLoop() { v8::Locker locker; - CHECK(i::Isolate::Current() != NULL); - CHECK_GT(i::Isolate::Current()->thread_manager()->CurrentId(), 0); + CHECK(CcTest::i_isolate() != NULL); + CHECK_GT(CcTest::i_isolate()->thread_manager()->CurrentId(), 0); SetV8ThreadId(); while (IsRunning()) { v8::HandleScope scope; @@ -197,8 +198,8 @@ class LoopingNonJsThread : public LoopingThread { v8::Locker locker; v8::Unlocker unlocker; // Now thread has V8's id, but will not run VM code. - CHECK(i::Isolate::Current() != NULL); - CHECK_GT(i::Isolate::Current()->thread_manager()->CurrentId(), 0); + CHECK(CcTest::i_isolate() != NULL); + CHECK_GT(CcTest::i_isolate()->thread_manager()->CurrentId(), 0); double i = 10; SignalRunning(); while (IsRunning()) { @@ -243,14 +244,14 @@ TEST(ProfMultipleThreads) { TestSampler* sampler = NULL; { v8::Locker locker; - sampler = new TestSampler(v8::internal::Isolate::Current()); + sampler = new TestSampler(CcTest::i_isolate()); sampler->Start(); CHECK(sampler->IsActive()); } - LoopingJsThread jsThread(v8::internal::Isolate::Current()); + LoopingJsThread jsThread(CcTest::i_isolate()); jsThread.Start(); - LoopingNonJsThread nonJsThread(v8::internal::Isolate::Current()); + LoopingNonJsThread nonJsThread(CcTest::i_isolate()); nonJsThread.Start(); CHECK(!sampler->WasSampleStackCalled()); @@ -299,8 +300,8 @@ class SimpleExternalString : public v8::String::ExternalStringResource { } // namespace TEST(Issue23768) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Handle<v8::Context> env = v8::Context::New(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); + v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate()); env->Enter(); SimpleExternalString source_ext_str("(function ext() {})();"); @@ -317,7 +318,7 @@ TEST(Issue23768) { i_source->set_resource(NULL); // Must not crash. - i::Isolate::Current()->logger()->LogCompiledFunctions(); + CcTest::i_isolate()->logger()->LogCompiledFunctions(); } @@ -330,7 +331,7 @@ TEST(LogCallbacks) { Logger* logger = initialize_logger.logger(); v8::Local<v8::FunctionTemplate> obj = - v8::Local<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), + v8::Local<v8::FunctionTemplate>::New(CcTest::isolate(), v8::FunctionTemplate::New()); obj->SetClassName(v8_str("Obj")); v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate(); @@ -379,7 +380,7 @@ TEST(LogAccessorCallbacks) { Logger* logger = initialize_logger.logger(); v8::Local<v8::FunctionTemplate> obj = - v8::Local<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), + v8::Local<v8::FunctionTemplate>::New(CcTest::isolate(), v8::FunctionTemplate::New()); obj->SetClassName(v8_str("Obj")); v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate(); @@ -439,7 +440,7 @@ TEST(EquivalenceOfLoggingAndTraversal) { " (function a(j) { return function b() { return j; } })(100);\n" "})(this);"); logger->StopProfiler(); - HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); + CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); logger->StringEvent("test-logging-done", ""); // Iterate heap to find compiled functions, will write to log. diff --git a/deps/v8/test/cctest/test-macro-assembler-arm.cc b/deps/v8/test/cctest/test-macro-assembler-arm.cc new file mode 100644 index 0000000000..77f7abbd44 --- /dev/null +++ b/deps/v8/test/cctest/test-macro-assembler-arm.cc @@ -0,0 +1,136 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> + +#include "v8.h" +#include "macro-assembler.h" +#include "arm/macro-assembler-arm.h" +#include "arm/simulator-arm.h" +#include "cctest.h" + + +using namespace v8::internal; + +typedef void* (*F)(int x, int y, int p2, int p3, int p4); + +#define __ masm-> + + +static byte to_non_zero(int n) { + return static_cast<unsigned>(n) % 255 + 1; +} + + +static bool all_zeroes(const byte* beg, const byte* end) { + CHECK(beg); + CHECK(beg <= end); + while (beg < end) { + if (*beg++ != 0) + return false; + } + return true; +} + + +TEST(CopyBytes) { + CcTest::InitializeVM(); + Isolate* isolate = Isolate::Current(); + HandleScope handles(isolate); + + const int data_size = 1 * KB; + size_t act_size; + + // Allocate two blocks to copy data between. + byte* src_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0)); + CHECK(src_buffer); + CHECK(act_size >= static_cast<size_t>(data_size)); + byte* dest_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0)); + CHECK(dest_buffer); + CHECK(act_size >= static_cast<size_t>(data_size)); + + // Storage for R0 and R1. + byte* r0_; + byte* r1_; + + MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler* masm = &assembler; + + // Code to be generated: The stuff in CopyBytes followed by a store of R0 and + // R1, respectively. + __ CopyBytes(r0, r1, r2, r3); + __ mov(r2, Operand(reinterpret_cast<int>(&r0_))); + __ mov(r3, Operand(reinterpret_cast<int>(&r1_))); + __ str(r0, MemOperand(r2)); + __ str(r1, MemOperand(r3)); + __ bx(lr); + + CodeDesc desc; + masm->GetCode(&desc); + Object* code = isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked(); + CHECK(code->IsCode()); + + F f = FUNCTION_CAST<F>(Code::cast(code)->entry()); + + // Initialise source data with non-zero bytes. + for (int i = 0; i < data_size; i++) { + src_buffer[i] = to_non_zero(i); + } + + const int fuzz = 11; + + for (int size = 0; size < 600; size++) { + for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) { + for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { + memset(dest_buffer, 0, data_size); + CHECK(dest + size < dest_buffer + data_size); + (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src), + reinterpret_cast<int>(dest), size, 0, 0); + // R0 and R1 should point at the first byte after the copied data. + CHECK_EQ(src + size, r0_); + CHECK_EQ(dest + size, r1_); + // Check that we haven't written outside the target area. + CHECK(all_zeroes(dest_buffer, dest)); + CHECK(all_zeroes(dest + size, dest_buffer + data_size)); + // Check the target area. + CHECK_EQ(0, memcmp(src, dest, size)); + } + } + } + + // Check that the source data hasn't been clobbered. + for (int i = 0; i < data_size; i++) { + CHECK(src_buffer[i] == to_non_zero(i)); + } +} + + + +#undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-mips.cc b/deps/v8/test/cctest/test-macro-assembler-mips.cc new file mode 100644 index 0000000000..b200949679 --- /dev/null +++ b/deps/v8/test/cctest/test-macro-assembler-mips.cc @@ -0,0 +1,136 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> + +#include "v8.h" +#include "macro-assembler.h" +#include "mips/macro-assembler-mips.h" +#include "mips/simulator-mips.h" +#include "cctest.h" + + +using namespace v8::internal; + +typedef void* (*F)(int x, int y, int p2, int p3, int p4); + +#define __ masm-> + + +static byte to_non_zero(int n) { + return static_cast<unsigned>(n) % 255 + 1; +} + + +static bool all_zeroes(const byte* beg, const byte* end) { + CHECK(beg); + CHECK(beg <= end); + while (beg < end) { + if (*beg++ != 0) + return false; + } + return true; +} + + +TEST(CopyBytes) { + CcTest::InitializeVM(); + Isolate* isolate = Isolate::Current(); + HandleScope handles(isolate); + + const int data_size = 1 * KB; + size_t act_size; + + // Allocate two blocks to copy data between. + byte* src_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0)); + CHECK(src_buffer); + CHECK(act_size >= static_cast<size_t>(data_size)); + byte* dest_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0)); + CHECK(dest_buffer); + CHECK(act_size >= static_cast<size_t>(data_size)); + + // Storage for a0 and a1. + byte* a0_; + byte* a1_; + + MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler* masm = &assembler; + + // Code to be generated: The stuff in CopyBytes followed by a store of a0 and + // a1, respectively. + __ CopyBytes(a0, a1, a2, a3); + __ li(a2, Operand(reinterpret_cast<int>(&a0_))); + __ li(a3, Operand(reinterpret_cast<int>(&a1_))); + __ sw(a0, MemOperand(a2)); + __ jr(ra); + __ sw(a1, MemOperand(a3)); + + CodeDesc desc; + masm->GetCode(&desc); + Object* code = isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked(); + CHECK(code->IsCode()); + + ::F f = FUNCTION_CAST< ::F>(Code::cast(code)->entry()); + + // Initialise source data with non-zero bytes. + for (int i = 0; i < data_size; i++) { + src_buffer[i] = to_non_zero(i); + } + + const int fuzz = 11; + + for (int size = 0; size < 600; size++) { + for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) { + for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { + memset(dest_buffer, 0, data_size); + CHECK(dest + size < dest_buffer + data_size); + (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src), + reinterpret_cast<int>(dest), size, 0, 0); + // a0 and a1 should point at the first byte after the copied data. + CHECK_EQ(src + size, a0_); + CHECK_EQ(dest + size, a1_); + // Check that we haven't written outside the target area. + CHECK(all_zeroes(dest_buffer, dest)); + CHECK(all_zeroes(dest + size, dest_buffer + data_size)); + // Check the target area. + CHECK_EQ(0, memcmp(src, dest, size)); + } + } + } + + // Check that the source data hasn't been clobbered. + for (int i = 0; i < data_size; i++) { + CHECK(src_buffer[i] == to_non_zero(i)); + } +} + + + +#undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index a2070a5ea8..61914b58c3 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -47,6 +47,7 @@ using v8::internal::MacroAssembler; using v8::internal::OS; using v8::internal::Operand; using v8::internal::RelocInfo; +using v8::internal::Representation; using v8::internal::Smi; using v8::internal::SmiIndex; using v8::internal::byte; @@ -141,8 +142,8 @@ TEST(Smi) { static void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) { __ movl(rax, Immediate(id)); - __ Move(rcx, Smi::FromInt(0)); - __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(0))); + __ Move(rcx, value); + __ Set(rdx, reinterpret_cast<intptr_t>(value)); __ cmpq(rcx, rdx); __ j(not_equal, exit); } @@ -157,7 +158,7 @@ TEST(SmiMove) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. @@ -246,7 +247,7 @@ TEST(SmiCompare) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -297,7 +298,7 @@ TEST(Integer32ToSmi) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -426,7 +427,7 @@ TEST(Integer64PlusConstantToSmi) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -471,7 +472,7 @@ TEST(SmiCheck) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -720,7 +721,7 @@ TEST(SmiNeg) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -751,8 +752,6 @@ TEST(SmiNeg) { } - - static void SmiAddTest(MacroAssembler* masm, Label* exit, int id, @@ -802,15 +801,122 @@ static void SmiAddTest(MacroAssembler* masm, } +static void SmiAddOverflowTest(MacroAssembler* masm, + Label* exit, + int id, + int x) { + // Adds a Smi to x so that the addition overflows. + ASSERT(x != 0); // Can't overflow by adding a Smi. + int y_max = (x > 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue - x - 1); + int y_min = (x > 0) ? (Smi::kMaxValue - x + 1) : (Smi::kMinValue + 0); + + __ movl(rax, Immediate(id)); + __ Move(rcx, Smi::FromInt(x)); + __ movq(r11, rcx); // Store original Smi value of x in r11. + __ Move(rdx, Smi::FromInt(y_min)); + { + Label overflow_ok; + __ SmiAdd(r9, rcx, rdx, &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + { + Label overflow_ok; + __ incq(rax); + __ SmiAdd(rcx, rcx, rdx, &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + __ movq(rcx, r11); + { + Label overflow_ok; + __ incq(rax); + __ SmiAddConstant(r9, rcx, Smi::FromInt(y_min), &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + { + Label overflow_ok; + __ incq(rax); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_min), &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + __ Move(rdx, Smi::FromInt(y_max)); + + { + Label overflow_ok; + __ incq(rax); + __ SmiAdd(r9, rcx, rdx, &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + { + Label overflow_ok; + __ incq(rax); + __ SmiAdd(rcx, rcx, rdx, &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + __ movq(rcx, r11); + { + Label overflow_ok; + __ incq(rax); + __ SmiAddConstant(r9, rcx, Smi::FromInt(y_max), &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } + + { + Label overflow_ok; + __ incq(rax); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_max), &overflow_ok); + __ jmp(exit); + __ bind(&overflow_ok); + __ incq(rax); + __ cmpq(rcx, r11); + __ j(not_equal, exit); + } +} + + TEST(SmiAdd) { v8::internal::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; - byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, - &actual_size, - true)); + byte* buffer = + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, + &actual_size, + true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -829,6 +935,14 @@ TEST(SmiAdd) { SmiAddTest(masm, &exit, 0x70, Smi::kMaxValue, -5); SmiAddTest(masm, &exit, 0x80, Smi::kMaxValue, Smi::kMinValue); + SmiAddOverflowTest(masm, &exit, 0x90, -1); + SmiAddOverflowTest(masm, &exit, 0xA0, 1); + SmiAddOverflowTest(masm, &exit, 0xB0, 1024); + SmiAddOverflowTest(masm, &exit, 0xC0, Smi::kMaxValue); + SmiAddOverflowTest(masm, &exit, 0xD0, -2); + SmiAddOverflowTest(masm, &exit, 0xE0, -42000); + SmiAddOverflowTest(masm, &exit, 0xF0, Smi::kMinValue); + __ xor_(rax, rax); // Success. __ bind(&exit); ExitCode(masm); @@ -886,6 +1000,7 @@ static void SmiSubTest(MacroAssembler* masm, __ j(not_equal, exit); } + static void SmiSubOverflowTest(MacroAssembler* masm, Label* exit, int id, @@ -1001,7 +1116,7 @@ TEST(SmiSub) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1092,7 +1207,7 @@ TEST(SmiMul) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1199,7 +1314,7 @@ TEST(SmiDiv) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1310,7 +1425,7 @@ TEST(SmiMod) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1408,7 +1523,7 @@ TEST(SmiIndex) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1478,7 +1593,7 @@ TEST(SmiSelectNonSmi) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1558,7 +1673,7 @@ TEST(SmiAnd) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1640,7 +1755,7 @@ TEST(SmiOr) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1724,7 +1839,7 @@ TEST(SmiXor) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1792,7 +1907,7 @@ TEST(SmiNot) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1889,7 +2004,7 @@ TEST(SmiShiftLeft) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -1996,7 +2111,7 @@ TEST(SmiShiftLogicalRight) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -2066,7 +2181,7 @@ TEST(SmiShiftArithmeticRight) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -2131,7 +2246,7 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -2175,7 +2290,7 @@ TEST(OperandOffset) { &actual_size, true)); CHECK(buffer); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); @@ -2520,5 +2635,114 @@ TEST(OperandOffset) { } +TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Isolate* isolate = CcTest::i_isolate(); + HandleScope handles(isolate); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. + masm->set_allow_stub_calls(false); + EntryCode(masm); + __ subq(rsp, Immediate(1 * kPointerSize)); + Label exit; + + // Test 1. + __ movq(rax, Immediate(1)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Byte()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(255)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Byte()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 2. + __ movq(rax, Immediate(2)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ Set(rcx, V8_2PART_UINT64_C(0xdeadbeaf, 12345678)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Smi()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ Set(rdx, V8_2PART_UINT64_C(0xdeadbeaf, 12345678)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Smi()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 3. + __ movq(rax, Immediate(3)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer32()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(-1)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer32()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 4. + __ movq(rax, Immediate(4)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movl(rcx, Immediate(0x44332211)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::HeapObject()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(0x44332211)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::HeapObject()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 5. + __ movq(rax, Immediate(5)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ Set(rcx, V8_2PART_UINT64_C(0x12345678, deadbeaf)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Tagged()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ Set(rdx, V8_2PART_UINT64_C(0x12345678, deadbeaf)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Tagged()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 6. + __ movq(rax, Immediate(6)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ Set(rcx, V8_2PART_UINT64_C(0x11223344, 55667788)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::External()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ Set(rdx, V8_2PART_UINT64_C(0x11223344, 55667788)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::External()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + __ xor_(rax, rax); // Success. + __ bind(&exit); + __ addq(rsp, Immediate(1 * kPointerSize)); + ExitCode(masm); + __ ret(0); + + CodeDesc desc; + masm->GetCode(&desc); + // Call the function from C++. + int result = FUNCTION_CAST<F0>(buffer)(); + CHECK_EQ(0, result); +} + #undef __ diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc index 33d9230e01..e62bdeb074 100644 --- a/deps/v8/test/cctest/test-mark-compact.cc +++ b/deps/v8/test/cctest/test-mark-compact.cc @@ -73,86 +73,63 @@ TEST(MarkingDeque) { TEST(Promotion) { - // This test requires compaction. If compaction is turned off, we - // skip the entire test. - if (FLAG_never_compact) return; - - // Ensure that we get a compacting collection so that objects are promoted - // from new space. - FLAG_gc_global = true; - FLAG_always_compact = true; - HEAP->ConfigureHeap(2*256*KB, 8*MB, 8*MB); - CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + heap->ConfigureHeap(2*256*KB, 1*MB, 1*MB); v8::HandleScope sc(CcTest::isolate()); // Allocate a fixed array in the new space. - int array_size = + int array_length = (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) / - (kPointerSize * 4); - Object* obj = HEAP->AllocateFixedArray(array_size)->ToObjectChecked(); - + (4 * kPointerSize); + Object* obj = heap->AllocateFixedArray(array_length)->ToObjectChecked(); Handle<FixedArray> array(FixedArray::cast(obj)); // Array should be in the new space. - CHECK(HEAP->InSpace(*array, NEW_SPACE)); + CHECK(heap->InSpace(*array, NEW_SPACE)); - // Call the m-c collector, so array becomes an old object. - HEAP->CollectGarbage(OLD_POINTER_SPACE); + // Call mark compact GC, so array becomes an old object. + heap->CollectGarbage(OLD_POINTER_SPACE); // Array now sits in the old space - CHECK(HEAP->InSpace(*array, OLD_POINTER_SPACE)); + CHECK(heap->InSpace(*array, OLD_POINTER_SPACE)); } TEST(NoPromotion) { - HEAP->ConfigureHeap(2*256*KB, 8*MB, 8*MB); - - // Test the situation that some objects in new space are promoted to - // the old space CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + heap->ConfigureHeap(2*256*KB, 1*MB, 1*MB); v8::HandleScope sc(CcTest::isolate()); - // Do a mark compact GC to shrink the heap. - HEAP->CollectGarbage(OLD_POINTER_SPACE); - - // Allocate a big Fixed array in the new space. - int length = (Page::kMaxNonCodeHeapObjectSize - - FixedArray::kHeaderSize) / (2 * kPointerSize); - Object* obj = i::Isolate::Current()->heap()->AllocateFixedArray(length)-> - ToObjectChecked(); - + // Allocate a big fixed array in the new space. + int array_length = + (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) / + (2 * kPointerSize); + Object* obj = heap->AllocateFixedArray(array_length)->ToObjectChecked(); Handle<FixedArray> array(FixedArray::cast(obj)); - // Array still stays in the new space. - CHECK(HEAP->InSpace(*array, NEW_SPACE)); - - // Allocate objects in the old space until out of memory. - FixedArray* host = *array; - while (true) { - Object* obj; - { MaybeObject* maybe_obj = HEAP->AllocateFixedArray(100, TENURED); - if (!maybe_obj->ToObject(&obj)) break; - } + // Array should be in the new space. + CHECK(heap->InSpace(*array, NEW_SPACE)); - host->set(0, obj); - host = FixedArray::cast(obj); - } + // Simulate a full old space to make promotion fail. + SimulateFullSpace(heap->old_pointer_space()); // Call mark compact GC, and it should pass. - HEAP->CollectGarbage(OLD_POINTER_SPACE); + heap->CollectGarbage(OLD_POINTER_SPACE); } TEST(MarkCompactCollector) { FLAG_incremental_marking = false; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); v8::HandleScope sc(CcTest::isolate()); + Handle<GlobalObject> global(isolate->context()->global_object()); // call mark-compact when heap is empty heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 1"); @@ -191,8 +168,8 @@ TEST(MarkCompactCollector) { Map::cast(heap->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)->ToObjectChecked()); function->set_initial_map(initial_map); - isolate->context()->global_object()->SetProperty( - func_name, function, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty( + global, handle(func_name), handle(function), NONE, kNonStrictMode); JSObject* obj = JSObject::cast( heap->AllocateJSObject(function)->ToObjectChecked()); @@ -200,7 +177,7 @@ TEST(MarkCompactCollector) { func_name = String::cast( heap->InternalizeUtf8String("theFunction")->ToObjectChecked()); - CHECK(isolate->context()->global_object()->HasLocalProperty(func_name)); + CHECK(JSReceiver::HasLocalProperty(global, handle(func_name))); Object* func_value = isolate->context()->global_object()-> GetProperty(func_name)->ToObjectChecked(); CHECK(func_value->IsJSFunction()); @@ -209,20 +186,19 @@ TEST(MarkCompactCollector) { obj = JSObject::cast(heap->AllocateJSObject(function)->ToObjectChecked()); String* obj_name = String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked()); - isolate->context()->global_object()->SetProperty( - obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetProperty( + global, handle(obj_name), handle(obj), NONE, kNonStrictMode); String* prop_name = String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked()); - obj->SetProperty(prop_name, - Smi::FromInt(23), - NONE, - kNonStrictMode)->ToObjectChecked(); + Handle<Smi> twenty_three(Smi::FromInt(23), isolate); + JSReceiver::SetProperty( + handle(obj), handle(prop_name), twenty_three, NONE, kNonStrictMode); heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 5"); obj_name = String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked()); - CHECK(isolate->context()->global_object()->HasLocalProperty(obj_name)); + CHECK(JSReceiver::HasLocalProperty(global, handle(obj_name))); CHECK(isolate->context()->global_object()-> GetProperty(obj_name)->ToObjectChecked()->IsJSObject()); obj = JSObject::cast(isolate->context()->global_object()-> @@ -243,7 +219,7 @@ static Handle<Map> CreateMap(Isolate* isolate) { TEST(MapCompact) { FLAG_max_map_space_pages = 16; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); { @@ -255,51 +231,18 @@ TEST(MapCompact) { Handle<Map> map = CreateMap(); map->set_prototype(*root); root = factory->NewJSObjectFromMap(map); - } while (HEAP->map_space()->MapPointersEncodable()); + } while (CcTest::heap()->map_space()->MapPointersEncodable()); } // Now, as we don't have any handles to just allocated maps, we should // be able to trigger map compaction. // To give an additional chance to fail, try to force compaction which // should be impossible right now. - HEAP->CollectAllGarbage(Heap::kForceCompactionMask); + CcTest::heap()->CollectAllGarbage(Heap::kForceCompactionMask); // And now map pointers should be encodable again. - CHECK(HEAP->map_space()->MapPointersEncodable()); + CHECK(CcTest::heap()->map_space()->MapPointersEncodable()); } #endif -static int gc_starts = 0; -static int gc_ends = 0; - -static void GCPrologueCallbackFunc() { - CHECK(gc_starts == gc_ends); - gc_starts++; -} - - -static void GCEpilogueCallbackFunc() { - CHECK(gc_starts == gc_ends + 1); - gc_ends++; -} - - -TEST(GCCallback) { - i::FLAG_stress_compaction = false; - CcTest::InitializeVM(); - - HEAP->SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc); - HEAP->SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc); - - // Scavenge does not call GC callback functions. - HEAP->PerformScavenge(); - - CHECK_EQ(0, gc_starts); - CHECK_EQ(gc_ends, gc_starts); - - HEAP->CollectGarbage(OLD_POINTER_SPACE); - CHECK_EQ(1, gc_starts); - CHECK_EQ(gc_ends, gc_starts); -} - static int NumberOfWeakCalls = 0; static void WeakPointerCallback(v8::Isolate* isolate, @@ -314,17 +257,17 @@ static void WeakPointerCallback(v8::Isolate* isolate, TEST(ObjectGroups) { FLAG_incremental_marking = false; CcTest::InitializeVM(); - GlobalHandles* global_handles = Isolate::Current()->global_handles(); - + GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); + Heap* heap = CcTest::heap(); NumberOfWeakCalls = 0; v8::HandleScope handle_scope(CcTest::isolate()); Handle<Object> g1s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1c1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); global_handles->MakeWeak(g1s1.location(), reinterpret_cast<void*>(1234), &WeakPointerCallback); @@ -336,11 +279,11 @@ TEST(ObjectGroups) { &WeakPointerCallback); Handle<Object> g2s1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2s2 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2c1 = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); global_handles->MakeWeak(g2s1.location(), reinterpret_cast<void*>(1234), &WeakPointerCallback); @@ -370,7 +313,7 @@ TEST(ObjectGroups) { Handle<HeapObject>::cast(g2s1).location(), g2_children, 1); } // Do a full GC - HEAP->CollectGarbage(OLD_POINTER_SPACE); + heap->CollectGarbage(OLD_POINTER_SPACE); // All object should be alive. CHECK_EQ(0, NumberOfWeakCalls); @@ -398,7 +341,7 @@ TEST(ObjectGroups) { Handle<HeapObject>::cast(g2s1).location(), g2_children, 1); } - HEAP->CollectGarbage(OLD_POINTER_SPACE); + heap->CollectGarbage(OLD_POINTER_SPACE); // All objects should be gone. 5 global handles in total. CHECK_EQ(5, NumberOfWeakCalls); @@ -411,7 +354,7 @@ TEST(ObjectGroups) { reinterpret_cast<void*>(1234), &WeakPointerCallback); - HEAP->CollectGarbage(OLD_POINTER_SPACE); + heap->CollectGarbage(OLD_POINTER_SPACE); CHECK_EQ(7, NumberOfWeakCalls); } @@ -442,12 +385,12 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo { TEST(EmptyObjectGroups) { CcTest::InitializeVM(); - GlobalHandles* global_handles = Isolate::Current()->global_handles(); + GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); v8::HandleScope handle_scope(CcTest::isolate()); - Handle<Object> object = - global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); + Handle<Object> object = global_handles->Create( + CcTest::heap()->AllocateFixedArray(1)->ToObjectChecked()); TestRetainedObjectInfo info; global_handles->AddObjectGroup(NULL, 0, &info); diff --git a/deps/v8/test/cctest/test-object-observe.cc b/deps/v8/test/cctest/test-object-observe.cc index b129ff3af4..b4488a603a 100644 --- a/deps/v8/test/cctest/test-object-observe.cc +++ b/deps/v8/test/cctest/test-object-observe.cc @@ -58,7 +58,7 @@ class HarmonyIsolate { TEST(PerIsolateState) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context1; + LocalContext context1(isolate.GetIsolate()); CompileRun( "var count = 0;" "var calls = 0;" @@ -71,20 +71,20 @@ TEST(PerIsolateState) { "(function() { obj.foo = 'bar'; })"); Handle<Value> notify_fun2; { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), obj); notify_fun2 = CompileRun( "(function() { obj.foo = 'baz'; })"); } Handle<Value> notify_fun3; { - LocalContext context3; + LocalContext context3(isolate.GetIsolate()); context3->Global()->Set(String::New("obj"), obj); notify_fun3 = CompileRun( "(function() { obj.foo = 'bat'; })"); } { - LocalContext context4; + LocalContext context4(isolate.GetIsolate()); context4->Global()->Set(String::New("observer"), observer); context4->Global()->Set(String::New("fun1"), notify_fun1); context4->Global()->Set(String::New("fun2"), notify_fun2); @@ -99,7 +99,7 @@ TEST(PerIsolateState) { TEST(EndOfMicrotaskDelivery) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); CompileRun( "var obj = {};" "var count = 0;" @@ -113,7 +113,7 @@ TEST(EndOfMicrotaskDelivery) { TEST(DeliveryOrdering) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); CompileRun( "var obj1 = {};" "var obj2 = {};" @@ -145,7 +145,7 @@ TEST(DeliveryOrdering) { TEST(DeliveryOrderingReentrant) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); CompileRun( "var obj = {};" "var reentered = false;" @@ -177,7 +177,7 @@ TEST(DeliveryOrderingReentrant) { TEST(DeliveryOrderingDeliverChangeRecords) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); CompileRun( "var obj = {};" "var ordering = [];" @@ -203,14 +203,14 @@ TEST(ObjectHashTableGrowth) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); // Initializing this context sets up initial hash tables. - LocalContext context; + LocalContext context(isolate.GetIsolate()); Handle<Value> obj = CompileRun("obj = {};"); Handle<Value> observer = CompileRun( "var ran = false;" "(function() { ran = true })"); { // As does initializing this context. - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), obj); context2->Global()->Set(String::New("observer"), observer); CompileRun( @@ -231,7 +231,7 @@ TEST(ObjectHashTableGrowth) { TEST(GlobalObjectObservation) { HarmonyIsolate isolate; - LocalContext context; + LocalContext context(isolate.GetIsolate()); HandleScope scope(isolate.GetIsolate()); Handle<Object> global_proxy = context->Global(); Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); @@ -263,7 +263,7 @@ TEST(GlobalObjectObservation) { // to the old context. context->DetachGlobal(); { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->DetachGlobal(); context2->ReattachGlobal(global_proxy); CompileRun( @@ -278,7 +278,8 @@ TEST(GlobalObjectObservation) { // Attaching by passing to Context::New { // Delegates to Context::New - LocalContext context3(NULL, Handle<ObjectTemplate>(), global_proxy); + LocalContext context3( + isolate.GetIsolate(), NULL, Handle<ObjectTemplate>(), global_proxy); CompileRun( "var records3 = [];" "Object.observe(this, function(r) { [].push.apply(records3, r) });" @@ -330,7 +331,7 @@ static void ExpectRecords(Handle<Value> records, TEST(APITestBasicMutation) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); Handle<Object> obj = Handle<Object>::Cast(CompileRun( "var records = [];" "var obj = {};" @@ -374,7 +375,7 @@ TEST(APITestBasicMutation) { TEST(HiddenPrototypeObservation) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); tmpl->SetHiddenPrototype(true); tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); @@ -393,7 +394,7 @@ TEST(HiddenPrototypeObservation) { { obj, "updated", "foo", Number::New(75) } }; EXPECT_RECORDS(CompileRun("records"), expected_records); - obj->SetPrototype(Null()); + obj->SetPrototype(Null(isolate.GetIsolate())); CompileRun("obj.foo = 43"); const RecordExpectation expected_records2[] = { { obj, "new", "foo", Handle<Value>() } @@ -423,14 +424,15 @@ static int NumberOfElements(i::Handle<i::JSWeakMap> map) { TEST(ObservationWeakMap) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); CompileRun( "var obj = {};" "Object.observe(obj, function(){});" "Object.getNotifier(obj);" "obj = null;"); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate.GetIsolate()); i::Handle<i::JSObject> observation_state = - i::Isolate::Current()->factory()->observation_state(); + i_isolate->factory()->observation_state(); i::Handle<i::JSWeakMap> callbackInfoMap = i::Handle<i::JSWeakMap>::cast( i::GetProperty(observation_state, "callbackInfoMap")); @@ -443,7 +445,7 @@ TEST(ObservationWeakMap) { CHECK_EQ(1, NumberOfElements(callbackInfoMap)); CHECK_EQ(1, NumberOfElements(objectInfoMap)); CHECK_EQ(1, NumberOfElements(notifierObjectInfoMap)); - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); + i_isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); CHECK_EQ(0, NumberOfElements(callbackInfoMap)); CHECK_EQ(0, NumberOfElements(objectInfoMap)); CHECK_EQ(0, NumberOfElements(notifierObjectInfoMap)); @@ -463,50 +465,54 @@ static bool IndexedAccessAlwaysAllowed(Local<Object>, uint32_t, AccessType, static AccessType g_access_block_type = ACCESS_GET; +static const uint32_t kBlockedContextIndex = 1337; static bool NamedAccessAllowUnlessBlocked(Local<Object> host, - Local<Value> key, - AccessType type, - Local<Value>) { + Local<Value> key, + AccessType type, + Local<Value> data) { if (type != g_access_block_type) return true; - Handle<Object> global = Context::GetCurrent()->Global(); - Handle<Value> blacklist = global->Get(String::New("blacklist")); - if (!blacklist->IsObject()) return true; - if (key->IsString()) return !blacklist.As<Object>()->Has(key); - return true; + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( + Utils::OpenHandle(*host)->GetIsolate()); + Handle<Object> global = isolate->GetCurrentContext()->Global(); + if (!global->Has(kBlockedContextIndex)) return true; + return !key->IsString() || !key->Equals(data); } static bool IndexedAccessAllowUnlessBlocked(Local<Object> host, - uint32_t index, - AccessType type, - Local<Value>) { - if (type != ACCESS_GET) return true; - Handle<Object> global = Context::GetCurrent()->Global(); - Handle<Value> blacklist = global->Get(String::New("blacklist")); - if (!blacklist->IsObject()) return true; - return !blacklist.As<Object>()->Has(index); + uint32_t index, + AccessType type, + Local<Value> data) { + if (type != g_access_block_type) return true; + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( + Utils::OpenHandle(*host)->GetIsolate()); + Handle<Object> global = isolate->GetCurrentContext()->Global(); + if (!global->Has(kBlockedContextIndex)) return true; + return index != data->Uint32Value(); } static bool BlockAccessKeys(Local<Object> host, Local<Value> key, AccessType type, Local<Value>) { - Handle<Object> global = Context::GetCurrent()->Global(); - Handle<Value> blacklist = global->Get(String::New("blacklist")); - if (!blacklist->IsObject()) return true; - return type != ACCESS_KEYS || - !blacklist.As<Object>()->Has(String::New("__block_access_keys")); + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( + Utils::OpenHandle(*host)->GetIsolate()); + Handle<Object> global = isolate->GetCurrentContext()->Global(); + return type != ACCESS_KEYS || !global->Has(kBlockedContextIndex); } static Handle<Object> CreateAccessCheckedObject( NamedSecurityCallback namedCallback, - IndexedSecurityCallback indexedCallback) { + IndexedSecurityCallback indexedCallback, + Handle<Value> data = Handle<Value>()) { Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); - tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback); + tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback, data); Handle<Object> instance = tmpl->NewInstance(); - instance->CreationContext()->Global()->Set(String::New("obj"), instance); + Handle<Object> global = instance->CreationContext()->Global(); + global->Set(String::New("obj"), instance); + global->Set(kBlockedContextIndex, v8::True()); return instance; } @@ -516,19 +522,20 @@ TEST(NamedAccessCheck) { const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); g_access_block_type = types[i]; Handle<Object> instance = CreateAccessCheckedObject( - NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed); + NamedAccessAllowUnlessBlocked, + IndexedAccessAlwaysAllowed, + String::New("foo")); CompileRun("var records = null;" "var objNoCheck = {};" - "var blacklist = {foo: true};" "var observer = function(r) { records = r };" "Object.observe(obj, observer);" "Object.observe(objNoCheck, observer);"); Handle<Value> obj_no_check = CompileRun("objNoCheck"); { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), instance); context2->Global()->Set(String::New("objNoCheck"), obj_no_check); CompileRun("var records2 = null;" @@ -563,19 +570,19 @@ TEST(IndexedAccessCheck) { const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); g_access_block_type = types[i]; Handle<Object> instance = CreateAccessCheckedObject( - NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); + NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, + Number::New(7)); CompileRun("var records = null;" "var objNoCheck = {};" - "var blacklist = {7: true};" "var observer = function(r) { records = r };" "Object.observe(obj, observer);" "Object.observe(objNoCheck, observer);"); Handle<Value> obj_no_check = CompileRun("objNoCheck"); { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), instance); context2->Global()->Set(String::New("objNoCheck"), obj_no_check); CompileRun("var records2 = null;" @@ -608,21 +615,21 @@ TEST(IndexedAccessCheck) { TEST(SpliceAccessCheck) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); g_access_block_type = ACCESS_GET; Handle<Object> instance = CreateAccessCheckedObject( - NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); + NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, + Number::New(1)); CompileRun("var records = null;" "obj[1] = 'foo';" "obj.length = 2;" "var objNoCheck = {1: 'bar', length: 2};" - "var blacklist = {1: true};" "observer = function(r) { records = r };" "Array.observe(obj, observer);" "Array.observe(objNoCheck, observer);"); Handle<Value> obj_no_check = CompileRun("objNoCheck"); { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), instance); context2->Global()->Set(String::New("objNoCheck"), obj_no_check); CompileRun("var records2 = null;" @@ -653,18 +660,17 @@ TEST(SpliceAccessCheck) { TEST(DisallowAllForAccessKeys) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); Handle<Object> instance = CreateAccessCheckedObject( BlockAccessKeys, IndexedAccessAlwaysAllowed); CompileRun("var records = null;" "var objNoCheck = {};" "var observer = function(r) { records = r };" - "var blacklist = {__block_access_keys: true};" "Object.observe(obj, observer);" "Object.observe(objNoCheck, observer);"); Handle<Value> obj_no_check = CompileRun("objNoCheck"); { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), instance); context2->Global()->Set(String::New("objNoCheck"), obj_no_check); CompileRun("var records2 = null;" @@ -691,15 +697,14 @@ TEST(DisallowAllForAccessKeys) { TEST(AccessCheckDisallowApiModifications) { HarmonyIsolate isolate; HandleScope scope(isolate.GetIsolate()); - LocalContext context; + LocalContext context(isolate.GetIsolate()); Handle<Object> instance = CreateAccessCheckedObject( BlockAccessKeys, IndexedAccessAlwaysAllowed); CompileRun("var records = null;" "var observer = function(r) { records = r };" - "var blacklist = {__block_access_keys: true};" "Object.observe(obj, observer);"); { - LocalContext context2; + LocalContext context2(isolate.GetIsolate()); context2->Global()->Set(String::New("obj"), instance); CompileRun("var records2 = null;" "var observer2 = function(r) { records2 = r };" @@ -715,3 +720,18 @@ TEST(AccessCheckDisallowApiModifications) { } CHECK(CompileRun("records")->IsNull()); } + + +TEST(HiddenPropertiesLeakage) { + HarmonyIsolate isolate; + HandleScope scope(isolate.GetIsolate()); + LocalContext context(isolate.GetIsolate()); + CompileRun("var obj = {};" + "var records = null;" + "var observer = function(r) { records = r };" + "Object.observe(obj, observer);"); + Handle<Value> obj = context->Global()->Get(String::New("obj")); + Handle<Object>::Cast(obj)->SetHiddenValue(String::New("foo"), Null()); + CompileRun(""); // trigger delivery + CHECK(CompileRun("records")->IsNull()); +} diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index 80b276c8f9..952cb68cec 100644 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -107,6 +107,7 @@ TEST(ScanKeywords) { TEST(ScanHTMLEndComments) { v8::V8::Initialize(); + v8::Isolate* isolate = CcTest::isolate(); // Regression test. See: // http://code.google.com/p/chromium/issues/detail?id=53548 @@ -139,19 +140,19 @@ TEST(ScanHTMLEndComments) { // Parser/Scanner needs a stack limit. int marker; - i::Isolate::Current()->stack_guard()->SetStackLimit( + CcTest::i_isolate()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); for (int i = 0; tests[i]; i++) { v8::ScriptData* data = - v8::ScriptData::PreCompile(tests[i], i::StrLength(tests[i])); + v8::ScriptData::PreCompile(isolate, tests[i], i::StrLength(tests[i])); CHECK(data != NULL && !data->HasError()); delete data; } for (int i = 0; fail_tests[i]; i++) { - v8::ScriptData* data = - v8::ScriptData::PreCompile(fail_tests[i], i::StrLength(fail_tests[i])); + v8::ScriptData* data = v8::ScriptData::PreCompile( + isolate, fail_tests[i], i::StrLength(fail_tests[i])); CHECK(data == NULL || data->HasError()); delete data; } @@ -173,12 +174,12 @@ class ScriptResource : public v8::String::ExternalAsciiStringResource { TEST(Preparsing) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handles(isolate); v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); int marker; - i::Isolate::Current()->stack_guard()->SetStackLimit( + CcTest::i_isolate()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); // Source containing functions that might be lazily compiled and all types @@ -199,7 +200,7 @@ TEST(Preparsing) { int error_source_length = i::StrLength(error_source); v8::ScriptData* preparse = - v8::ScriptData::PreCompile(source, source_length); + v8::ScriptData::PreCompile(isolate, source, source_length); CHECK(!preparse->HasError()); bool lazy_flag = i::FLAG_lazy; { @@ -221,7 +222,7 @@ TEST(Preparsing) { // Syntax error. v8::ScriptData* error_preparse = - v8::ScriptData::PreCompile(error_source, error_source_length); + v8::ScriptData::PreCompile(isolate, error_source, error_source_length); CHECK(error_preparse->HasError()); i::ScriptDataImpl *pre_impl = reinterpret_cast<i::ScriptDataImpl*>(error_preparse); @@ -241,7 +242,7 @@ TEST(StandAlonePreParser) { v8::V8::Initialize(); int marker; - i::Isolate::Current()->stack_guard()->SetStackLimit( + CcTest::i_isolate()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); const char* programs[] = { @@ -253,22 +254,21 @@ TEST(StandAlonePreParser) { NULL }; - uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit(); + uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); for (int i = 0; programs[i]; i++) { const char* program = programs[i]; i::Utf8ToUtf16CharacterStream stream( reinterpret_cast<const i::byte*>(program), static_cast<unsigned>(strlen(program))); i::CompleteParserRecorder log; - i::Scanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); scanner.Initialize(&stream); - v8::preparser::PreParser preparser(&scanner, &log, stack_limit); + i::PreParser preparser(&scanner, &log, stack_limit); preparser.set_allow_lazy(true); preparser.set_allow_natives_syntax(true); - v8::preparser::PreParser::PreParseResult result = - preparser.PreParseProgram(); - CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); + i::PreParser::PreParseResult result = preparser.PreParseProgram(); + CHECK_EQ(i::PreParser::kPreParseSuccess, result); i::ScriptDataImpl data(log.ExtractData()); CHECK(!data.has_error()); } @@ -279,7 +279,7 @@ TEST(StandAlonePreParserNoNatives) { v8::V8::Initialize(); int marker; - i::Isolate::Current()->stack_guard()->SetStackLimit( + CcTest::i_isolate()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); const char* programs[] = { @@ -288,22 +288,21 @@ TEST(StandAlonePreParserNoNatives) { NULL }; - uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit(); + uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); for (int i = 0; programs[i]; i++) { const char* program = programs[i]; i::Utf8ToUtf16CharacterStream stream( reinterpret_cast<const i::byte*>(program), static_cast<unsigned>(strlen(program))); i::CompleteParserRecorder log; - i::Scanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); scanner.Initialize(&stream); // Preparser defaults to disallowing natives syntax. - v8::preparser::PreParser preparser(&scanner, &log, stack_limit); + i::PreParser preparser(&scanner, &log, stack_limit); preparser.set_allow_lazy(true); - v8::preparser::PreParser::PreParseResult result = - preparser.PreParseProgram(); - CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); + i::PreParser::PreParseResult result = preparser.PreParseProgram(); + CHECK_EQ(i::PreParser::kPreParseSuccess, result); i::ScriptDataImpl data(log.ExtractData()); // Data contains syntax error. CHECK(data.has_error()); @@ -313,7 +312,7 @@ TEST(StandAlonePreParserNoNatives) { TEST(RegressChromium62639) { v8::V8::Initialize(); - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); int marker; isolate->stack_guard()->SetStackLimit( @@ -337,7 +336,7 @@ TEST(RegressChromium62639) { TEST(Regress928) { v8::V8::Initialize(); - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); // Preparsing didn't consider the catch clause of a try statement @@ -352,7 +351,7 @@ TEST(Regress928) { "try { } catch (e) { var foo = function () { /* first */ } }" "var bar = function () { /* second */ }"; - v8::HandleScope handles(v8::Isolate::GetCurrent()); + v8::HandleScope handles(CcTest::isolate()); i::Handle<i::String> source( factory->NewStringFromAscii(i::CStrVector(program))); i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); @@ -384,7 +383,7 @@ TEST(PreParseOverflow) { v8::V8::Initialize(); int marker; - i::Isolate::Current()->stack_guard()->SetStackLimit( + CcTest::i_isolate()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); size_t kProgramSize = 1024 * 1024; @@ -392,20 +391,19 @@ TEST(PreParseOverflow) { memset(*program, '(', kProgramSize); program[kProgramSize] = '\0'; - uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit(); + uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); i::Utf8ToUtf16CharacterStream stream( reinterpret_cast<const i::byte*>(*program), static_cast<unsigned>(kProgramSize)); i::CompleteParserRecorder log; - i::Scanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); scanner.Initialize(&stream); - v8::preparser::PreParser preparser(&scanner, &log, stack_limit); + i::PreParser preparser(&scanner, &log, stack_limit); preparser.set_allow_lazy(true); - v8::preparser::PreParser::PreParseResult result = - preparser.PreParseProgram(); - CHECK_EQ(v8::preparser::PreParser::kPreParseStackOverflow, result); + i::PreParser::PreParseResult result = preparser.PreParseProgram(); + CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); } @@ -437,7 +435,7 @@ void TestCharacterStream(const char* ascii_source, unsigned end = 0) { if (end == 0) end = length; unsigned sub_length = end - start; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); i::HandleScope test_scope(isolate); i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]); @@ -544,7 +542,7 @@ void TestCharacterStream(const char* ascii_source, TEST(CharacterStreams) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handles(isolate); v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -619,7 +617,7 @@ void TestStreamScanner(i::Utf16CharacterStream* stream, i::Token::Value* expected_tokens, int skip_pos = 0, // Zero means not skipping. int skip_to = 0) { - i::Scanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); scanner.Initialize(stream); int i = 0; @@ -701,7 +699,7 @@ void TestScanRegExp(const char* re_source, const char* expected) { i::Utf8ToUtf16CharacterStream stream( reinterpret_cast<const i::byte*>(re_source), static_cast<unsigned>(strlen(re_source))); - i::Scanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); scanner.Initialize(&stream); i::Token::Value start = scanner.peek(); @@ -990,11 +988,11 @@ TEST(ScopePositions) { { NULL, NULL, NULL, i::EVAL_SCOPE, i::CLASSIC_MODE } }; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); - v8::HandleScope handles(v8::Isolate::GetCurrent()); - v8::Handle<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent()); + v8::HandleScope handles(CcTest::isolate()); + v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); v8::Context::Scope context_scope(context); int marker; @@ -1027,11 +1025,11 @@ TEST(ScopePositions) { parser.set_allow_harmony_scoping(true); info.MarkAsGlobal(); info.SetLanguageMode(source_data[i].language_mode); - i::FunctionLiteral* function = parser.ParseProgram(); - CHECK(function != NULL); + parser.Parse(); + CHECK(info.function() != NULL); // Check scope types and positions. - i::Scope* scope = function->scope(); + i::Scope* scope = info.function()->scope(); CHECK(scope->is_global_scope()); CHECK_EQ(scope->start_position(), 0); CHECK_EQ(scope->end_position(), kProgramSize); @@ -1048,7 +1046,7 @@ TEST(ScopePositions) { i::Handle<i::String> FormatMessage(i::ScriptDataImpl* data) { - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); const char* message = data->BuildMessage(); i::Handle<i::String> format = v8::Utils::OpenHandle( @@ -1087,30 +1085,25 @@ enum ParserFlag { kAllowModules, kAllowGenerators, kAllowForOf, - kAllowHarmonyNumericLiterals, - kParserFlagCount + kAllowHarmonyNumericLiterals }; -static bool checkParserFlag(unsigned flags, ParserFlag flag) { - return flags & (1 << flag); +void SetParserFlags(i::ParserBase* parser, i::EnumSet<ParserFlag> flags) { + parser->set_allow_lazy(flags.Contains(kAllowLazy)); + parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax)); + parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); + parser->set_allow_modules(flags.Contains(kAllowModules)); + parser->set_allow_generators(flags.Contains(kAllowGenerators)); + parser->set_allow_for_of(flags.Contains(kAllowForOf)); + parser->set_allow_harmony_numeric_literals( + flags.Contains(kAllowHarmonyNumericLiterals)); } -#define SET_PARSER_FLAGS(parser, flags) \ - parser.set_allow_lazy(checkParserFlag(flags, kAllowLazy)); \ - parser.set_allow_natives_syntax(checkParserFlag(flags, \ - kAllowNativesSyntax)); \ - parser.set_allow_harmony_scoping(checkParserFlag(flags, \ - kAllowHarmonyScoping)); \ - parser.set_allow_modules(checkParserFlag(flags, kAllowModules)); \ - parser.set_allow_generators(checkParserFlag(flags, kAllowGenerators)); \ - parser.set_allow_for_of(checkParserFlag(flags, kAllowForOf)); \ - parser.set_allow_harmony_numeric_literals( \ - checkParserFlag(flags, kAllowHarmonyNumericLiterals)); - -void TestParserSyncWithFlags(i::Handle<i::String> source, unsigned flags) { - i::Isolate* isolate = i::Isolate::Current(); +void TestParserSyncWithFlags(i::Handle<i::String> source, + i::EnumSet<ParserFlag> flags) { + i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); uintptr_t stack_limit = isolate->stack_guard()->real_climit(); @@ -1120,12 +1113,11 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, unsigned flags) { { i::Scanner scanner(isolate->unicode_cache()); i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); - v8::preparser::PreParser preparser(&scanner, &log, stack_limit); - SET_PARSER_FLAGS(preparser, flags); + i::PreParser preparser(&scanner, &log, stack_limit); + SetParserFlags(&preparser, flags); scanner.Initialize(&stream); - v8::preparser::PreParser::PreParseResult result = - preparser.PreParseProgram(); - CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); + i::PreParser::PreParseResult result = preparser.PreParseProgram(); + CHECK_EQ(i::PreParser::kPreParseSuccess, result); } i::ScriptDataImpl data(log.ExtractData()); @@ -1135,9 +1127,10 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, unsigned flags) { i::Handle<i::Script> script = factory->NewScript(source); i::CompilationInfoWithZone info(script); i::Parser parser(&info); - SET_PARSER_FLAGS(parser, flags); + SetParserFlags(&parser, flags); info.MarkAsGlobal(); - function = parser.ParseProgram(); + parser.Parse(); + function = info.function(); } // Check that preparsing fails iff parsing fails. @@ -1188,9 +1181,17 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, unsigned flags) { } -void TestParserSync(i::Handle<i::String> source) { - for (unsigned flags = 0; flags < (1 << kParserFlagCount); ++flags) { - TestParserSyncWithFlags(source, flags); +void TestParserSync(const char* source, + const ParserFlag* flag_list, + size_t flag_list_length) { + i::Handle<i::String> str = + CcTest::i_isolate()->factory()->NewStringFromAscii(i::CStrVector(source)); + for (int bits = 0; bits < (1 << flag_list_length); bits++) { + i::EnumSet<ParserFlag> flags; + for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) { + if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]); + } + TestParserSyncWithFlags(str, flags); } } @@ -1264,17 +1265,18 @@ TEST(ParserSync) { NULL }; - i::Isolate* isolate = i::Isolate::Current(); - i::Factory* factory = isolate->factory(); - - v8::HandleScope handles(v8::Isolate::GetCurrent()); - v8::Handle<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent()); + v8::HandleScope handles(CcTest::isolate()); + v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); v8::Context::Scope context_scope(context); int marker; - isolate->stack_guard()->SetStackLimit( + CcTest::i_isolate()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); + static const ParserFlag flags1[] = { + kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, + kAllowForOf + }; for (int i = 0; context_data[i][0] != NULL; ++i) { for (int j = 0; statement_data[j] != NULL; ++j) { for (int k = 0; termination_data[k] != NULL; ++k) { @@ -1294,12 +1296,20 @@ TEST(ParserSync) { termination_data[k], context_data[i][1]); CHECK(length == kProgramSize); - i::Handle<i::String> source = - factory->NewStringFromAscii(i::CStrVector(program.start())); - TestParserSync(source); + TestParserSync(program.start(), flags1, ARRAY_SIZE(flags1)); } } } + + // Neither Harmony numeric literals nor our natives syntax have any + // interaction with the flags above, so test these separately to reduce + // the combinatorial explosion. + static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals }; + TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2)); + TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2)); + + static const ParserFlag flags3[] = { kAllowNativesSyntax }; + TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3)); } @@ -1308,9 +1318,9 @@ TEST(PreparserStrictOctal) { // such (issue 2220). v8::internal::FLAG_min_preparse_length = 1; // Force preparsing. v8::V8::Initialize(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Context::Scope context_scope( - v8::Context::New(v8::Isolate::GetCurrent())); + v8::Context::New(CcTest::isolate())); v8::TryCatch try_catch; const char* script = "\"use strict\"; \n" diff --git a/deps/v8/test/cctest/test-platform.cc b/deps/v8/test/cctest/test-platform.cc index 079cbd121b..36ad487079 100644 --- a/deps/v8/test/cctest/test-platform.cc +++ b/deps/v8/test/cctest/test-platform.cc @@ -70,7 +70,7 @@ void GetStackPointer(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(StackAlignment) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); global_template->Set(v8_str("get_stack_pointer"), diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index 7504b171de..47146ecc48 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -399,7 +399,7 @@ class TestSetup { TEST(RecordTickSample) { TestSetup test_setup; - CpuProfilesCollection profiles(CcTest::i_isolate()->heap()); + CpuProfilesCollection profiles(CcTest::heap()); profiles.StartProfiling("", 1, false); ProfileGenerator generator(&profiles); CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); @@ -465,7 +465,7 @@ static void CheckNodeIds(ProfileNode* node, int* expectedId) { TEST(SampleIds) { TestSetup test_setup; - CpuProfilesCollection profiles(CcTest::i_isolate()->heap()); + CpuProfilesCollection profiles(CcTest::heap()); profiles.StartProfiling("", 1, true); ProfileGenerator generator(&profiles); CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); @@ -513,7 +513,7 @@ TEST(SampleIds) { TEST(NoSamples) { TestSetup test_setup; - CpuProfilesCollection profiles(CcTest::i_isolate()->heap()); + CpuProfilesCollection profiles(CcTest::heap()); profiles.StartProfiling("", 1, false); ProfileGenerator generator(&profiles); CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); @@ -605,14 +605,14 @@ TEST(RecordStackTraceAtStartProfiling) { // don't appear in the stack trace. i::FLAG_use_inlining = false; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); const char* extensions[] = { "v8/profiler" }; v8::ExtensionConfiguration config(1, extensions); v8::Local<v8::Context> context = v8::Context::New(isolate, &config); context->Enter(); - CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler(); + CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); CHECK_EQ(0, profiler->GetProfilesCount()); CompileRun( "function c() { startProfiling(); }\n" @@ -652,7 +652,7 @@ TEST(RecordStackTraceAtStartProfiling) { TEST(Issue51919) { - CpuProfilesCollection collection(CcTest::i_isolate()->heap()); + CpuProfilesCollection collection(CcTest::heap()); i::EmbeddedVector<char*, CpuProfilesCollection::kMaxSimultaneousProfiles> titles; for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) { @@ -744,7 +744,7 @@ static const char* line_number_test_source_profile_time_functions = "function lazy_func_at_6th_line() {}"; int GetFunctionLineNumber(LocalContext* env, const char* name) { - CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler(); + CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); CodeMap* code_map = profiler->generator()->code_map(); i::Handle<i::JSFunction> func = v8::Utils::OpenHandle( *v8::Local<v8::Function>::Cast( @@ -761,7 +761,7 @@ TEST(LineNumber) { CcTest::InitializeVM(); LocalContext env; - i::Isolate* isolate = i::Isolate::Current(); + i::Isolate* isolate = CcTest::i_isolate(); TestSetup test_setup; i::HandleScope scope(isolate); diff --git a/deps/v8/test/cctest/test-random.cc b/deps/v8/test/cctest/test-random.cc index 4227326a92..ea1f36f24c 100644 --- a/deps/v8/test/cctest/test-random.cc +++ b/deps/v8/test/cctest/test-random.cc @@ -69,8 +69,8 @@ void TestSeeds(Handle<JSFunction> fun, TEST(CrankshaftRandom) { v8::V8::Initialize(); // Skip test if crankshaft is disabled. - if (!Isolate::Current()->use_crankshaft()) return; - v8::Isolate* v8_isolate = v8::Isolate::GetCurrent(); + if (!CcTest::i_isolate()->use_crankshaft()) return; + v8::Isolate* v8_isolate = CcTest::isolate(); v8::HandleScope scope(v8_isolate); v8::Context::Scope context_scope(v8::Context::New(v8_isolate)); @@ -82,7 +82,7 @@ TEST(CrankshaftRandom) { CompileRun("function f() { return Math.random(); }"); - Object* string = Isolate::Current()->factory()->InternalizeOneByteString( + Object* string = CcTest::i_isolate()->factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("f"))->ToObjectChecked(); MaybeObject* fun_object = context->global_object()->GetProperty(String::cast(string)); diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index 14989ee980..cc946464b2 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -71,9 +71,9 @@ using namespace v8::internal; static bool CheckParse(const char* input) { V8::Initialize(NULL); - v8::HandleScope scope(v8::Isolate::GetCurrent()); - Zone zone(Isolate::Current()); - FlatStringReader reader(Isolate::Current(), CStrVector(input)); + v8::HandleScope scope(CcTest::isolate()); + Zone zone(CcTest::i_isolate()); + FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); RegExpCompileData result; return v8::internal::RegExpParser::ParseRegExp( &reader, false, &result, &zone); @@ -82,9 +82,9 @@ static bool CheckParse(const char* input) { static SmartArrayPointer<const char> Parse(const char* input) { V8::Initialize(NULL); - v8::HandleScope scope(v8::Isolate::GetCurrent()); - Zone zone(Isolate::Current()); - FlatStringReader reader(Isolate::Current(), CStrVector(input)); + v8::HandleScope scope(CcTest::isolate()); + Zone zone(CcTest::i_isolate()); + FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); RegExpCompileData result; CHECK(v8::internal::RegExpParser::ParseRegExp( &reader, false, &result, &zone)); @@ -97,9 +97,9 @@ static SmartArrayPointer<const char> Parse(const char* input) { static bool CheckSimple(const char* input) { V8::Initialize(NULL); - v8::HandleScope scope(v8::Isolate::GetCurrent()); - Zone zone(Isolate::Current()); - FlatStringReader reader(Isolate::Current(), CStrVector(input)); + v8::HandleScope scope(CcTest::isolate()); + Zone zone(CcTest::i_isolate()); + FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); RegExpCompileData result; CHECK(v8::internal::RegExpParser::ParseRegExp( &reader, false, &result, &zone)); @@ -116,9 +116,9 @@ struct MinMaxPair { static MinMaxPair CheckMinMaxMatch(const char* input) { V8::Initialize(NULL); - v8::HandleScope scope(v8::Isolate::GetCurrent()); - Zone zone(Isolate::Current()); - FlatStringReader reader(Isolate::Current(), CStrVector(input)); + v8::HandleScope scope(CcTest::isolate()); + Zone zone(CcTest::i_isolate()); + FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); RegExpCompileData result; CHECK(v8::internal::RegExpParser::ParseRegExp( &reader, false, &result, &zone)); @@ -390,9 +390,9 @@ TEST(ParserRegression) { static void ExpectError(const char* input, const char* expected) { V8::Initialize(NULL); - v8::HandleScope scope(v8::Isolate::GetCurrent()); - Zone zone(Isolate::Current()); - FlatStringReader reader(Isolate::Current(), CStrVector(input)); + v8::HandleScope scope(CcTest::isolate()); + Zone zone(CcTest::i_isolate()); + FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); RegExpCompileData result; CHECK(!v8::internal::RegExpParser::ParseRegExp( &reader, false, &result, &zone)); @@ -404,7 +404,6 @@ static void ExpectError(const char* input, TEST(Errors) { - V8::Initialize(NULL); const char* kEndBackslash = "\\ at end of pattern"; ExpectError("\\", kEndBackslash); const char* kUnterminatedGroup = "Unterminated group"; @@ -475,7 +474,7 @@ static bool NotWord(uc16 c) { static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) { - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneList<CharacterRange>* ranges = new(&zone) ZoneList<CharacterRange>(2, &zone); CharacterRange::AddClassEscape(c, ranges, &zone); @@ -507,7 +506,7 @@ static RegExpNode* Compile(const char* input, bool is_ascii, Zone* zone) { V8::Initialize(NULL); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); FlatStringReader reader(isolate, CStrVector(input)); RegExpCompileData compile_data; if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline, @@ -533,8 +532,8 @@ static void Execute(const char* input, bool multiline, bool is_ascii, bool dot_output = false) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); - Zone zone(Isolate::Current()); + v8::HandleScope scope(CcTest::isolate()); + Zone zone(CcTest::i_isolate()); RegExpNode* node = Compile(input, multiline, is_ascii, &zone); USE(node); #ifdef DEBUG @@ -574,7 +573,7 @@ static unsigned PseudoRandom(int i, int j) { TEST(SplayTreeSimple) { v8::internal::V8::Initialize(NULL); static const unsigned kLimit = 1000; - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneSplayTree<TestConfig> tree(&zone); bool seen[kLimit]; for (unsigned i = 0; i < kLimit; i++) seen[i] = false; @@ -642,7 +641,7 @@ TEST(DispatchTableConstruction) { } } // Enter test data into dispatch table. - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); DispatchTable table(&zone); for (int i = 0; i < kRangeCount; i++) { uc16* range = ranges[i]; @@ -710,8 +709,8 @@ typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler; class ContextInitializer { public: ContextInitializer() - : scope_(v8::Isolate::GetCurrent()), - env_(v8::Context::New(v8::Isolate::GetCurrent())) { + : scope_(CcTest::isolate()), + env_(v8::Context::New(CcTest::isolate())) { env_->Enter(); } ~ContextInitializer() { @@ -737,14 +736,14 @@ static ArchRegExpMacroAssembler::Result Execute(Code* code, input_end, captures, 0, - Isolate::Current()); + CcTest::i_isolate()); } TEST(MacroAssemblerNativeSuccess) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -781,7 +780,7 @@ TEST(MacroAssemblerNativeSuccess) { TEST(MacroAssemblerNativeSimple) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -847,7 +846,7 @@ TEST(MacroAssemblerNativeSimple) { TEST(MacroAssemblerNativeSimpleUC16) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -918,7 +917,7 @@ TEST(MacroAssemblerNativeSimpleUC16) { TEST(MacroAssemblerNativeBacktrack) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -958,7 +957,7 @@ TEST(MacroAssemblerNativeBacktrack) { TEST(MacroAssemblerNativeBackReferenceASCII) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1007,7 +1006,7 @@ TEST(MacroAssemblerNativeBackReferenceASCII) { TEST(MacroAssemblerNativeBackReferenceUC16) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1059,7 +1058,7 @@ TEST(MacroAssemblerNativeBackReferenceUC16) { TEST(MacroAssemblernativeAtStart) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1118,7 +1117,7 @@ TEST(MacroAssemblernativeAtStart) { TEST(MacroAssemblerNativeBackRefNoCase) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1177,7 +1176,7 @@ TEST(MacroAssemblerNativeBackRefNoCase) { TEST(MacroAssemblerNativeRegisters) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1280,7 +1279,7 @@ TEST(MacroAssemblerNativeRegisters) { TEST(MacroAssemblerStackOverflow) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1319,7 +1318,7 @@ TEST(MacroAssemblerStackOverflow) { TEST(MacroAssemblerNativeLotsOfRegisters) { v8::V8::Initialize(); ContextInitializer initializer; - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); Zone zone(isolate); @@ -1370,7 +1369,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) { TEST(MacroAssembler) { V8::Initialize(NULL); byte codes[1024]; - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024), &zone); // ^f(o)o. Label start, fail, backtrack; @@ -1403,7 +1402,7 @@ TEST(MacroAssembler) { m.PopRegister(0); m.Fail(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); HandleScope scope(isolate); @@ -1438,7 +1437,7 @@ TEST(AddInverseToTable) { static const int kLimit = 1000; static const int kRangeCount = 16; for (int t = 0; t < 10; t++) { - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneList<CharacterRange>* ranges = new(&zone) ZoneList<CharacterRange>(kRangeCount, &zone); for (int i = 0; i < kRangeCount; i++) { @@ -1459,7 +1458,7 @@ TEST(AddInverseToTable) { CHECK_EQ(is_on, set->Get(0) == false); } } - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneList<CharacterRange>* ranges = new(&zone) ZoneList<CharacterRange>(1, &zone); ranges->Add(CharacterRange(0xFFF0, 0xFFFE), &zone); @@ -1572,7 +1571,7 @@ TEST(UncanonicalizeEquivalence) { static void TestRangeCaseIndependence(CharacterRange input, Vector<CharacterRange> expected) { - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); int count = expected.length(); ZoneList<CharacterRange>* list = new(&zone) ZoneList<CharacterRange>(count, &zone); @@ -1637,7 +1636,7 @@ static bool InClass(uc16 c, ZoneList<CharacterRange>* ranges) { TEST(CharClassDifference) { v8::internal::V8::Initialize(NULL); - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneList<CharacterRange>* base = new(&zone) ZoneList<CharacterRange>(1, &zone); base->Add(CharacterRange::Everything(), &zone); @@ -1665,7 +1664,7 @@ TEST(CharClassDifference) { TEST(CanonicalizeCharacterSets) { v8::internal::V8::Initialize(NULL); - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneList<CharacterRange>* list = new(&zone) ZoneList<CharacterRange>(4, &zone); CharacterSet set(list); @@ -1727,7 +1726,7 @@ TEST(CanonicalizeCharacterSets) { TEST(CharacterRangeMerge) { v8::internal::V8::Initialize(NULL); - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ZoneList<CharacterRange> l1(4, &zone); ZoneList<CharacterRange> l2(4, &zone); // Create all combinations of intersections of ranges, both singletons and diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 099f3a05a9..4132d2d4cf 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -84,7 +84,7 @@ static int* counter_function(const char* name) { template <class T> static Address AddressOf(T id) { - return ExternalReference(id, i::Isolate::Current()).address(); + return ExternalReference(id, CcTest::i_isolate()).address(); } @@ -100,7 +100,7 @@ static int make_code(TypeCode type, int id) { TEST(ExternalReferenceEncoder) { - Isolate* isolate = i::Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); isolate->stats_table()->SetCounterFunction(counter_function); v8::V8::Initialize(); @@ -137,7 +137,7 @@ TEST(ExternalReferenceEncoder) { TEST(ExternalReferenceDecoder) { - Isolate* isolate = i::Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); isolate->stats_table()->SetCounterFunction(counter_function); v8::V8::Initialize(); @@ -251,20 +251,22 @@ static void Serialize() { // 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 = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); { v8::HandleScope scope(isolate); v8::Context::New(isolate); } - WriteToFile(reinterpret_cast<Isolate*>(isolate), - FLAG_testing_serialization_file); + + 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. TEST(Serialize) { if (!Snapshot::HaveASnapshotToStartFrom()) { - Serializer::Enable(Isolate::Current()); + Serializer::Enable(CcTest::i_isolate()); v8::V8::Initialize(); Serialize(); } @@ -274,7 +276,7 @@ TEST(Serialize) { // Test that heap serialization is non-destructive. TEST(SerializeTwice) { if (!Snapshot::HaveASnapshotToStartFrom()) { - Serializer::Enable(Isolate::Current()); + Serializer::Enable(CcTest::i_isolate()); v8::V8::Initialize(); Serialize(); Serialize(); @@ -291,14 +293,14 @@ static void Deserialize() { static void SanityCheck() { - Isolate* isolate = Isolate::Current(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + Isolate* isolate = CcTest::i_isolate(); + v8::HandleScope scope(CcTest::isolate()); #ifdef VERIFY_HEAP - HEAP->Verify(); + CcTest::heap()->Verify(); #endif CHECK(isolate->global_object()->IsJSObject()); CHECK(isolate->native_context()->IsContext()); - CHECK(HEAP->string_table()->IsStringTable()); + CHECK(CcTest::heap()->string_table()->IsStringTable()); CHECK(!isolate->factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("Empty"))->IsFailure()); } @@ -309,7 +311,7 @@ DEPENDENT_TEST(Deserialize, Serialize) { // 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 = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Deserialize(); @@ -323,7 +325,7 @@ DEPENDENT_TEST(Deserialize, Serialize) { DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Deserialize(); @@ -337,7 +339,7 @@ DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) { DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Deserialize(); @@ -355,7 +357,7 @@ DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, SerializeTwice) { if (!Snapshot::HaveASnapshotToStartFrom()) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Deserialize(); @@ -372,7 +374,7 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, TEST(PartialSerialization) { if (!Snapshot::HaveASnapshotToStartFrom()) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Serializer::Enable(isolate); v8::V8::Initialize(); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); @@ -495,7 +497,7 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { int snapshot_size = 0; byte* snapshot = ReadBytes(file_name, &snapshot_size); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Object* root; { SnapshotByteSource source(snapshot, snapshot_size); @@ -523,7 +525,7 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { TEST(ContextSerialization) { if (!Snapshot::HaveASnapshotToStartFrom()) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Serializer::Enable(isolate); v8::V8::Initialize(); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); @@ -607,7 +609,7 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { int snapshot_size = 0; byte* snapshot = ReadBytes(file_name, &snapshot_size); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Object* root; { SnapshotByteSource source(snapshot, snapshot_size); diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc index 3326a015de..73710658a2 100644 --- a/deps/v8/test/cctest/test-spaces.cc +++ b/deps/v8/test/cctest/test-spaces.cc @@ -72,7 +72,7 @@ TEST(Page) { Page* p = Page::FromAddress(page_start); // Initialized Page has heap pointer, normally set by memory_allocator. - p->heap_ = HEAP; + p->heap_ = CcTest::heap(); CHECK(p->address() == page_start); CHECK(p->is_valid()); @@ -207,7 +207,7 @@ static unsigned int Pseudorandom() { TEST(MemoryChunk) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); CHECK(heap->ConfigureHeapDefault()); @@ -263,7 +263,7 @@ TEST(MemoryChunk) { TEST(MemoryAllocator) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); CHECK(isolate->heap()->ConfigureHeapDefault()); @@ -312,7 +312,7 @@ TEST(MemoryAllocator) { TEST(NewSpace) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); CHECK(heap->ConfigureHeapDefault()); @@ -323,8 +323,8 @@ TEST(NewSpace) { NewSpace new_space(heap); - CHECK(new_space.SetUp(HEAP->ReservedSemiSpaceSize(), - HEAP->ReservedSemiSpaceSize())); + CHECK(new_space.SetUp(CcTest::heap()->ReservedSemiSpaceSize(), + CcTest::heap()->ReservedSemiSpaceSize())); CHECK(new_space.HasBeenSetUp()); while (new_space.Available() >= Page::kMaxNonCodeHeapObjectSize) { @@ -341,7 +341,7 @@ TEST(NewSpace) { TEST(OldSpace) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); isolate->InitializeLoggingAndCounters(); Heap* heap = isolate->heap(); CHECK(heap->ConfigureHeapDefault()); @@ -372,7 +372,7 @@ TEST(OldSpace) { TEST(LargeObjectSpace) { v8::V8::Initialize(); - LargeObjectSpace* lo = HEAP->lo_space(); + LargeObjectSpace* lo = CcTest::heap()->lo_space(); CHECK(lo != NULL); int lo_size = Page::kPageSize; @@ -400,3 +400,25 @@ TEST(LargeObjectSpace) { CHECK(lo->AllocateRaw(lo_size, NOT_EXECUTABLE)->IsFailure()); } + + +TEST(SizeOfFirstPageIsLargeEnough) { + if (i::FLAG_always_opt) return; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + + // Freshly initialized VM gets by with one page per space. + for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { + CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages()); + } + + // Executing the empty script gets by with one page per space. + HandleScope scope(isolate); + CompileRun("/*empty*/"); + for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { + CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages()); + } + + // No large objects required to perform the above steps. + CHECK(isolate->heap()->lo_space()->IsEmpty()); +} diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index 9049df1b72..4aa74a8191 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -137,7 +137,7 @@ static void InitializeBuildingBlocks(Handle<String>* building_blocks, Zone* zone) { // A list of pointers that we don't have any interest in cleaning up. // If they are reachable from a root then leak detection won't complain. - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); for (int i = 0; i < bb_length; i++) { int len = rng->next(16); @@ -290,7 +290,7 @@ ConsStringGenerationData::ConsStringGenerationData(bool long_blocks, rng_.init(); InitializeBuildingBlocks( building_blocks_, kNumberOfBuildingBlocks, long_blocks, &rng_, zone); - empty_string_ = Isolate::Current()->heap()->empty_string(); + empty_string_ = CcTest::heap()->empty_string(); Reset(); } @@ -403,7 +403,7 @@ void VerifyConsString(Handle<String> root, ConsStringGenerationData* data) { static Handle<String> ConstructRandomString(ConsStringGenerationData* data, unsigned max_recursion) { - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); // Compute termination characteristics. bool terminate = false; bool flat = data->rng_.next(data->empty_leaf_threshold_); @@ -465,7 +465,7 @@ static Handle<String> ConstructRandomString(ConsStringGenerationData* data, static Handle<String> ConstructLeft( ConsStringGenerationData* data, int depth) { - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); Handle<String> answer = factory->NewStringFromAscii(CStrVector("")); data->stats_.leaves_++; for (int i = 0; i < depth; i++) { @@ -483,7 +483,7 @@ static Handle<String> ConstructLeft( static Handle<String> ConstructRight( ConsStringGenerationData* data, int depth) { - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); Handle<String> answer = factory->NewStringFromAscii(CStrVector("")); data->stats_.leaves_++; for (int i = depth - 1; i >= 0; i--) { @@ -502,7 +502,7 @@ static Handle<String> ConstructBalancedHelper( ConsStringGenerationData* data, int from, int to) { - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); CHECK(to > from); if (to - from == 1) { data->stats_.chars_ += data->block(from)->length(); @@ -571,7 +571,7 @@ TEST(Traverse) { printf("TestTraverse\n"); CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - Zone zone(Isolate::Current()); + Zone zone(CcTest::i_isolate()); ConsStringGenerationData data(false, &zone); Handle<String> flat = ConstructBalanced(&data); FlattenString(flat); @@ -659,7 +659,7 @@ printf( template<typename BuildString> void TestStringCharacterStream(BuildString build, int test_cases) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope outer_scope(isolate); Zone zone(isolate); ConsStringGenerationData data(true, &zone); @@ -697,7 +697,7 @@ static const int kCharacterStreamNonRandomCases = 8; static Handle<String> BuildEdgeCaseConsString( int test_case, ConsStringGenerationData* data) { - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); data->Reset(); switch (test_case) { case 0: @@ -860,7 +860,7 @@ static const int DEEP_ASCII_DEPTH = 100000; TEST(DeepAscii) { printf("TestDeepAscii\n"); CcTest::InitializeVM(); - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(CcTest::isolate()); char* foo = NewArray<char>(DEEP_ASCII_DEPTH); @@ -930,10 +930,10 @@ TEST(Utf8Conversion) { TEST(ExternalShortStringAdd) { - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Zone zone(isolate); - CcTest::InitializeVM(); + LocalContext context; v8::HandleScope handle_scope(CcTest::isolate()); // Make sure we cover all always-flat lengths and at least one above. @@ -974,7 +974,7 @@ TEST(ExternalShortStringAdd) { } // Add the arrays with the short external strings in the global object. - v8::Handle<v8::Object> global = CcTest::env()->Global(); + v8::Handle<v8::Object> global = context->Global(); global->Set(v8_str("external_ascii"), ascii_external_strings); global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); global->Set(v8_str("max_length"), v8::Integer::New(kMaxLength)); @@ -1018,9 +1018,9 @@ TEST(ExternalShortStringAdd) { TEST(JSONStringifySliceMadeExternal) { - Isolate* isolate = Isolate::Current(); - Zone zone(isolate); CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Zone zone(isolate); // Create a sliced string from a one-byte string. The latter is turned // into a two-byte external string. Check that JSON.stringify works. v8::HandleScope handle_scope(CcTest::isolate()); @@ -1048,13 +1048,13 @@ TEST(JSONStringifySliceMadeExternal) { TEST(CachedHashOverflow) { + CcTest::InitializeVM(); // We incorrectly allowed strings to be tagged as array indices even if their // values didn't fit in the hash field. // See http://code.google.com/p/v8/issues/detail?id=728 - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); Zone zone(isolate); - CcTest::InitializeVM(); v8::HandleScope handle_scope(CcTest::isolate()); // Lines must be executed sequentially. Combining them into one script // makes the bug go away. @@ -1098,7 +1098,7 @@ TEST(CachedHashOverflow) { TEST(SliceFromCons) { FLAG_string_slices = true; CcTest::InitializeVM(); - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(CcTest::isolate()); Handle<String> string = factory->NewStringFromAscii(CStrVector("parentparentparent")); @@ -1133,7 +1133,7 @@ class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { TEST(SliceFromExternal) { FLAG_string_slices = true; CcTest::InitializeVM(); - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(CcTest::isolate()); AsciiVectorResource resource( i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); @@ -1153,7 +1153,7 @@ TEST(TrivialSlice) { // actually creates a new string (it should not). FLAG_string_slices = true; CcTest::InitializeVM(); - Factory* factory = Isolate::Current()->factory(); + Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Value> result; Handle<String> string; @@ -1227,7 +1227,7 @@ TEST(AsciiArrayJoin) { "for (var i = 1; i <= two_14; i++) a.push(s);" "a.join("");"; - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); LocalContext context; v8::V8::IgnoreOutOfMemoryException(); v8::Local<v8::Script> script = diff --git a/deps/v8/test/cctest/test-symbols.cc b/deps/v8/test/cctest/test-symbols.cc index 6a8323bea4..a04ffa70c5 100644 --- a/deps/v8/test/cctest/test-symbols.cc +++ b/deps/v8/test/cctest/test-symbols.cc @@ -15,7 +15,7 @@ using namespace v8::internal; TEST(Create) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); const int kNumSymbols = 30; @@ -37,8 +37,8 @@ TEST(Create) { #endif } - HEAP->PerformScavenge(); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); + CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); // All symbols should be distinct. for (int i = 0; i < kNumSymbols; ++i) { diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc index b89f3ef8cf..13f594096f 100644 --- a/deps/v8/test/cctest/test-thread-termination.cc +++ b/deps/v8/test/cctest/test-thread-termination.cc @@ -39,8 +39,8 @@ void Signal(const v8::FunctionCallbackInfo<v8::Value>& args) { void TerminateCurrentThread(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(!v8::V8::IsExecutionTerminating()); - v8::V8::TerminateExecution(); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); + v8::V8::TerminateExecution(args.GetIsolate()); } @@ -50,18 +50,18 @@ void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { void Loop(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); v8::Handle<v8::String> source = v8::String::New("try { doloop(); fail(); } catch(e) { fail(); }"); v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run(); CHECK(result.IsEmpty()); - CHECK(v8::V8::IsExecutionTerminating()); + CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); } void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); v8::Script::Compile(v8::String::New("function f() {" " var term = true;" " try {" @@ -79,13 +79,13 @@ void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); + CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); } void DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); v8::Script::Compile(v8::String::New("var term = true;" "while(true) {" " if (term) terminate();" @@ -95,7 +95,7 @@ void DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); + CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); } @@ -115,19 +115,19 @@ v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate( // Test that a single thread of JavaScript execution can terminate // itself. TEST(TerminateOnlyV8ThreadFromThreadItself) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(TerminateCurrentThread, DoLoop); v8::Handle<v8::Context> context = - v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); + v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. v8::Handle<v8::String> source = v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); // Test that we can run the code again after thread termination. - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); v8::Script::Compile(source)->Run(); } @@ -135,18 +135,18 @@ TEST(TerminateOnlyV8ThreadFromThreadItself) { // Test that a single thread of JavaScript execution can terminate // itself in a loop that performs no calls. TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); v8::Handle<v8::Context> context = - v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); + v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. v8::Handle<v8::String> source = v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Test that we can run the code again after thread termination. v8::Script::Compile(source)->Run(); } @@ -172,15 +172,15 @@ class TerminatorThread : public v8::internal::Thread { // from the side by another thread. TEST(TerminateOnlyV8ThreadFromOtherThread) { semaphore = new v8::internal::Semaphore(0); - TerminatorThread thread(i::Isolate::Current()); + TerminatorThread thread(CcTest::i_isolate()); thread.Start(); - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); v8::Handle<v8::Context> context = - v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); + v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. v8::Handle<v8::String> source = v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); @@ -197,8 +197,8 @@ int call_count = 0; void TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) { if (++call_count == 10) { - CHECK(!v8::V8::IsExecutionTerminating()); - v8::V8::TerminateExecution(); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); + v8::V8::TerminateExecution(args.GetIsolate()); return; } v8::Local<v8::Object> result = v8::Object::New(); @@ -209,7 +209,7 @@ void TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) { void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); v8::Script::Compile(v8::String::New("function f() {" " try {" " while(true) {" @@ -225,14 +225,14 @@ void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); + CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); } // Test that we correctly handle termination exceptions if they are // triggered by the creation of error objects in connection with ICs. TEST(TerminateLoadICException) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); global->Set(v8::String::New("terminate_or_return_object"), v8::FunctionTemplate::New(TerminateOrReturnObject)); @@ -241,16 +241,16 @@ TEST(TerminateLoadICException) { v8::FunctionTemplate::New(LoopGetProperty)); v8::Handle<v8::Context> context = - v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); + v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. v8::Handle<v8::String> source = v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); call_count = 0; v8::Script::Compile(source)->Run(); // Test that we can run the code again after thread termination. - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); call_count = 0; v8::Script::Compile(source)->Run(); } @@ -258,7 +258,7 @@ TEST(TerminateLoadICException) { void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); v8::Script::Compile(v8::String::New("function f() {" " var term = true;" " try {" @@ -276,7 +276,7 @@ void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); + CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); } @@ -284,17 +284,17 @@ void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) { // Test that reentry into V8 while the termination exception is still pending // (has not yet unwound the 0-level JS frame) does not crash. TEST(TerminateAndReenterFromThreadItself) { - v8::HandleScope scope(v8::Isolate::GetCurrent()); + v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); v8::Handle<v8::Context> context = - v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); + v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); CHECK(!v8::V8::IsExecutionTerminating()); v8::Handle<v8::String> source = v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Check we can run JS again after termination. CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" "f()"))->Run()->IsTrue()); @@ -316,7 +316,7 @@ void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(!try_catch.CanContinue()); CHECK(v8::V8::IsExecutionTerminating()); CHECK(try_catch.HasTerminated()); - v8::V8::CancelTerminateExecution(v8::Isolate::GetCurrent()); + v8::V8::CancelTerminateExecution(CcTest::isolate()); CHECK(!v8::V8::IsExecutionTerminating()); } @@ -324,13 +324,13 @@ void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { // Test that a single thread of JavaScript execution can terminate // itself and then resume execution. TEST(TerminateCancelTerminateFromThreadItself) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate); v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global); v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); v8::Handle<v8::String> source = v8::String::New("try { doloop(); } catch(e) { fail(); } 'completed';"); // Check that execution completed with correct return value. diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 6cc5f52338..4709961636 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -34,21 +34,21 @@ TEST(Preemption) { - v8::Isolate* isolate = CcTest::default_isolate(); + v8::Isolate* isolate = CcTest::isolate(); v8::Locker locker(isolate); v8::V8::Initialize(); v8::HandleScope scope(isolate); v8::Handle<v8::Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - v8::Locker::StartPreemption(100); + v8::Locker::StartPreemption(isolate, 100); v8::Handle<v8::Script> script = v8::Script::Compile( v8::String::New("var count = 0; var obj = new Object(); count++;\n")); script->Run(); - v8::Locker::StopPreemption(); + v8::Locker::StopPreemption(isolate); v8::internal::OS::Sleep(500); // Make sure the timer fires. script->Run(); @@ -69,8 +69,9 @@ class ThreadA : public v8::internal::Thread { public: ThreadA() : Thread("ThreadA") { } void Run() { - v8::Isolate* isolate = CcTest::default_isolate(); + v8::Isolate* isolate = CcTest::isolate(); v8::Locker locker(isolate); + v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope scope(isolate); v8::Handle<v8::Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -90,7 +91,7 @@ class ThreadA : public v8::internal::Thread { turn = CLEAN_CACHE; do { { - v8::Unlocker unlocker(CcTest::default_isolate()); + v8::Unlocker unlocker(CcTest::isolate()); Thread::YieldCPU(); } } while (turn != SECOND_TIME_FILL_CACHE); @@ -109,15 +110,16 @@ class ThreadB : public v8::internal::Thread { void Run() { do { { - v8::Isolate* isolate = CcTest::default_isolate(); + v8::Isolate* isolate = CcTest::isolate(); v8::Locker locker(isolate); + v8::Isolate::Scope isolate_scope(isolate); if (turn == CLEAN_CACHE) { v8::HandleScope scope(isolate); v8::Handle<v8::Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); // Clear the caches by forcing major GC. - HEAP->CollectAllGarbage(v8::internal::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(v8::internal::Heap::kNoGCFlags); turn = SECOND_TIME_FILL_CACHE; break; } @@ -130,8 +132,6 @@ class ThreadB : public v8::internal::Thread { TEST(JSFunctionResultCachesInTwoThreads) { - v8::V8::Initialize(); - ThreadA threadA; ThreadB threadB; diff --git a/deps/v8/test/cctest/test-time.cc b/deps/v8/test/cctest/test-time.cc index 8b92d8d32a..28d647a5c1 100644 --- a/deps/v8/test/cctest/test-time.cc +++ b/deps/v8/test/cctest/test-time.cc @@ -133,7 +133,7 @@ TEST(TimeTicksIsMonotonic) { timer.Start(); while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) { TimeTicks normal_ticks = TimeTicks::Now(); - TimeTicks highres_ticks = TimeTicks::HighResNow(); + TimeTicks highres_ticks = TimeTicks::HighResolutionNow(); CHECK_GE(normal_ticks, previous_normal_ticks); CHECK_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0); CHECK_GE(highres_ticks, previous_highres_ticks); @@ -142,3 +142,54 @@ TEST(TimeTicksIsMonotonic) { previous_highres_ticks = highres_ticks; } } + + +template <typename T> +static void ResolutionTest(T (*Now)(), TimeDelta target_granularity) { + // We're trying to measure that intervals increment in a VERY small amount + // of time -- according to the specified target granularity. Unfortunately, + // if we happen to have a context switch in the middle of our test, the + // context switch could easily exceed our limit. So, we iterate on this + // several times. As long as we're able to detect the fine-granularity + // timers at least once, then the test has succeeded. + static const TimeDelta kExpirationTimeout = TimeDelta::FromSeconds(1); + ElapsedTimer timer; + timer.Start(); + TimeDelta delta; + do { + T start = Now(); + T now = start; + // Loop until we can detect that the clock has changed. Non-HighRes timers + // will increment in chunks, i.e. 15ms. By spinning until we see a clock + // change, we detect the minimum time between measurements. + do { + now = Now(); + delta = now - start; + } while (now <= start); + CHECK_NE(static_cast<int64_t>(0), delta.InMicroseconds()); + } while (delta > target_granularity && !timer.HasExpired(kExpirationTimeout)); + CHECK_LE(delta, target_granularity); +} + + +TEST(TimeNowResolution) { + // We assume that Time::Now() has at least 16ms resolution. + static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16); + ResolutionTest<Time>(&Time::Now, kTargetGranularity); +} + + +TEST(TimeTicksNowResolution) { + // We assume that TimeTicks::Now() has at least 16ms resolution. + static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16); + ResolutionTest<TimeTicks>(&TimeTicks::Now, kTargetGranularity); +} + + +TEST(TimeTicksHighResolutionNowResolution) { + if (!TimeTicks::IsHighResolutionClockWorking()) return; + + // We assume that TimeTicks::HighResolutionNow() has sub-ms resolution. + static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(1); + ResolutionTest<TimeTicks>(&TimeTicks::HighResolutionNow, kTargetGranularity); +} diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc index b5f65954fa..264d2ed881 100644 --- a/deps/v8/test/cctest/test-types.cc +++ b/deps/v8/test/cctest/test-types.cc @@ -111,8 +111,8 @@ class HandlifiedTypes { Null(Type::Null(), isolate), Undefined(Type::Undefined(), isolate), Number(Type::Number(), isolate), - Integer31(Type::Smi(), isolate), - Integer32(Type::Signed32(), isolate), + Smi(Type::Smi(), isolate), + Signed32(Type::Signed32(), isolate), Double(Type::Double(), isolate), Name(Type::Name(), isolate), UniqueName(Type::UniqueName(), isolate), @@ -128,16 +128,18 @@ class HandlifiedTypes { array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), isolate_(isolate) { smi = handle(Smi::FromInt(666), isolate); + signed32 = isolate->factory()->NewHeapNumber(0x40000000); object1 = isolate->factory()->NewJSObjectFromMap(object_map); object2 = isolate->factory()->NewJSObjectFromMap(object_map); array = isolate->factory()->NewJSArray(20); - ObjectClass = handle(Type::Class(object_map), isolate); - ArrayClass = handle(Type::Class(array_map), isolate); - Integer31Constant = handle(Type::Constant(smi, isolate), isolate); - ObjectConstant1 = handle(Type::Constant(object1), isolate); - ObjectConstant2 = handle(Type::Constant(object2), isolate); - ArrayConstant1 = handle(Type::Constant(array), isolate); - ArrayConstant2 = handle(Type::Constant(array), isolate); + ObjectClass = Class(object_map); + ArrayClass = Class(array_map); + SmiConstant = Constant(smi); + Signed32Constant = Constant(signed32); + ObjectConstant1 = Constant(object1); + ObjectConstant2 = Constant(object2); + ArrayConstant1 = Constant(array); + ArrayConstant2 = Constant(array); } Handle<Type> None; @@ -147,8 +149,8 @@ class HandlifiedTypes { Handle<Type> Null; Handle<Type> Undefined; Handle<Type> Number; - Handle<Type> Integer31; - Handle<Type> Integer32; + Handle<Type> Smi; + Handle<Type> Signed32; Handle<Type> Double; Handle<Type> Name; Handle<Type> UniqueName; @@ -164,7 +166,8 @@ class HandlifiedTypes { Handle<Type> ObjectClass; Handle<Type> ArrayClass; - Handle<Type> Integer31Constant; + Handle<Type> SmiConstant; + Handle<Type> Signed32Constant; Handle<Type> ObjectConstant1; Handle<Type> ObjectConstant2; Handle<Type> ArrayConstant1; @@ -173,11 +176,18 @@ class HandlifiedTypes { Handle<Map> object_map; Handle<Map> array_map; - Handle<v8::internal::Smi> smi; + Handle<i::Smi> smi; + Handle<HeapNumber> signed32; Handle<JSObject> object1; Handle<JSObject> object2; Handle<JSArray> array; + Handle<Type> Class(Handle<Map> map) { + return handle(Type::Class(map), isolate_); + } + Handle<Type> Constant(Handle<i::Object> value) { + return handle(Type::Constant(value, isolate_), isolate_); + } Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) { return handle(Type::Union(type1, type2), isolate_); } @@ -192,7 +202,7 @@ class HandlifiedTypes { TEST(Bitset) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); @@ -217,7 +227,7 @@ TEST(Bitset) { TEST(Class) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); @@ -231,17 +241,17 @@ TEST(Class) { TEST(Constant) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); - CHECK(IsConstant(*T.Integer31Constant)); + CHECK(IsConstant(*T.SmiConstant)); CHECK(IsConstant(*T.ObjectConstant1)); CHECK(IsConstant(*T.ObjectConstant2)); CHECK(IsConstant(*T.ArrayConstant1)); CHECK(IsConstant(*T.ArrayConstant2)); - CHECK(*T.smi == AsConstant(*T.Integer31Constant)); + CHECK(*T.smi == AsConstant(*T.SmiConstant)); CHECK(*T.object1 == AsConstant(*T.ObjectConstant1)); CHECK(*T.object2 == AsConstant(*T.ObjectConstant2)); CHECK(*T.object1 != AsConstant(*T.ObjectConstant2)); @@ -252,7 +262,7 @@ TEST(Constant) { TEST(Is) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); @@ -278,12 +288,12 @@ TEST(Is) { CheckUnordered(T.Boolean, T.Undefined); CheckSub(T.Number, T.Any); - CheckSub(T.Integer31, T.Number); - CheckSub(T.Integer32, T.Number); + CheckSub(T.Smi, T.Number); + CheckSub(T.Signed32, T.Number); CheckSub(T.Double, T.Number); - CheckSub(T.Integer31, T.Integer32); - CheckUnordered(T.Integer31, T.Double); - CheckUnordered(T.Integer32, T.Double); + CheckSub(T.Smi, T.Signed32); + CheckUnordered(T.Smi, T.Double); + CheckUnordered(T.Signed32, T.Double); CheckSub(T.Name, T.Any); CheckSub(T.UniqueName, T.Any); @@ -308,13 +318,18 @@ TEST(Is) { CheckUnordered(T.Array, T.Function); // Structured subtyping + CheckSub(T.None, T.ObjectClass); + CheckSub(T.None, T.ObjectConstant1); + CheckSub(T.ObjectClass, T.Any); + CheckSub(T.ObjectConstant1, T.Any); + CheckSub(T.ObjectClass, T.Object); CheckSub(T.ArrayClass, T.Object); CheckUnordered(T.ObjectClass, T.ArrayClass); - CheckSub(T.Integer31Constant, T.Integer31); - CheckSub(T.Integer31Constant, T.Integer32); - CheckSub(T.Integer31Constant, T.Number); + CheckSub(T.SmiConstant, T.Smi); + CheckSub(T.SmiConstant, T.Signed32); + CheckSub(T.SmiConstant, T.Number); CheckSub(T.ObjectConstant1, T.Object); CheckSub(T.ObjectConstant2, T.Object); CheckSub(T.ArrayConstant1, T.Object); @@ -332,7 +347,7 @@ TEST(Is) { TEST(Maybe) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); @@ -348,9 +363,9 @@ TEST(Maybe) { CheckDisjoint(T.Boolean, T.Undefined); CheckOverlap(T.Number, T.Any); - CheckOverlap(T.Integer31, T.Number); + CheckOverlap(T.Smi, T.Number); CheckOverlap(T.Double, T.Number); - CheckDisjoint(T.Integer32, T.Double); + CheckDisjoint(T.Signed32, T.Double); CheckOverlap(T.Name, T.Any); CheckOverlap(T.UniqueName, T.Any); @@ -374,16 +389,19 @@ TEST(Maybe) { CheckDisjoint(T.Object, T.Proxy); CheckDisjoint(T.Array, T.Function); + CheckOverlap(T.ObjectClass, T.Any); + CheckOverlap(T.ObjectConstant1, T.Any); + CheckOverlap(T.ObjectClass, T.Object); CheckOverlap(T.ArrayClass, T.Object); CheckOverlap(T.ObjectClass, T.ObjectClass); CheckOverlap(T.ArrayClass, T.ArrayClass); CheckDisjoint(T.ObjectClass, T.ArrayClass); - CheckOverlap(T.Integer31Constant, T.Integer31); - CheckOverlap(T.Integer31Constant, T.Integer32); - CheckOverlap(T.Integer31Constant, T.Number); - CheckDisjoint(T.Integer31Constant, T.Double); + CheckOverlap(T.SmiConstant, T.Smi); + CheckOverlap(T.SmiConstant, T.Signed32); + CheckOverlap(T.SmiConstant, T.Number); + CheckDisjoint(T.SmiConstant, T.Double); CheckOverlap(T.ObjectConstant1, T.Object); CheckOverlap(T.ObjectConstant2, T.Object); CheckOverlap(T.ArrayConstant1, T.Object); @@ -403,7 +421,7 @@ TEST(Maybe) { TEST(Union) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); @@ -422,6 +440,8 @@ TEST(Union) { CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass))); CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); + CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); + CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any); CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); @@ -437,6 +457,8 @@ TEST(Union) { CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2); + CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2)); + CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any); CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2)); @@ -453,32 +475,36 @@ TEST(Union) { CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number))); CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); + CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); - CheckSub(T.Union(T.ObjectClass, T.Integer31), T.Union(T.Object, T.Number)); + CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number)); CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); // Bitset-constant - CHECK(IsBitset(Type::Union(T.Integer31Constant, T.Number))); + CHECK(IsBitset(Type::Union(T.SmiConstant, T.Number))); CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object))); CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number))); - CheckEqual(T.Union(T.Integer31Constant, T.Number), T.Number); + CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); + CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number)); CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); - CheckSub( - T.Union(T.ObjectConstant1, T.Integer32), T.Union(T.Object, T.Number)); + CheckSub(T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); + CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); // Class-constant CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass))); CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2))); + CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); + CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); @@ -508,6 +534,9 @@ TEST(Union) { T.ObjectConstant1, T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); CheckSub( + T.None, + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); + CheckSub( T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), T.Any); CheckSub( @@ -524,6 +553,12 @@ TEST(Union) { T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), T.Union(T.ObjectClass, T.ObjectConstant1)); CheckSub( + T.None, + T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass))); + CheckSub( + T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), + T.Any); + CheckSub( T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), T.Object); CheckEqual( @@ -547,7 +582,7 @@ TEST(Union) { // Union-union CHECK(IsBitset(Type::Union( - T.Union(T.Number, T.ArrayClass), T.Union(T.Integer32, T.Array)))); + T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); CHECK(IsUnion(Type::Union( T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass)))); @@ -562,14 +597,14 @@ TEST(Union) { T.Union(T.ObjectConstant1, T.ArrayConstant2)), T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1)); CheckEqual( - T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Integer31, T.Array)), + T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)), T.Union(T.Number, T.Array)); } TEST(Intersect) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); HandlifiedTypes T(isolate); @@ -610,12 +645,12 @@ TEST(Intersect) { CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); // Bitset-constant - CHECK(IsBitset(Type::Intersect(T.Integer31, T.Number))); - CHECK(IsConstant(Type::Intersect(T.Integer31Constant, T.Number))); + CHECK(IsBitset(Type::Intersect(T.Smi, T.Number))); + CHECK(IsConstant(Type::Intersect(T.SmiConstant, T.Number))); CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object))); - CheckEqual(T.Intersect(T.Integer31, T.Number), T.Integer31); - CheckEqual(T.Intersect(T.Integer31Constant, T.Number), T.Integer31Constant); + CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi); + CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); // Class-constant @@ -642,7 +677,7 @@ TEST(Intersect) { CHECK(IsClass( Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); CHECK(IsClass( - Type::Intersect(T.Union(T.Object, T.Integer31Constant), T.ArrayClass))); + Type::Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); CHECK(IsBitset( Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); @@ -650,7 +685,7 @@ TEST(Intersect) { T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), T.ArrayClass); CheckEqual( - T.Intersect(T.ArrayClass, T.Union(T.Object, T.Integer31Constant)), + T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), T.ArrayClass); CheckEqual( T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass), @@ -660,7 +695,7 @@ TEST(Intersect) { CHECK(IsConstant(Type::Intersect( T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); CHECK(IsConstant(Type::Intersect( - T.Union(T.Number, T.ObjectClass), T.Integer31Constant))); + T.Union(T.Number, T.ObjectClass), T.SmiConstant))); CHECK(IsBitset(Type::Intersect( T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); @@ -669,28 +704,28 @@ TEST(Intersect) { T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), T.ObjectConstant1); CheckEqual( - T.Intersect(T.Integer31Constant, T.Union(T.Number, T.ObjectConstant2)), - T.Integer31Constant); + T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), + T.SmiConstant); CheckEqual( T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1), T.None); // Union-union CHECK(IsUnion(Type::Intersect( - T.Union(T.Number, T.ArrayClass), T.Union(T.Integer32, T.Array)))); + T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); CHECK(IsBitset(Type::Intersect( - T.Union(T.Number, T.ObjectClass), T.Union(T.Integer32, T.Array)))); + T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); CheckEqual( T.Intersect( T.Union(T.Number, T.ArrayClass), - T.Union(T.Integer31, T.Array)), - T.Union(T.Integer31, T.ArrayClass)); + T.Union(T.Smi, T.Array)), + T.Union(T.Smi, T.ArrayClass)); CheckEqual( T.Intersect( T.Union(T.Number, T.ObjectClass), - T.Union(T.Integer32, T.Array)), - T.Integer32); + T.Union(T.Signed32, T.Array)), + T.Signed32); CheckEqual( T.Intersect( T.Union(T.ObjectConstant2, T.ObjectConstant1), diff --git a/deps/v8/test/cctest/test-unique.cc b/deps/v8/test/cctest/test-unique.cc index 1d268580ed..0936908f12 100644 --- a/deps/v8/test/cctest/test-unique.cc +++ b/deps/v8/test/cctest/test-unique.cc @@ -36,6 +36,35 @@ using namespace v8::internal; +#define MAKE_HANDLES_AND_DISALLOW_ALLOCATION \ +Isolate* isolate = CcTest::i_isolate(); \ +Factory* factory = isolate->factory(); \ +HandleScope sc(isolate); \ +Handle<String> handles[] = { \ + factory->InternalizeUtf8String("A"), \ + factory->InternalizeUtf8String("B"), \ + factory->InternalizeUtf8String("C"), \ + factory->InternalizeUtf8String("D"), \ + factory->InternalizeUtf8String("E"), \ + factory->InternalizeUtf8String("F"), \ + factory->InternalizeUtf8String("G") \ +}; \ +DisallowHeapAllocation _disable + +#define MAKE_UNIQUES_A_B_C \ + Unique<String> A(handles[0]); \ + Unique<String> B(handles[1]); \ + Unique<String> C(handles[2]) + +#define MAKE_UNIQUES_A_B_C_D_E_F_G \ + Unique<String> A(handles[0]); \ + Unique<String> B(handles[1]); \ + Unique<String> C(handles[2]); \ + Unique<String> D(handles[3]); \ + Unique<String> E(handles[4]); \ + Unique<String> F(handles[5]); \ + Unique<String> G(handles[6]) + template <class T, class U> void CheckHashCodeEqual(Unique<T> a, Unique<U> b) { int64_t hasha = static_cast<int64_t>(a.Hashcode()); @@ -58,11 +87,9 @@ void CheckHashCodeNotEqual(Unique<T> a, Unique<U> b) { TEST(UniqueCreate) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + Handle<String> A = handles[0], B = handles[1]; - Handle<String> A = factory->InternalizeUtf8String("A"); Unique<String> HA(A); CHECK(*HA.handle() == *A); @@ -77,7 +104,6 @@ TEST(UniqueCreate) { CHECK(HA2 == HA); CHECK_EQ(*HA2.handle(), *HA.handle()); - Handle<String> B = factory->InternalizeUtf8String("B"); Unique<String> HB(B); CheckHashCodeNotEqual(HA, HB); @@ -93,11 +119,9 @@ TEST(UniqueCreate) { TEST(UniqueSubsume) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + Handle<String> A = handles[0]; - Handle<String> A = factory->InternalizeUtf8String("A"); Unique<String> HA(A); CHECK(*HA.handle() == *A); @@ -116,13 +140,8 @@ TEST(UniqueSubsume) { TEST(UniqueSet_Add) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); - - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; Zone zone(isolate); @@ -146,6 +165,104 @@ TEST(UniqueSet_Add) { } +TEST(UniqueSet_Remove) { + CcTest::InitializeVM(); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; + + Zone zone(isolate); + + UniqueSet<String>* set = new(&zone) UniqueSet<String>(); + + set->Add(A, &zone); + set->Add(B, &zone); + set->Add(C, &zone); + CHECK_EQ(3, set->size()); + + set->Remove(A); + CHECK_EQ(2, set->size()); + CHECK(!set->Contains(A)); + CHECK(set->Contains(B)); + CHECK(set->Contains(C)); + + set->Remove(A); + CHECK_EQ(2, set->size()); + CHECK(!set->Contains(A)); + CHECK(set->Contains(B)); + CHECK(set->Contains(C)); + + set->Remove(B); + CHECK_EQ(1, set->size()); + CHECK(!set->Contains(A)); + CHECK(!set->Contains(B)); + CHECK(set->Contains(C)); + + set->Remove(C); + CHECK_EQ(0, set->size()); + CHECK(!set->Contains(A)); + CHECK(!set->Contains(B)); + CHECK(!set->Contains(C)); +} + + +TEST(UniqueSet_Contains) { + CcTest::InitializeVM(); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; + + Zone zone(isolate); + + UniqueSet<String>* set = new(&zone) UniqueSet<String>(); + + CHECK_EQ(0, set->size()); + set->Add(A, &zone); + CHECK(set->Contains(A)); + CHECK(!set->Contains(B)); + CHECK(!set->Contains(C)); + + set->Add(A, &zone); + CHECK(set->Contains(A)); + CHECK(!set->Contains(B)); + CHECK(!set->Contains(C)); + + set->Add(B, &zone); + CHECK(set->Contains(A)); + CHECK(set->Contains(B)); + + set->Add(C, &zone); + CHECK(set->Contains(A)); + CHECK(set->Contains(B)); + CHECK(set->Contains(C)); +} + + +TEST(UniqueSet_At) { + CcTest::InitializeVM(); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; + + Zone zone(isolate); + + UniqueSet<String>* set = new(&zone) UniqueSet<String>(); + + CHECK_EQ(0, set->size()); + set->Add(A, &zone); + CHECK(A == set->at(0)); + + set->Add(A, &zone); + CHECK(A == set->at(0)); + + set->Add(B, &zone); + CHECK(A == set->at(0) || B == set->at(0)); + CHECK(A == set->at(1) || B == set->at(1)); + + set->Add(C, &zone); + CHECK(A == set->at(0) || B == set->at(0) || C == set->at(0)); + CHECK(A == set->at(1) || B == set->at(1) || C == set->at(1)); + CHECK(A == set->at(2) || B == set->at(2) || C == set->at(2)); +} + + template <class T> static void CHECK_SETS( UniqueSet<T>* set1, UniqueSet<T>* set2, bool expected) { @@ -158,13 +275,8 @@ static void CHECK_SETS( TEST(UniqueSet_Equals) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); - - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; Zone zone(isolate); @@ -201,13 +313,8 @@ TEST(UniqueSet_Equals) { TEST(UniqueSet_IsSubset1) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); - - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; Zone zone(isolate); @@ -241,17 +348,8 @@ TEST(UniqueSet_IsSubset1) { TEST(UniqueSet_IsSubset2) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); - - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); - Unique<String> D(factory->InternalizeUtf8String("D")); - Unique<String> E(factory->InternalizeUtf8String("E")); - Unique<String> F(factory->InternalizeUtf8String("F")); - Unique<String> G(factory->InternalizeUtf8String("G")); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C_D_E_F_G; Zone zone(isolate); @@ -293,20 +391,11 @@ TEST(UniqueSet_IsSubsetExhaustive) { const int kSetSize = 6; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C_D_E_F_G; Zone zone(isolate); - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); - Unique<String> D(factory->InternalizeUtf8String("D")); - Unique<String> E(factory->InternalizeUtf8String("E")); - Unique<String> F(factory->InternalizeUtf8String("F")); - Unique<String> G(factory->InternalizeUtf8String("G")); - Unique<String> elements[] = { A, B, C, D, E, F, G }; @@ -325,13 +414,8 @@ TEST(UniqueSet_IsSubsetExhaustive) { TEST(UniqueSet_Intersect1) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); - - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; Zone zone(isolate); @@ -371,20 +455,11 @@ TEST(UniqueSet_IntersectExhaustive) { const int kSetSize = 6; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C_D_E_F_G; Zone zone(isolate); - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); - Unique<String> D(factory->InternalizeUtf8String("D")); - Unique<String> E(factory->InternalizeUtf8String("E")); - Unique<String> F(factory->InternalizeUtf8String("F")); - Unique<String> G(factory->InternalizeUtf8String("G")); - Unique<String> elements[] = { A, B, C, D, E, F, G }; @@ -407,13 +482,8 @@ TEST(UniqueSet_IntersectExhaustive) { TEST(UniqueSet_Union1) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); - - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C; Zone zone(isolate); @@ -453,20 +523,11 @@ TEST(UniqueSet_UnionExhaustive) { const int kSetSize = 6; CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); - Factory* factory = isolate->factory(); - HandleScope sc(isolate); + MAKE_HANDLES_AND_DISALLOW_ALLOCATION; + MAKE_UNIQUES_A_B_C_D_E_F_G; Zone zone(isolate); - Unique<String> A(factory->InternalizeUtf8String("A")); - Unique<String> B(factory->InternalizeUtf8String("B")); - Unique<String> C(factory->InternalizeUtf8String("C")); - Unique<String> D(factory->InternalizeUtf8String("D")); - Unique<String> E(factory->InternalizeUtf8String("E")); - Unique<String> F(factory->InternalizeUtf8String("F")); - Unique<String> G(factory->InternalizeUtf8String("G")); - Unique<String> elements[] = { A, B, C, D, E, F, G }; diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc index feff477933..86d52fa82b 100644 --- a/deps/v8/test/cctest/test-utils.cc +++ b/deps/v8/test/cctest/test-utils.cc @@ -103,35 +103,22 @@ static const int kAreaSize = 512; void TestMemMove(byte* area1, byte* area2, - byte* area3, int src_offset, int dest_offset, int length) { for (int i = 0; i < kAreaSize; i++) { area1[i] = i & 0xFF; area2[i] = i & 0xFF; - area3[i] = i & 0xFF; } OS::MemMove(area1 + dest_offset, area1 + src_offset, length); - MoveBytes(area2 + dest_offset, area2 + src_offset, length); - memmove(area3 + dest_offset, area3 + src_offset, length); - if (memcmp(area1, area3, kAreaSize) != 0) { + memmove(area2 + dest_offset, area2 + src_offset, length); + if (memcmp(area1, area2, kAreaSize) != 0) { printf("OS::MemMove(): src_offset: %d, dest_offset: %d, length: %d\n", src_offset, dest_offset, length); for (int i = 0; i < kAreaSize; i++) { - if (area1[i] == area3[i]) continue; + if (area1[i] == area2[i]) continue; printf("diff at offset %d (%p): is %d, should be %d\n", - i, reinterpret_cast<void*>(area1 + i), area1[i], area3[i]); - } - CHECK(false); - } - if (memcmp(area2, area3, kAreaSize) != 0) { - printf("MoveBytes(): src_offset: %d, dest_offset: %d, length: %d\n", - src_offset, dest_offset, length); - for (int i = 0; i < kAreaSize; i++) { - if (area2[i] == area3[i]) continue; - printf("diff at offset %d (%p): is %d, should be %d\n", - i, reinterpret_cast<void*>(area2 + i), area2[i], area3[i]); + i, reinterpret_cast<void*>(area1 + i), area1[i], area2[i]); } CHECK(false); } @@ -142,7 +129,6 @@ TEST(MemMove) { v8::V8::Initialize(); byte* area1 = new byte[kAreaSize]; byte* area2 = new byte[kAreaSize]; - byte* area3 = new byte[kAreaSize]; static const int kMinOffset = 32; static const int kMaxOffset = 64; @@ -152,13 +138,12 @@ TEST(MemMove) { for (int src_offset = kMinOffset; src_offset <= kMaxOffset; src_offset++) { for (int dst_offset = kMinOffset; dst_offset <= kMaxOffset; dst_offset++) { for (int length = 0; length <= kMaxLength; length++) { - TestMemMove(area1, area2, area3, src_offset, dst_offset, length); + TestMemMove(area1, area2, src_offset, dst_offset, length); } } } delete[] area1; delete[] area2; - delete[] area3; } diff --git a/deps/v8/test/intl/OWNERS b/deps/v8/test/intl/OWNERS new file mode 100644 index 0000000000..9d54cbbea8 --- /dev/null +++ b/deps/v8/test/intl/OWNERS @@ -0,0 +1,2 @@ +cira@chromium.org +mnita@google.com diff --git a/deps/v8/test/intl/date-format/parse-MMMdy.js b/deps/v8/test/intl/date-format/parse-MMMdy.js index 7136527810..b23a3cde3a 100644 --- a/deps/v8/test/intl/date-format/parse-MMMdy.js +++ b/deps/v8/test/intl/date-format/parse-MMMdy.js @@ -30,19 +30,22 @@ var dtf = new Intl.DateTimeFormat(['en'], {year: 'numeric', month: 'short', - day: 'numeric'}); + day: 'numeric', + timeZone: 'America/Los_Angeles'}); // Make sure we have pattern we expect (may change in the future). assertEquals('MMM d, y', dtf.resolved.pattern); -assertEquals('Sat May 04 1974 00:00:00 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('May 4, 1974')))); +var date = dtf.v8Parse('Feb 4, 1974'); +assertEquals(1974, date.getUTCFullYear()); +assertEquals(1, date.getUTCMonth()); +assertEquals(4, date.getUTCDate()); // Missing , in the pattern. -assertEquals(undefined, dtf.v8Parse('May 4 1974')); +assertEquals(undefined, dtf.v8Parse('Feb 4 1974')); // Extra "th" after 4 in the pattern. -assertEquals(undefined, dtf.v8Parse('May 4th, 1974')); +assertEquals(undefined, dtf.v8Parse('Feb 4th, 1974')); // Wrong pattern. -assertEquals(undefined, dtf.v8Parse('5/4/1974')); +assertEquals(undefined, dtf.v8Parse('2/4/1974')); diff --git a/deps/v8/test/intl/date-format/parse-mdy.js b/deps/v8/test/intl/date-format/parse-mdy.js index e767a0b2d2..7b1a79af86 100644 --- a/deps/v8/test/intl/date-format/parse-mdy.js +++ b/deps/v8/test/intl/date-format/parse-mdy.js @@ -27,23 +27,25 @@ // Testing v8Parse method for date only. -var dtf = new Intl.DateTimeFormat(['en']); +function checkDate(date) { + assertEquals(1974, date.getUTCFullYear()); + assertEquals(1, date.getUTCMonth()); + assertEquals(4, date.getUTCDate()); +} + +var dtf = new Intl.DateTimeFormat(['en'], {timeZone: 'America/Los_Angeles'}); // Make sure we have pattern we expect (may change in the future). assertEquals('M/d/y', dtf.resolved.pattern); -assertEquals('Sat May 04 1974 00:00:00 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('5/4/74')))); -assertEquals('Sat May 04 1974 00:00:00 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('05/04/74')))); -assertEquals('Sat May 04 1974 00:00:00 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('5/04/74')))); -assertEquals('Sat May 04 1974 00:00:00 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('5/4/1974')))); - -// Month is numeric, so it fails on "May". -assertEquals(undefined, dtf.v8Parse('May 4th 1974')); +checkDate(dtf.v8Parse('2/4/74')); +checkDate(dtf.v8Parse('02/04/74')); +checkDate(dtf.v8Parse('2/04/74')); +checkDate(dtf.v8Parse('02/4/74')); +checkDate(dtf.v8Parse('2/4/1974')); +checkDate(dtf.v8Parse('02/4/1974')); +checkDate(dtf.v8Parse('2/04/1974')); +checkDate(dtf.v8Parse('02/04/1974')); -// Time is ignored from the input, since the pattern doesn't have it. -assertEquals('Sat May 04 1974 00:00:00 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('5/4/74 12:30:12')))); +// Month is numeric, so it fails on "Feb". +assertEquals(undefined, dtf.v8Parse('Feb 4th 1974')); diff --git a/deps/v8/test/intl/date-format/parse-mdyhms.js b/deps/v8/test/intl/date-format/parse-mdyhms.js index 74f7467f3d..73efb62053 100644 --- a/deps/v8/test/intl/date-format/parse-mdyhms.js +++ b/deps/v8/test/intl/date-format/parse-mdyhms.js @@ -30,22 +30,28 @@ var dtf = new Intl.DateTimeFormat(['en'], {year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', - minute: 'numeric', second: 'numeric'}); + minute: 'numeric', second: 'numeric', + timeZone: 'UTC'}); // Make sure we have pattern we expect (may change in the future). assertEquals('M/d/y h:mm:ss a', dtf.resolved.pattern); -assertEquals('Sat May 04 1974 12:30:12 GMT-0007 (PDT)', - usePDT(String(dtf.v8Parse('5/4/74 12:30:12 pm')))); +var date = dtf.v8Parse('2/4/74 12:30:42 pm'); +assertEquals(1974, date.getUTCFullYear()); +assertEquals(1, date.getUTCMonth()); +assertEquals(4, date.getUTCDate()); +assertEquals(12, date.getUTCHours()); +assertEquals(30, date.getUTCMinutes()); +assertEquals(42, date.getUTCSeconds()); // AM/PM were not specified. -assertEquals(undefined, dtf.v8Parse('5/4/74 12:30:12')); +assertEquals(undefined, dtf.v8Parse('2/4/74 12:30:12')); // Time was not specified. -assertEquals(undefined, dtf.v8Parse('5/4/74')); +assertEquals(undefined, dtf.v8Parse('2/4/74')); -// Month is numeric, so it fails on "May". -assertEquals(undefined, dtf.v8Parse('May 4th 1974')); +// Month is numeric, so it fails on "Feb". +assertEquals(undefined, dtf.v8Parse('Feb 4th 1974')); // Wrong date delimiter. -assertEquals(undefined, dtf.v8Parse('5-4-74 12:30:12 am')); +assertEquals(undefined, dtf.v8Parse('2-4-74 12:30:12 am')); diff --git a/deps/v8/test/intl/date-format/timezone-name.js b/deps/v8/test/intl/date-format/timezone-name.js new file mode 100644 index 0000000000..2ed5c1acae --- /dev/null +++ b/deps/v8/test/intl/date-format/timezone-name.js @@ -0,0 +1,53 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Tests time zone names. + +// Winter date (PST). +var winter = new Date(2013, 1, 12, 14, 42, 53, 0); + +// Summer date (PDT). +var summer = new Date(2013, 7, 12, 14, 42, 53, 0); + +// Common flags for both formatters. +var flags = { + year: 'numeric', month: 'long', day: 'numeric', + hour : '2-digit', minute : '2-digit', second : '2-digit', + timeZone: 'America/Los_Angeles' +}; + +flags.timeZoneName = "short"; +var dfs = new Intl.DateTimeFormat('en-US', flags); + +assertTrue(dfs.format(winter).indexOf('PST') !== -1); +assertTrue(dfs.format(summer).indexOf('PDT') !== -1); + +flags.timeZoneName = "long"; +var dfl = new Intl.DateTimeFormat('en-US', flags); + +assertTrue(dfl.format(winter).indexOf('Pacific Standard Time') !== -1); +assertTrue(dfl.format(summer).indexOf('Pacific Daylight Time') !== -1); diff --git a/deps/v8/test/intl/intl.status b/deps/v8/test/intl/intl.status index 34610a5d73..fc3c66b9c1 100644 --- a/deps/v8/test/intl/intl.status +++ b/deps/v8/test/intl/intl.status @@ -25,12 +25,17 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -prefix intl +[ +[ALWAYS, { + # The following tests use getDefaultTimeZone(). + 'date-format/resolved-options': [FAIL], + 'date-format/timezone': [FAIL], + 'general/v8Intl-exists': [FAIL], -# The following tests use getDefaultTimeZone(). -date-format/resolved-options: FAIL -date-format/timezone: FAIL -general/v8Intl-exists: FAIL + # TODO(jochen): The following test is flaky. + 'overrides/caching': [PASS, FAIL], -# TODO(jochen): The following test is flaky. -overrides/caching: PASS || FAIL + # BUG(2899): default locale for search fails on mac and on android. + 'collator/default-locale': [['system == macos or arch == android_arm or arch == android_ia32', FAIL]], +}], # ALWAYS +] diff --git a/deps/v8/test/intl/testcfg.py b/deps/v8/test/intl/testcfg.py index 09d29d0bee..9fc087e5f5 100644 --- a/deps/v8/test/intl/testcfg.py +++ b/deps/v8/test/intl/testcfg.py @@ -57,7 +57,6 @@ class IntlTestSuite(testsuite.TestSuite): files = [] files.append(os.path.join(self.root, "assert.js")) files.append(os.path.join(self.root, "utils.js")) - files.append(os.path.join(self.root, "date-format", "utils.js")) files.append(os.path.join(self.root, testcase.path + self.suffix())) flags += files diff --git a/deps/v8/test/message/message.status b/deps/v8/test/message/message.status index 441f8edd0d..234bf0f35c 100644 --- a/deps/v8/test/message/message.status +++ b/deps/v8/test/message/message.status @@ -25,7 +25,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -prefix message - -# All tests in the bug directory are expected to fail. -bugs/*: FAIL +[ +[ALWAYS, { + # All tests in the bug directory are expected to fail. + 'bugs/*': [FAIL], +}], # ALWAYS +] diff --git a/deps/v8/test/message/paren_in_arg_string.out b/deps/v8/test/message/paren_in_arg_string.out index 3bc978b965..0ed59bab1e 100644 --- a/deps/v8/test/message/paren_in_arg_string.out +++ b/deps/v8/test/message/paren_in_arg_string.out @@ -2,5 +2,5 @@ var paren_in_arg_string_bad = new Function(')', 'return;'); ^ SyntaxError: Function arg string contains parenthesis - at Function (<anonymous>) - at *%(basename)s:29:31
\ No newline at end of file + at Function (native) + at *%(basename)s:29:31 diff --git a/deps/v8/test/message/testcfg.py b/deps/v8/test/message/testcfg.py index 411f71ceb2..e4f3f5587a 100644 --- a/deps/v8/test/message/testcfg.py +++ b/deps/v8/test/message/testcfg.py @@ -35,6 +35,7 @@ from testrunner.objects import testcase FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") +INVALID_FLAGS = ["--enable-slow-asserts"] class MessageTestSuite(testsuite.TestSuite): @@ -62,6 +63,7 @@ class MessageTestSuite(testsuite.TestSuite): for match in flags_match: result += match.strip().split() result += context.mode_flags + result = [x for x in result if x not in INVALID_FLAGS] result.append(os.path.join(self.root, testcase.path + ".js")) return testcase.flags + result diff --git a/deps/v8/test/mjsunit/allocation-site-info.js b/deps/v8/test/mjsunit/allocation-site-info.js index 5f6817b6d3..f32344a405 100644 --- a/deps/v8/test/mjsunit/allocation-site-info.js +++ b/deps/v8/test/mjsunit/allocation-site-info.js @@ -35,6 +35,11 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. +// Reset the GC stress mode to be off. Needed because AllocationMementos only +// live for one gc, so a gc that happens in certain fragile areas of the test +// can break assumptions. +%SetFlags("--gc-interval=-1") + // support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); support_smi_only_arrays = true; @@ -150,17 +155,14 @@ if (support_smi_only_arrays) { // Verify that we will not pretransition the double->fast path. obj = fastliteralcase(get_standard_literal(), "elliot"); assertKind(elements_kind.fast, obj); - // This fails until we turn off optimistic transitions to the - // most general elements kind seen on keyed stores. It's a goal - // to turn it off, but for now we need it. - // obj = fastliteralcase(3); - // assertKind(elements_kind.fast_double, obj); + obj = fastliteralcase(get_standard_literal(), 3); + assertKind(elements_kind.fast, obj); // Make sure this works in crankshafted code too. %OptimizeFunctionOnNextCall(get_standard_literal); get_standard_literal(); obj = get_standard_literal(); - assertKind(elements_kind.fast_double, obj); + assertKind(elements_kind.fast, obj); function fastliteralcase_smifast(value) { var literal = [1, 2, 3, 4]; @@ -231,16 +233,14 @@ if (support_smi_only_arrays) { obj = newarraycase_length_smidouble(2); assertKind(elements_kind.fast_double, obj); - // Try to continue the transition to fast object, but - // we will not pretransition from double->fast, because - // it may hurt performance ("poisoning"). + // Try to continue the transition to fast object. This won't work for + // constructed arrays because constructor dispatch is done on the + // elements kind, and a DOUBLE array constructor won't create an allocation + // memento. obj = newarraycase_length_smidouble("coates"); assertKind(elements_kind.fast, obj); - obj = newarraycase_length_smidouble(2.5); - // However, because of optimistic transitions, we will - // transition to the most general kind of elements kind found, - // therefore I can't count on this assert yet. - // assertKind(elements_kind.fast_double, obj); + obj = newarraycase_length_smidouble(2); + assertKind(elements_kind.fast_double, obj); function newarraycase_length_smiobj(value) { var a = new Array(3); @@ -379,4 +379,114 @@ if (support_smi_only_arrays) { instanceof_check(realmBArray); assertUnoptimized(instanceof_check); + + // Case: make sure nested arrays benefit from allocation site feedback as + // well. + (function() { + // Make sure we handle nested arrays + function get_nested_literal() { + var literal = [[1,2,3,4], [2], [3]]; + return literal; + } + + obj = get_nested_literal(); + assertKind(elements_kind.fast, obj); + obj[0][0] = 3.5; + obj[2][0] = "hello"; + obj = get_nested_literal(); + assertKind(elements_kind.fast_double, obj[0]); + assertKind(elements_kind.fast_smi_only, obj[1]); + assertKind(elements_kind.fast, obj[2]); + + // A more complex nested literal case. + function get_deep_nested_literal() { + var literal = [[1], [[2], "hello"], 3, [4]]; + return literal; + } + + obj = get_deep_nested_literal(); + assertKind(elements_kind.fast_smi_only, obj[1][0]); + obj[0][0] = 3.5; + obj[1][0][0] = "goodbye"; + assertKind(elements_kind.fast_double, obj[0]); + assertKind(elements_kind.fast, obj[1][0]); + + obj = get_deep_nested_literal(); + assertKind(elements_kind.fast_double, obj[0]); + assertKind(elements_kind.fast, obj[1][0]); + })(); + + + // Make sure object literals with array fields benefit from the type feedback + // that allocation mementos provide. + (function() { + // A literal in an object + function get_object_literal() { + var literal = { + array: [1,2,3], + data: 3.5 + }; + return literal; + } + + obj = get_object_literal(); + assertKind(elements_kind.fast_smi_only, obj.array); + obj.array[1] = 3.5; + assertKind(elements_kind.fast_double, obj.array); + obj = get_object_literal(); + assertKind(elements_kind.fast_double, obj.array); + + function get_nested_object_literal() { + var literal = { + array: [[1],[2],[3]], + data: 3.5 + }; + return literal; + } + + obj = get_nested_object_literal(); + assertKind(elements_kind.fast, obj.array); + assertKind(elements_kind.fast_smi_only, obj.array[1]); + obj.array[1][0] = 3.5; + assertKind(elements_kind.fast_double, obj.array[1]); + obj = get_nested_object_literal(); + assertKind(elements_kind.fast_double, obj.array[1]); + + %OptimizeFunctionOnNextCall(get_nested_object_literal); + get_nested_object_literal(); + obj = get_nested_object_literal(); + assertKind(elements_kind.fast_double, obj.array[1]); + + // Make sure we handle nested arrays + function get_nested_literal() { + var literal = [[1,2,3,4], [2], [3]]; + return literal; + } + + obj = get_nested_literal(); + assertKind(elements_kind.fast, obj); + obj[0][0] = 3.5; + obj[2][0] = "hello"; + obj = get_nested_literal(); + assertKind(elements_kind.fast_double, obj[0]); + assertKind(elements_kind.fast_smi_only, obj[1]); + assertKind(elements_kind.fast, obj[2]); + + // A more complex nested literal case. + function get_deep_nested_literal() { + var literal = [[1], [[2], "hello"], 3, [4]]; + return literal; + } + + obj = get_deep_nested_literal(); + assertKind(elements_kind.fast_smi_only, obj[1][0]); + obj[0][0] = 3.5; + obj[1][0][0] = "goodbye"; + assertKind(elements_kind.fast_double, obj[0]); + assertKind(elements_kind.fast, obj[1][0]); + + obj = get_deep_nested_literal(); + assertKind(elements_kind.fast_double, obj[0]); + assertKind(elements_kind.fast, obj[1][0]); + })(); } diff --git a/deps/v8/test/mjsunit/array-functions-prototype-misc.js b/deps/v8/test/mjsunit/array-functions-prototype-misc.js index 0543c323b6..74dc9a6be0 100644 --- a/deps/v8/test/mjsunit/array-functions-prototype-misc.js +++ b/deps/v8/test/mjsunit/array-functions-prototype-misc.js @@ -31,7 +31,7 @@ * should work on other objects too, so we test that too. */ -var LARGE = 40000000; +var LARGE = 4000000; var VERYLARGE = 4000000000; // Nicer for firefox 1.5. Unless you uncomment the following two lines, @@ -276,7 +276,7 @@ for (var i = 0; i < a.length; i += 1000) { } // Take something near the end of the array. -for (var i = 0; i < 100; i++) { +for (var i = 0; i < 10; i++) { var top = a.splice(LARGE, 5); assertEquals(5, top.length); assertEquals(LARGE, top[0]); diff --git a/deps/v8/test/mjsunit/array-literal-feedback.js b/deps/v8/test/mjsunit/array-literal-feedback.js index 3378394d90..d2245c62a2 100644 --- a/deps/v8/test/mjsunit/array-literal-feedback.js +++ b/deps/v8/test/mjsunit/array-literal-feedback.js @@ -44,6 +44,42 @@ if (support_smi_only_arrays) { print("Tests do NOT include smi-only arrays."); } +var elements_kind = { + fast_smi_only : 'fast smi only elements', + fast : 'fast elements', + fast_double : 'fast double elements', + dictionary : 'dictionary elements', + external_byte : 'external byte elements', + external_unsigned_byte : 'external unsigned byte elements', + external_short : 'external short elements', + external_unsigned_short : 'external unsigned short elements', + external_int : 'external int elements', + external_unsigned_int : 'external unsigned int elements', + external_float : 'external float elements', + external_double : 'external double elements', + external_pixel : 'external pixel elements' +} + +function getKind(obj) { + if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only; + if (%HasFastObjectElements(obj)) return elements_kind.fast; + if (%HasFastDoubleElements(obj)) return elements_kind.fast_double; + if (%HasDictionaryElements(obj)) return elements_kind.dictionary; +} + +function isHoley(obj) { + if (%HasFastHoleyElements(obj)) return true; + return false; +} + +function assertKind(expected, obj, name_opt) { + if (!support_smi_only_arrays && + expected == elements_kind.fast_smi_only) { + expected = elements_kind.fast; + } + assertEquals(expected, getKind(obj), name_opt); +} + if (support_smi_only_arrays) { function get_literal(x) { @@ -72,4 +108,19 @@ if (support_smi_only_arrays) { b = get_literal(3); assertTrue(%HasFastDoubleElements(b)); assertOptimized(get_literal); + + + // Test: make sure allocation site information is updated through a + // transition from SMI->DOUBLE->FAST + (function() { + function bar(a, b, c) { + return [a, b, c]; + } + + a = bar(1, 2, 3); + a[0] = 3.5; + a[1] = 'hi'; + b = bar(1, 2, 3); + assertKind(elements_kind.fast, b); + })(); } diff --git a/deps/v8/test/mjsunit/big-array-literal.js b/deps/v8/test/mjsunit/big-array-literal.js index 9f0617989c..13f91f855e 100644 --- a/deps/v8/test/mjsunit/big-array-literal.js +++ b/deps/v8/test/mjsunit/big-array-literal.js @@ -92,16 +92,25 @@ for (var i = 0; i < sizes.length; i++) { testLiteral(sizes[i], true); } + +function checkExpectedException(e) { + assertInstanceof(e, RangeError); + assertTrue(e.message.indexOf("Maximum call stack size exceeded") >= 0); +} + + function testLiteralAndCatch(size) { var big_enough = false; try { testLiteral(size, false); } catch (e) { + checkExpectedException(e); big_enough = true; } try { testLiteral(size, true); } catch (e) { + checkExpectedException(e); big_enough = true; } return big_enough; diff --git a/deps/v8/test/mjsunit/big-object-literal.js b/deps/v8/test/mjsunit/big-object-literal.js index c937f54de1..92c6ab7b7b 100644 --- a/deps/v8/test/mjsunit/big-object-literal.js +++ b/deps/v8/test/mjsunit/big-object-literal.js @@ -92,16 +92,25 @@ for (var i = 0; i < sizes.length; i++) { testLiteral(sizes[i], true); } + +function checkExpectedException(e) { + assertInstanceof(e, RangeError); + assertTrue(e.message.indexOf("Maximum call stack size exceeded") >= 0); +} + + function testLiteralAndCatch(size) { var big_enough = false; try { testLiteral(size, false); } catch (e) { + checkExpectedException(e); big_enough = true; } try { testLiteral(size, true); } catch (e) { + checkExpectedException(e); big_enough = true; } return big_enough; diff --git a/deps/v8/test/mjsunit/bitwise-operations-bools.js b/deps/v8/test/mjsunit/bitwise-operations-bools.js new file mode 100644 index 0000000000..6c7da110b0 --- /dev/null +++ b/deps/v8/test/mjsunit/bitwise-operations-bools.js @@ -0,0 +1,94 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Test bitwise operations with booleans. + +var t = 1; + +function testFalseLeftHandSide() { + var b; + if (t) b = false; + assertEquals(b | 1, 1); + assertEquals(b & 1, 0); + assertEquals(b ^ 1, 1); + assertEquals(b << 1, 0); + assertEquals(b >> 1, 0); + assertEquals(b >>> 1, 0); +} + +function testFalseRightHandSide() { + if (t) b = false; + assertEquals(1 | b, 1); + assertEquals(1 & b, 0); + assertEquals(1 ^ b, 1); + assertEquals(1 << b, 1); + assertEquals(1 >> b, 1); + assertEquals(1 >>> b, 1); +} + +function testTrueLeftHandSide() { + if (t) b = true; + assertEquals(b | 1, 1); + assertEquals(b & 1, 1); + assertEquals(b ^ 1, 0); + assertEquals(b << 1, 2); + assertEquals(b >> 1, 0); + assertEquals(b >>> 1, 0); +} + +function testTrueRightHandSide() { + if (t) b = true; + assertEquals(1 | b, 1); + assertEquals(1 & b, 1); + assertEquals(1 ^ b, 0); + assertEquals(1 << b, 2); + assertEquals(1 >> b, 0); + assertEquals(1 >>> b, 0); +} + +function testBothSides() { + if (t) a = true; + if (t) b = false; + assertEquals(a | b, 1); + assertEquals(a & b, 0); + assertEquals(a ^ b, 1); + assertEquals(a << b, 1); + assertEquals(a >> b, 1); + assertEquals(a >>> b, 1); +} + + +testFalseLeftHandSide(); +testFalseRightHandSide(); +testTrueLeftHandSide(); +testTrueRightHandSide(); +testFalseLeftHandSide(); +testFalseRightHandSide(); +testTrueLeftHandSide(); +testTrueRightHandSide(); +testBothSides(); +testBothSides(); diff --git a/deps/v8/test/mjsunit/compare-known-objects.js b/deps/v8/test/mjsunit/compare-known-objects.js new file mode 100644 index 0000000000..afffc07014 --- /dev/null +++ b/deps/v8/test/mjsunit/compare-known-objects.js @@ -0,0 +1,65 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Test CompareIC stubs for normal and strict equality comparison of known +// objects in slow mode. These objects share the same map even though they +// might have completely different properties. + +function eq(a, b) { + return a == b; +} + +function eq_strict(a, b) { + return a === b; +} + +function test(a, b) { + // Check CompareIC for equality of known objects. + assertTrue(eq(a, a)); + assertTrue(eq(b, b)); + assertFalse(eq(a, b)); + // Check CompareIC for strict equality of known objects. + assertTrue(eq_strict(a, a)); + assertTrue(eq_strict(b, b)); + assertFalse(eq_strict(a, b)); +} + +function O(){}; +O.prototype.t = function() {} + +var obj1 = new O; +var obj2 = new O; + +// Test original objects. +assertTrue(%HaveSameMap(obj1, obj2)); +test(obj1, obj2); + +// Test after adding property to first object. +obj1.x = 1; +test(obj1, obj2); diff --git a/deps/v8/test/mjsunit/compare-objects.js b/deps/v8/test/mjsunit/compare-objects.js new file mode 100644 index 0000000000..fb31203b74 --- /dev/null +++ b/deps/v8/test/mjsunit/compare-objects.js @@ -0,0 +1,108 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Test CompareIC stubs for normal and strict equality comparison of known +// objects in hydrogen. + +function lt(a, b) { + return a < b; +} + +function gt(a, b) { + return a > b; +} + +function eq(a, b) { + return a == b; +} + +function eq_strict(a, b) { + return a === b; +} + +function test(a, b, less, greater) { + // Check CompareIC for equality of known objects. + assertTrue(eq(a, a)); + assertTrue(eq(b, b)); + assertFalse(eq(a, b)); + assertTrue(eq_strict(a, a)); + assertTrue(eq_strict(b, b)); + assertFalse(eq_strict(a, b)); + assertEquals(lt(a, b), less); + assertEquals(gt(a, b), greater); + assertEquals(lt(b, a), greater); + assertEquals(gt(b, a), less); +} + +var obj1 = {toString: function() {return "1";}}; +var obj2 = {toString: function() {return "2";}}; + +var less = obj1 < obj2; +var greater = obj1 > obj2; + +test(obj1, obj2, less, greater); +test(obj1, obj2, less, greater); +test(obj1, obj2, less, greater); +%OptimizeFunctionOnNextCall(test); +test(obj1, obj2, less, greater); +test(obj1, obj2, less, greater); + +obj1.x = 1; +test(obj1, obj2, less, greater); + +obj2.y = 2; +test(obj1, obj2, less, greater); + +var obj1 = {test: 3}; +var obj2 = {test2: 3}; + +var less = obj1 < obj2; +var greater = obj1 > obj2; + +test(obj1, obj2, less, greater); +test(obj1, obj2, less, greater); +test(obj1, obj2, less, greater); +%OptimizeFunctionOnNextCall(test); +test(obj1, obj2, less, greater); +test(obj1, obj2, less, greater); + +obj1.toString = function() {return "1"}; +var less = obj1 < obj2; +var greater = obj1 > obj2; +test(obj1, obj2, less, greater); +%OptimizeFunctionOnNextCall(test); +test(obj1, obj2, less, greater); + +obj2.toString = function() {return "2"}; +var less = true; +var greater = false; + +test(obj1, obj2, less, greater); +obj2.y = 2; +test(obj1, obj2, less, greater); diff --git a/deps/v8/test/mjsunit/parallel-invalidate-transition-map.js b/deps/v8/test/mjsunit/compiler/concurrent-invalidate-transition-map.js index 9a5d31003f..699534f665 100644 --- a/deps/v8/test/mjsunit/parallel-invalidate-transition-map.js +++ b/deps/v8/test/mjsunit/compiler/concurrent-invalidate-transition-map.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --track-fields --track-double-fields --allow-natives-syntax -// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100 +// Flags: --concurrent-recompilation --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -49,9 +49,13 @@ add_field(new_object()); %OptimizeFunctionOnNextCall(add_field, "concurrent"); var o = new_object(); -// Trigger optimization in the background thread. +// Kick off recompilation. add_field(o); -// Invalidate transition map while optimization is underway. +// Invalidate transition map after compile graph has been created. o.c = 2.2; +// In the mean time, concurrent recompiling is still blocked. +assertUnoptimized(add_field, "no sync"); +// Let concurrent recompilation proceed. +%UnblockConcurrentRecompilation(); // Sync with background thread to conclude optimization that bailed out. assertUnoptimized(add_field, "sync"); diff --git a/deps/v8/test/mjsunit/compiler/parallel-proto-change.js b/deps/v8/test/mjsunit/compiler/concurrent-proto-change.js index 7602279893..e126465a95 100644 --- a/deps/v8/test/mjsunit/compiler/parallel-proto-change.js +++ b/deps/v8/test/mjsunit/compiler/concurrent-proto-change.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax -// Flags: --concurrent-recompilation --concurrent-recompilation-delay=50 +// Flags: --concurrent-recompilation --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -43,12 +43,14 @@ assertEquals(1, f(o)); // Mark for concurrent optimization. %OptimizeFunctionOnNextCall(f, "concurrent"); -// Trigger optimization in the background thread. +// Kick off recompilation. assertEquals(1, f(o)); -// While concurrent recompilation is running, optimization not yet done. -assertUnoptimized(f, "no sync"); -// Change the prototype chain during optimization to trigger map invalidation. +// Change the prototype chain after compile graph has been created. o.__proto__.__proto__ = { bar: function() { return 2; } }; +// At this point, concurrent recompilation thread has not yet done its job. +assertUnoptimized(f, "no sync"); +// Let the background thread proceed. +%UnblockConcurrentRecompilation(); // Optimization eventually bails out due to map dependency. assertUnoptimized(f, "sync"); assertEquals(2, f(o)); diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-representation.js b/deps/v8/test/mjsunit/compiler/escape-analysis-representation.js new file mode 100644 index 0000000000..8e21a36b40 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/escape-analysis-representation.js @@ -0,0 +1,73 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --use-escape-analysis --max-opt-count=100 + +// This tests that captured objects materialized through the deoptimizer +// have field descriptors with a representation matching the values that +// have actually been stored in the object. + +var values = [ function() { return {}; }, + function() { return 23; }, + function() { return 4.2; } ]; + +function constructor(value_track) { + this.x = value_track(); +} + +function access(value_track, value_break, deopt) { + var o = new constructor(value_track); + o.x = value_break; + deopt.deopt + assertEquals(value_break, o.x); +} + +function test(value_track, value_break) { + var deopt = { deopt:false }; + + // Warm-up field tracking to a certain representation. + access(value_track, value_track(), deopt); + access(value_track, value_track(), deopt); + %OptimizeFunctionOnNextCall(access); + access(value_track, value_track(), deopt); + + // Deoptimize on a run with a different representation. + delete deopt.deopt; + access(value_track, value_break(), deopt); + + // Clear type feedback of the access function for next run. + %ClearFunctionTypeFeedback(access); + + // Also make sure the initial map of the constructor is reset. + constructor.prototype = {}; +} + +for (var i = 0; i < values.length; i++) { + for (var j = 0; j < values.length; j++) { + test(values[i], values[j]) + } +} diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis.js b/deps/v8/test/mjsunit/compiler/escape-analysis.js index 74e638a538..dccc476925 100644 --- a/deps/v8/test/mjsunit/compiler/escape-analysis.js +++ b/deps/v8/test/mjsunit/compiler/escape-analysis.js @@ -271,3 +271,73 @@ %OptimizeFunctionOnNextCall(oob); assertEquals(7, oob(cons2, true)); })(); + + +// Test non-shallow nested graph of captured objects. +(function testDeep() { + var deopt = { deopt:false }; + function constructor1() { + this.x = 23; + } + function constructor2(nested) { + this.a = 17; + this.b = nested; + this.c = 42; + } + function deep() { + var o1 = new constructor1(); + var o2 = new constructor2(o1); + assertEquals(17, o2.a); + assertEquals(23, o2.b.x); + assertEquals(42, o2.c); + o1.x = 99; + deopt.deopt; + assertEquals(99, o1.x); + assertEquals(99, o2.b.x); + } + deep(); deep(); + %OptimizeFunctionOnNextCall(deep); + deep(); deep(); + delete deopt.deopt; + deep(); deep(); +})(); + + +// Test materialization of a field that requires a Smi value. +(function testSmiField() { + var deopt = { deopt:false }; + function constructor() { + this.x = 1; + } + function field(x) { + var o = new constructor(); + o.x = x; + deopt.deopt + assertEquals(x, o.x); + } + field(1); field(2); + %OptimizeFunctionOnNextCall(field); + field(3); field(4); + delete deopt.deopt; + field(5.5); field(6.5); +})(); + + +// Test materialization of a field that requires a heap object value. +(function testHeapObjectField() { + var deopt = { deopt:false }; + function constructor() { + this.x = {}; + } + function field(x) { + var o = new constructor(); + o.x = x; + deopt.deopt + assertEquals(x, o.x); + } + field({}); field({}); + %OptimizeFunctionOnNextCall(field); + field({}); field({}); + delete deopt.deopt; + field(1); field(2); +})(); diff --git a/deps/v8/test/mjsunit/compiler/expression-trees.js b/deps/v8/test/mjsunit/compiler/expression-trees.js index fac6b4cb65..0d971a95b2 100644 --- a/deps/v8/test/mjsunit/compiler/expression-trees.js +++ b/deps/v8/test/mjsunit/compiler/expression-trees.js @@ -55,46 +55,43 @@ function makeTrees(op, leaves) { } } -// All 429 possible bitwise OR trees with eight leaves. -var identifiers = ['a','b','c','d','e','f','g','h']; +// All possible bitwise OR trees with six leaves, i.e. CatalanNumber[5] = 42, +// see http://mathworld.wolfram.com/CatalanNumber.html. +var identifiers = ['a','b','c','d','e','f']; var or_trees = makeTrees("|", identifiers); var and_trees = makeTrees("&", identifiers); -// Set up leaf masks to set 8 least-significant bits. +// Set up leaf masks to set 6 least-significant bits. var a = 1 << 0; var b = 1 << 1; var c = 1 << 2; var d = 1 << 3; var e = 1 << 4; var f = 1 << 5; -var g = 1 << 6; -var h = 1 << 7; for (var i = 0; i < or_trees.length; ++i) { - for (var j = 0; j < 8; ++j) { + for (var j = 0; j < 6; ++j) { var or_fun = new Function("return " + or_trees[i]); - if (j == 0) assertEquals(255, or_fun()); + if (j == 0) assertEquals(63, or_fun()); // Set the j'th variable to a string to force a bailout. eval(identifiers[j] + "+= ''"); - assertEquals(255, or_fun()); + assertEquals(63, or_fun()); // Set it back to a number for the next iteration. eval(identifiers[j] + "= +" + identifiers[j]); } } -// Set up leaf masks to clear 8 least-significant bits. -a ^= 255; -b ^= 255; -c ^= 255; -d ^= 255; -e ^= 255; -f ^= 255; -g ^= 255; -h ^= 255; +// Set up leaf masks to clear 6 least-significant bits. +a ^= 63; +b ^= 63; +c ^= 63; +d ^= 63; +e ^= 63; +f ^= 63; for (i = 0; i < and_trees.length; ++i) { - for (var j = 0; j < 8; ++j) { + for (var j = 0; j < 6; ++j) { var and_fun = new Function("return " + and_trees[i]); if (j == 0) assertEquals(0, and_fun()); diff --git a/deps/v8/test/mjsunit/compiler/load-elimination-global.js b/deps/v8/test/mjsunit/compiler/load-elimination-global.js new file mode 100644 index 0000000000..9caaa9f718 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/load-elimination-global.js @@ -0,0 +1,196 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --load-elimination + +// Test global load elimination of redundant loads and stores. + +var X = true; // For forcing branches. +X = false; +X = true; +X = false; + +function B(x, y) { + this.x = x; + this.y = y; + return this; +} + +function test_load() { + var a = new B(1, 2); + var f = a.x + a.x; + if (false) ; + return f + a.x + a.x; +} + +function test_load2() { + var a = new B(1, 2); + var f = a.x + a.x; + if (true) ; + return f + a.x + a.x; +} + +function test_store_load() { + var a = new B(1, 2); + a.x = 4; + var b = X ? a.x : a.x; + return b + a.x; +} + +function test_store_load2() { + var a = new B(1, 2); + var c = 6; + if (X) a.x = c; + else a.x = c; + return a.x + a.x; +} + +function test_nonaliasing_store1() { + var a = new B(2, 3), b = new B(3, 4); + if (X) ; + b.x = 4; + if (X) ; + var f = a.x; + if (X) ; + b.x = 5; + if (X) ; + var g = a.x; + if (X) ; + b.x = 6; + if (X) ; + var h = a.x; + if (X) ; + b.x = 7; + if (X) ; + return f + g + h + a.x; +} + +function test_loop(x) { + var a = new B(2, 3); + var v = a.x; + var total = v; + var i = 0; + while (i++ < 10) { + total = a.x; + a.y = 4; + } + return total; +} + +function test_loop2(x) { + var a = new B(2, 3); + var v = a.x; + var total = v; + var i = 0; + while (i++ < 10) { + total = a.x; // a.x not affected by loop + a.y = 4; + + var j = 0; + while (j++ < 10) { + total = a.x; // a.x not affected by loop + a.y = 5; + } + + total = a.x; + a.y = 6; + + j = 0; + while (j++ < 10) { + total = a.x; // a.x not affected by loop + a.y = 7; + } + } + return total; +} + +function killall() { + try { } catch(e) { } +} + +%NeverOptimizeFunction(killall); + +function test_store_load_kill() { + var a = new B(1, 2); + if (X) ; + a.x = 4; + if (X) ; + var f = a.x; + if (X) ; + a.x = 5; + if (X) ; + var g = a.x; + if (X) ; + killall(); + if (X) ; + a.x = 6; + if (X) ; + var h = a.x; + if (X) ; + a.x = 7; + if (X) ; + return f + g + h + a.x; +} + +function test_store_store() { + var a = new B(6, 7); + if (X) ; + a.x = 7; + if (X) ; + a.x = 7; + if (X) ; + a.x = 7; + if (X) ; + a.x = 7; + if (X) ; + return a.x; +} + +function test(x, f) { + X = true; + assertEquals(x, f()); + assertEquals(x, f()); + X = false; + assertEquals(x, f()); + assertEquals(x, f()); + X = true; + %OptimizeFunctionOnNextCall(f); + assertEquals(x, f()); + assertEquals(x, f()); + X = false; + assertEquals(x, f()); + assertEquals(x, f()); +} + +test(4, test_load); +test(8, test_store_load); +test(12, test_store_load2); +test(8, test_nonaliasing_store1); +test(22, test_store_load_kill); +test(7, test_store_store); +test(2, test_loop); +test(2, test_loop2); diff --git a/deps/v8/test/mjsunit/compiler/load-elimination-osr.js b/deps/v8/test/mjsunit/compiler/load-elimination-osr.js new file mode 100644 index 0000000000..a57fe173ee --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/load-elimination-osr.js @@ -0,0 +1,65 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --load-elimination + +// Test global load elimination in the presence of OSR compilation. + +function It(x, y) { } + +function foo_osr(x, limit) { + var o = new It(); + o.x = x; + o.y = x; + for (var i = 0; i < limit; i++) { + o.y += o.x; // Load of x cannot be hoisted due to OSR. + } + + return o.y; +} + +assertEquals(22, foo_osr(11, 1)); +assertEquals(24, foo_osr(12, 1)); +assertEquals(1300013, foo_osr(13, 100000)); + + +function foo_hot(x, limit) { + var o = new It(); + o.x = x; + o.y = x; + for (var i = 0; i < limit; i++) { + o.y += o.x; // Load of x can be hoisted without OSR. + } + + return o.y; +} + +assertEquals(22, foo_hot(11, 1)); +assertEquals(24, foo_hot(12, 1)); +%OptimizeFunctionOnNextCall(foo_hot); +assertEquals(32, foo_hot(16, 1)); +assertEquals(1300013, foo_hot(13, 100000)); diff --git a/deps/v8/test/mjsunit/compiler/load-elimination.js b/deps/v8/test/mjsunit/compiler/load-elimination.js new file mode 100644 index 0000000000..e019508c65 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/load-elimination.js @@ -0,0 +1,106 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --load-elimination + +// Test local load elimination of redundant loads and stores. + +function B(x, y) { + this.x = x; + this.y = y; + return this; +} + +function test_load() { + var a = new B(1, 2); + return a.x + a.x + a.x + a.x; +} + +function test_store_load() { + var a = new B(1, 2); + a.x = 4; + var f = a.x; + a.x = 5; + var g = a.x; + a.x = 6; + var h = a.x; + a.x = 7; + return f + g + h + a.x; +} + +function test_nonaliasing_store1() { + var a = new B(2, 3), b = new B(3, 4); + b.x = 4; + var f = a.x; + b.x = 5; + var g = a.x; + b.x = 6; + var h = a.x; + b.x = 7; + return f + g + h + a.x; +} + +function killall() { + try { } catch(e) { } +} + +%NeverOptimizeFunction(killall); + +function test_store_load_kill() { + var a = new B(1, 2); + a.x = 4; + var f = a.x; + a.x = 5; + var g = a.x; + killall(); + a.x = 6; + var h = a.x; + a.x = 7; + return f + g + h + a.x; +} + +function test_store_store() { + var a = new B(6, 7); + a.x = 7; + a.x = 7; + a.x = 7; + a.x = 7; + return a.x; +} + +function test(x, f) { + assertEquals(x, f()); + assertEquals(x, f()); + %OptimizeFunctionOnNextCall(f); + assertEquals(x, f()); +} + +test(4, test_load); +test(22, test_store_load); +test(8, test_nonaliasing_store1); +test(22, test_store_load_kill); +test(7, test_store_store); diff --git a/deps/v8/test/mjsunit/manual-parallel-recompile.js b/deps/v8/test/mjsunit/compiler/manual-concurrent-recompile.js index 0a0e61d524..b2b63988ba 100644 --- a/deps/v8/test/mjsunit/manual-parallel-recompile.js +++ b/deps/v8/test/mjsunit/compiler/manual-concurrent-recompile.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --expose-gc -// Flags: --concurrent-recompilation --concurrent-recompilation-delay=50 +// Flags: --concurrent-recompilation --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -55,10 +55,13 @@ assertUnoptimized(g); %OptimizeFunctionOnNextCall(f, "concurrent"); %OptimizeFunctionOnNextCall(g, "concurrent"); -f(g(2)); // Trigger optimization. +f(g(2)); // Kick off recompilation. -assertUnoptimized(f, "no sync"); // Not yet optimized while background thread -assertUnoptimized(g, "no sync"); // is running. +assertUnoptimized(f, "no sync"); // Not yet optimized since recompilation +assertUnoptimized(g, "no sync"); // is still blocked. + +// Let concurrent recompilation proceed. +%UnblockConcurrentRecompilation(); assertOptimized(f, "sync"); // Optimized once we sync with the assertOptimized(g, "sync"); // background thread. diff --git a/deps/v8/test/mjsunit/compiler/osr-alignment.js b/deps/v8/test/mjsunit/compiler/osr-alignment.js new file mode 100644 index 0000000000..30d72d0614 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/osr-alignment.js @@ -0,0 +1,86 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --use-osr + +function f1() { + var sum = 0; + for (var i = 0; i < 1000000; i++) { + var x = i + 2; + var y = x + 5; + var z = y + 3; + sum += z; + } + return sum; +} + +function f2() { + var sum = 0; + for (var i = 0; i < 1000000; i++) { + var x = i + 2; + var y = x + 5; + var z = y + 3; + sum += z; + } + return sum; +} + +function f3() { + var sum = 0; + for (var i = 0; i < 1000000; i++) { + var x = i + 2; + var y = x + 5; + var z = y + 3; + sum += z; + } + return sum; +} + +function test1() { + var j = 11; + for (var i = 0; i < 2; i++) { + assertEquals(500009500000, f1()); + } +} + +function test2() { + for (var i = 0; i < 2; i++) { + var j = 11, k = 12; + assertEquals(500009500000, f2()); + } +} + +function test3() { + for (var i = 0; i < 2; i++) { + var j = 11, k = 13, m = 14; + assertEquals(500009500000, f3()); + } +} + +test1(); +test2(); +test3(); diff --git a/deps/v8/test/mjsunit/compiler/rotate.js b/deps/v8/test/mjsunit/compiler/rotate.js index 14fe9da3e6..2f4bc5a967 100644 --- a/deps/v8/test/mjsunit/compiler/rotate.js +++ b/deps/v8/test/mjsunit/compiler/rotate.js @@ -222,3 +222,89 @@ for (var i = 0; i <= 100; i++) { assertEquals(1 << ((i % 32)), ROR4(1, i)); } +//--------------------------------------------------------- +// add test cases for constant operand +//--------------------------------------------------------- +// constant operand: 20 +function ROR1_sa20(x) { + return (x >>> 20) | (x << 12); +} + +function ROR2_sa20(x) { + return (x >>> 12) | (x << 20); +} + +function ROR3_sa20(x, sa) { + return (x << 12) | (x >>> 20); +} + +function ROR4_sa20(x) { + return (x << 20) | (x >>> 12); +} + +// constant operand: 40 +function ROR1_sa40(x) { + return (x >>> 40) | (x << -8); +} + +function ROR2_sa40(x) { + return (x >>> -8) | (x << 40); +} + +function ROR3_sa40(x, sa) { + return (x << -8) | (x >>> 40); +} + +function ROR4_sa40(x) { + return (x << 40) | (x >>> -8); +} + +// ROR1_sa20 +assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF)); +assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF)); +%OptimizeFunctionOnNextCall(ROR1_sa20); +assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF)); + +// ROR1_sa40 +assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF)); +assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF)); +%OptimizeFunctionOnNextCall(ROR1_sa40); +assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF)); + +// ROR2_sa20 +assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF)); +assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF)); +%OptimizeFunctionOnNextCall(ROR2_sa20); +assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF)); + +// ROR2_sa40 +assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF)); +assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF)); +%OptimizeFunctionOnNextCall(ROR2_sa40); +assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF)); + +// ROR3_sa20 +assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF)); +assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF)); +%OptimizeFunctionOnNextCall(ROR3_sa20); +assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF)); + +// ROR3_sa40 +assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF)); +assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF)); +%OptimizeFunctionOnNextCall(ROR3_sa40); +assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF)); + +// ROR4_sa20 +assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF)); +assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF)); +%OptimizeFunctionOnNextCall(ROR4_sa20); +assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF)); + +// ROR4_sa40 +assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF)); +assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF)); +%OptimizeFunctionOnNextCall(ROR4_sa40); +assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF)); + + diff --git a/deps/v8/test/mjsunit/parallel-initial-prototype-change.js b/deps/v8/test/mjsunit/concurrent-initial-prototype-change.js index 625b590fcc..d5b1b99491 100644 --- a/deps/v8/test/mjsunit/parallel-initial-prototype-change.js +++ b/deps/v8/test/mjsunit/concurrent-initial-prototype-change.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax -// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100 +// Flags: --concurrent-recompilation --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -43,12 +43,15 @@ assertEquals(0.5, f1(arr, 0)); // Optimized code of f1 depends on initial object and array maps. %OptimizeFunctionOnNextCall(f1, "concurrent"); -// Trigger optimization in the background thread +// Kick off recompilation; assertEquals(0.5, f1(arr, 0)); -Object.prototype[1] = 1.5; // Invalidate current initial object map. +// Invalidate current initial object map after compile graph has been created. +Object.prototype[1] = 1.5; assertEquals(2, f1(arr, 1)); -// Not yet optimized while background thread is running. +// Not yet optimized since concurrent recompilation is blocked. assertUnoptimized(f1, "no sync"); +// Let concurrent recompilation proceed. +%UnblockConcurrentRecompilation(); // Sync with background thread to conclude optimization, which bails out // due to map dependency. assertUnoptimized(f1, "sync"); diff --git a/deps/v8/test/mjsunit/d8-performance-now.js b/deps/v8/test/mjsunit/d8-performance-now.js new file mode 100644 index 0000000000..13eb1d3f00 --- /dev/null +++ b/deps/v8/test/mjsunit/d8-performance-now.js @@ -0,0 +1,62 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Test the performance.now() function of d8. This test only makes sense with +// d8. + +// Don't run this test in gc stress mode. Time differences may be long +// due to garbage collections. +%SetFlags("--gc-interval=-1"); +%SetFlags("--nostress-compaction"); + +if (this.performance && performance.now) { + (function run() { + var start_test = performance.now(); + // Let the retry run for maximum 100ms to reduce flakiness. + for (var start = performance.now(); + start - start_test < 100; + start = performance.now()) { + var end = performance.now(); + assertTrue(start >= start_test); + assertTrue(end >= start); + while (end - start == 0) { + var next = performance.now(); + assertTrue(next >= end); + end = next; + } + if (end - start <= 1) { + // Found (sub-)millisecond granularity. + return; + } else { + print("Timer difference too big: " + (end - start) + "ms"); + } + } + assertTrue(false); + })() +} diff --git a/deps/v8/test/mjsunit/debug-liveedit-4.js b/deps/v8/test/mjsunit/debug-liveedit-4.js new file mode 100644 index 0000000000..38f751440a --- /dev/null +++ b/deps/v8/test/mjsunit/debug-liveedit-4.js @@ -0,0 +1,69 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-debug-as debug +// Get the Debug object exposed from the debug context global object. + +// In this test case we edit a script so that techincally function text +// hasen't been changed. However actually function became one level more nested +// and must be recompiled because it uses variable from outer scope. + + +Debug = debug.Debug + +eval( +"function TestFunction() {\n" ++ " var a = 'a';\n" ++ " var b = 'b';\n" ++ " var c = 'c';\n" ++ " function A() {\n" ++ " return 2013;\n" ++ " }\n" ++ " function B() {\n" ++ " return String([a, c]);\n" ++ " }\n" ++ " return B();\n" ++ "}\n" +); + +var res = TestFunction(); +print(res); +assertEquals('a,c', res); + +var script = Debug.findScript(TestFunction); +var new_source = script.source.replace("2013", "b"); +print("new source: " + new_source); +var change_log = new Array(); +var result = Debug.LiveEdit.SetScriptSource(script, new_source, false, change_log); + +print("Result: " + JSON.stringify(result) + "\n"); +print("Change log: " + JSON.stringify(change_log) + "\n"); + +var res = TestFunction(); +print(res); +// This might be 'a,b' without a bug fixed. +assertEquals('a,c', res); diff --git a/deps/v8/test/mjsunit/debug-stepin-function-call.js b/deps/v8/test/mjsunit/debug-stepin-function-call.js index 3b5240c933..eaeebcedb2 100644 --- a/deps/v8/test/mjsunit/debug-stepin-function-call.js +++ b/deps/v8/test/mjsunit/debug-stepin-function-call.js @@ -142,8 +142,19 @@ function bind1() { bound(); } +// Test step into apply of bound function. +function applyAndBind1() { + var bound = g.bind(null, 3); + debugger; + bound.apply(null, [3]); + var aLocalVar = 'test'; + var anotherLocalVar = g(aLocalVar) + 's'; + var yetAnotherLocal = 10; +} + var testFunctions = - [call1, call2, call3, call4, apply1, apply2, apply3, apply4, bind1]; + [call1, call2, call3, call4, apply1, apply2, apply3, apply4, bind1, + applyAndBind1]; for (var i = 0; i < testFunctions.length; i++) { state = 0; @@ -161,4 +172,4 @@ assertNull(exception); assertEquals(3, state); // Get rid of the debug event listener. -Debug.setListener(null);
\ No newline at end of file +Debug.setListener(null); diff --git a/deps/v8/test/mjsunit/div-mul-minus-one.js b/deps/v8/test/mjsunit/div-mul-minus-one.js new file mode 100644 index 0000000000..f05bf0f54c --- /dev/null +++ b/deps/v8/test/mjsunit/div-mul-minus-one.js @@ -0,0 +1,53 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function div(g) { + return (g/-1) ^ 1 +} + +var kMinInt = 1 << 31; +var expected_MinInt = div(kMinInt); +var expected_minus_zero = div(0); +%OptimizeFunctionOnNextCall(div); +assertEquals(expected_MinInt, div(kMinInt)); +assertOptimized(div); +assertEquals(expected_minus_zero , div(0)); +assertOptimized(div); + +function mul(g) { + return (g * -1) ^ 1 +} + +expected_MinInt = mul(kMinInt); +expected_minus_zero = mul(0); +%OptimizeFunctionOnNextCall(mul); +assertEquals(expected_MinInt, mul(kMinInt)); +assertOptimized(mul); +assertEquals(expected_minus_zero , mul(0)); +assertOptimized(mul); diff --git a/deps/v8/test/mjsunit/fast-prototype.js b/deps/v8/test/mjsunit/fast-prototype.js index 83bcffe44f..d700c3c3cc 100644 --- a/deps/v8/test/mjsunit/fast-prototype.js +++ b/deps/v8/test/mjsunit/fast-prototype.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax +// Flags: --allow-natives-syntax --expose-gc // TODO(mstarzinger): This test does not succeed when GCs happen in // between prototype transitions, we disable GC stress for now. @@ -84,6 +84,8 @@ function test(use_new, add_first, set__proto__, same_map_as) { return proto; } +// TODO(mstarzinger): This test fails easily if gc happens at the wrong time. +gc(); for (var i = 0; i < 4; i++) { var set__proto__ = ((i & 1) != 0); diff --git a/deps/v8/test/mjsunit/harmony/math-sign.js b/deps/v8/test/mjsunit/harmony/math-sign.js new file mode 100644 index 0000000000..8a89d62828 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-sign.js @@ -0,0 +1,48 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-maths + +assertEquals("Infinity", String(1/Math.sign(0))); +assertEquals("-Infinity", String(1/Math.sign(-0))); +assertEquals(1, Math.sign(100)); +assertEquals(-1, Math.sign(-199)); +assertEquals(1, Math.sign(100.1)); +assertTrue(isNaN(Math.sign("abc"))); +assertTrue(isNaN(Math.sign({}))); +assertEquals(0, Math.sign([])); +assertEquals(1, Math.sign([1])); +assertEquals(-1, Math.sign([-100.1])); +assertTrue(isNaN(Math.sign([1, 1]))); +assertEquals(1, Math.sign({ toString: function() { return "100"; } })); +assertEquals(1, Math.sign({ toString: function() { return 100; } })); +assertEquals(-1, Math.sign({ valueOf: function() { return -1.1; } })); +assertEquals(-1, Math.sign({ valueOf: function() { return "-1.1"; } })); +assertEquals(-1, Math.sign(-Infinity)); +assertEquals(1, Math.sign(Infinity)); +assertEquals(-1, Math.sign("-Infinity")); +assertEquals(1, Math.sign("Infinity")); diff --git a/deps/v8/test/mjsunit/harmony/math-trunc.js b/deps/v8/test/mjsunit/harmony/math-trunc.js new file mode 100644 index 0000000000..ed91ed1380 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-trunc.js @@ -0,0 +1,51 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-maths + +assertEquals("Infinity", String(1/Math.trunc(0))); +assertEquals("-Infinity", String(1/Math.trunc(-0))); +assertEquals("Infinity", String(1/Math.trunc(Math.PI/4))); +assertEquals("-Infinity", String(1/Math.trunc(-Math.sqrt(2)/2))); +assertEquals(100, Math.trunc(100)); +assertEquals(-199, Math.trunc(-199)); +assertEquals(100, Math.trunc(100.1)); +assertTrue(isNaN(Math.trunc("abc"))); +assertTrue(isNaN(Math.trunc({}))); +assertEquals(0, Math.trunc([])); +assertEquals(1, Math.trunc([1])); +assertEquals(-100, Math.trunc([-100.1])); +assertTrue(isNaN(Math.trunc([1, 1]))); +assertEquals(-100, Math.trunc({ toString: function() { return "-100.3"; } })); +assertEquals(10, Math.trunc({ toString: function() { return 10.1; } })); +assertEquals(-1, Math.trunc({ valueOf: function() { return -1.1; } })); +assertEquals("-Infinity", + String(1/Math.trunc({ valueOf: function() { return "-0.1"; } }))); +assertEquals("-Infinity", String(Math.trunc(-Infinity))); +assertEquals("Infinity", String(Math.trunc(Infinity))); +assertEquals("-Infinity", String(Math.trunc("-Infinity"))); +assertEquals("Infinity", String(Math.trunc("Infinity"))); diff --git a/deps/v8/test/mjsunit/harmony/object-observe.js b/deps/v8/test/mjsunit/harmony/object-observe.js index 75f0ff8bb8..f94ab75e9a 100644 --- a/deps/v8/test/mjsunit/harmony/object-observe.js +++ b/deps/v8/test/mjsunit/harmony/object-observe.js @@ -110,14 +110,16 @@ Object.defineProperty(changeRecordWithAccessor, 'name', { // Object.observe -assertThrows(function() { Object.observe("non-object", observer.callback); }, TypeError); +assertThrows(function() { Object.observe("non-object", observer.callback); }, + TypeError); assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); -assertThrows(function() { Object.observe(obj, function() {}, 1); }, TypeError); -assertThrows(function() { Object.observe(obj, function() {}, [undefined]); }, TypeError); -assertThrows(function() { Object.observe(obj, function() {}, [1]); }, TypeError); -assertThrows(function() { Object.observe(obj, function() {}, ['foo', null]); }, TypeError); -assertEquals(obj, Object.observe(obj, observer.callback, ['foo', 'bar', 'baz'])); +assertEquals(obj, Object.observe(obj, observer.callback, [1])); +assertEquals(obj, Object.observe(obj, observer.callback, [true])); +assertEquals(obj, Object.observe(obj, observer.callback, ['foo', null])); +assertEquals(obj, Object.observe(obj, observer.callback, [undefined])); +assertEquals(obj, Object.observe(obj, observer.callback, + ['foo', 'bar', 'baz'])); assertEquals(obj, Object.observe(obj, observer.callback, [])); assertEquals(obj, Object.observe(obj, observer.callback, undefined)); assertEquals(obj, Object.observe(obj, observer.callback)); @@ -202,6 +204,25 @@ observer.assertCallbackRecords([ { object: obj, name: 'bar', type: 'deleted', expando2: 'str' } ]); +// Non-string accept values are coerced to strings +reset(); +Object.observe(obj, observer.callback, [true, 1, null, undefined]); +notifier = Object.getNotifier(obj); +notifier.notify({ type: 'true' }); +notifier.notify({ type: 'false' }); +notifier.notify({ type: '1' }); +notifier.notify({ type: '-1' }); +notifier.notify({ type: 'null' }); +notifier.notify({ type: 'nill' }); +notifier.notify({ type: 'undefined' }); +notifier.notify({ type: 'defined' }); +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: obj, type: 'true' }, + { object: obj, type: '1' }, + { object: obj, type: 'null' }, + { object: obj, type: 'undefined' } +]); // No delivery takes place if no records are pending reset(); @@ -265,6 +286,20 @@ observer.assertCallbackRecords([ { object: obj, type: 'new', name: 'id' }, ]); +// The empty-string property is observable +reset(); +var obj = {}; +Object.observe(obj, observer.callback); +obj[''] = ''; +obj[''] = ' '; +delete obj['']; +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: obj, type: 'new', name: '' }, + { object: obj, type: 'updated', name: '', oldValue: '' }, + { object: obj, type: 'deleted', name: '', oldValue: ' ' }, +]); + // Observing a continuous stream of changes, while itermittantly unobserving. reset(); Object.observe(obj, observer.callback); @@ -307,7 +342,7 @@ observer.assertCallbackRecords([ // Accept reset(); -Object.observe(obj, observer.callback, []); +Object.observe(obj, observer.callback, ['somethingElse']); Object.getNotifier(obj).notify({ type: 'new' }); @@ -1233,6 +1268,75 @@ observer.assertCallbackRecords([ { object: array, name: '0', type: 'updated', oldValue: 2 }, ]); +// Splice emitted after Array mutation methods +function MockArray(initial, observer) { + for (var i = 0; i < initial.length; i++) + this[i] = initial[i]; + + this.length_ = initial.length; + this.observer = observer; +} +MockArray.prototype = { + set length(length) { + Object.getNotifier(this).notify({ type: 'lengthChange' }); + this.length_ = length; + Object.observe(this, this.observer.callback, ['splice']); + }, + get length() { + return this.length_; + } +} + +reset(); +var array = new MockArray([], observer); +Object.observe(array, observer.callback, ['lengthChange']); +Array.prototype.push.call(array, 1); +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: array, type: 'lengthChange' }, + { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 }, +]); + +reset(); +var array = new MockArray([1], observer); +Object.observe(array, observer.callback, ['lengthChange']); +Array.prototype.pop.call(array); +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: array, type: 'lengthChange' }, + { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 }, +]); + +reset(); +var array = new MockArray([1], observer); +Object.observe(array, observer.callback, ['lengthChange']); +Array.prototype.shift.call(array); +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: array, type: 'lengthChange' }, + { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 }, +]); + +reset(); +var array = new MockArray([], observer); +Object.observe(array, observer.callback, ['lengthChange']); +Array.prototype.unshift.call(array, 1); +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: array, type: 'lengthChange' }, + { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 }, +]); + +reset(); +var array = new MockArray([0, 1, 2], observer); +Object.observe(array, observer.callback, ['lengthChange']); +Array.prototype.splice.call(array, 1, 1); +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: array, type: 'lengthChange' }, + { object: array, type: 'splice', index: 1, removed: [1], addedCount: 0 }, +]); + // // === PLAIN OBJECTS === // diff --git a/deps/v8/test/mjsunit/harmony/typedarrays.js b/deps/v8/test/mjsunit/harmony/typedarrays.js index c6d130fc0c..e20fbade9b 100644 --- a/deps/v8/test/mjsunit/harmony/typedarrays.js +++ b/deps/v8/test/mjsunit/harmony/typedarrays.js @@ -123,6 +123,7 @@ function TestTypedArray(constr, elementSize, typicalElement) { var ab = new ArrayBuffer(256*elementSize); var a0 = new constr(30); + assertTrue(ArrayBuffer.isView(a0)); assertSame(elementSize, a0.BYTES_PER_ELEMENT); assertSame(30, a0.length); assertSame(30*elementSize, a0.byteLength); @@ -476,6 +477,7 @@ function TestDataViewConstructor() { var ab = new ArrayBuffer(256); var d1 = new DataView(ab, 1, 255); + assertTrue(ArrayBuffer.isView(d1)); assertSame(ab, d1.buffer); assertSame(1, d1.byteOffset); assertSame(255, d1.byteLength); diff --git a/deps/v8/test/mjsunit/lithium/DivI.js b/deps/v8/test/mjsunit/lithium/DivI.js new file mode 100644 index 0000000000..5420d8c8d0 --- /dev/null +++ b/deps/v8/test/mjsunit/lithium/DivI.js @@ -0,0 +1,57 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --no-use-osr + +function foo(a, b) { + var result = a / 35; + result += 50 / b; + result += a / b; + result += a / -1; + result += a / 1; + result += a / 4; + result += a / -4; + return result / b; +} + +foo(700, 5); +var r1 = foo(700, 5); +%OptimizeFunctionOnNextCall(foo); +var r2 = foo(700, 5); + +assertEquals(r1, r2); + +function boo(value) { + return value / -1; +} + +// Test deoptimization of MinInt / -1. +assertEquals(2147483600, boo(-2147483600)); +assertEquals(2147483600, boo(-2147483600)); +%OptimizeFunctionOnNextCall(boo); +assertEquals(2147483600, boo(-2147483600)); +assertEquals(2147483648, boo(-2147483648)); diff --git a/deps/v8/test/intl/date-format/utils.js b/deps/v8/test/mjsunit/lithium/MathExp.js index 535de15e9a..854ff5fd7f 100644 --- a/deps/v8/test/intl/date-format/utils.js +++ b/deps/v8/test/mjsunit/lithium/MathExp.js @@ -25,12 +25,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Utility methods for date testing. +// Flags: --allow-natives-syntax -/** - * Returns date with timezone info forced into PDT. - */ -function usePDT(dateString) { - var removedTZ = dateString.replace(/(\+|-)\d{4}/, '-0007'); - return removedTZ.replace(/\(.*?\)/, '(PDT)'); +function foo(x) { + return Math.exp(x); } + +foo(12.3); +var r1 = foo(12.3); +%OptimizeFunctionOnNextCall(foo); +var r2 = foo(12.3); + +assertEquals(r1, r2); diff --git a/deps/v8/test/mjsunit/lithium/SeqStringSetChar.js b/deps/v8/test/mjsunit/lithium/SeqStringSetChar.js new file mode 100644 index 0000000000..3c890a8489 --- /dev/null +++ b/deps/v8/test/mjsunit/lithium/SeqStringSetChar.js @@ -0,0 +1,46 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function MyStringFromCharCode(code, i) { + var one_byte = %NewString(3, true); + %_OneByteSeqStringSetChar(one_byte, 0, code); + %_OneByteSeqStringSetChar(one_byte, 1, code); + %_OneByteSeqStringSetChar(one_byte, i, code); + var two_byte = %NewString(3, false); + %_TwoByteSeqStringSetChar(two_byte, 0, code); + %_TwoByteSeqStringSetChar(two_byte, 1, code); + %_TwoByteSeqStringSetChar(two_byte, i, code); + return one_byte + two_byte; +} + +MyStringFromCharCode(65, 2); +var r1 = MyStringFromCharCode(65, 2); +%OptimizeFunctionOnNextCall(MyStringFromCharCode); +var r2 = MyStringFromCharCode(65, 2); +assertEquals(r1, r2); diff --git a/deps/v8/test/mjsunit/lithium/StoreKeyed.js b/deps/v8/test/mjsunit/lithium/StoreKeyed.js new file mode 100644 index 0000000000..d34f390d25 --- /dev/null +++ b/deps/v8/test/mjsunit/lithium/StoreKeyed.js @@ -0,0 +1,61 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --no-use-osr + +function foo(a, i, v) { + a[0] = v; + a[i] = v; +} + +function foo_int(a, i, v) { + a[0] = v; + a[i] = v; +} + +var A1 = [1.2, 2.3]; +var A2 = [1.2, 2.3]; +var A3 = [1.2, 2.3]; + +var A1_int = [12, 23]; +var A2_int = [12, 23]; +var A3_int = [12, 23]; + +foo(A1, 1, 3.4); +foo(A2, 1, 3.4); +%OptimizeFunctionOnNextCall(foo); +foo(A3, 1, 3.4); + +foo_int(A1_int, 1, 34); +foo_int(A2_int, 1, 34); +%OptimizeFunctionOnNextCall(foo_int); +foo_int(A3_int, 1, 34); + +assertEquals(A1[0], A3[0]); +assertEquals(A1[1], A3[1]); +assertEquals(A1_int[0], A3_int[0]); +assertEquals(A1_int[1], A3_int[1]); diff --git a/deps/v8/test/mjsunit/lithium/StoreKeyedExternal.js b/deps/v8/test/mjsunit/lithium/StoreKeyedExternal.js new file mode 100644 index 0000000000..a5670fee95 --- /dev/null +++ b/deps/v8/test/mjsunit/lithium/StoreKeyedExternal.js @@ -0,0 +1,109 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --no-use-osr + +function foo_pixel(a, i, v) { + a[0] = v; + a[i] = v; +} + +function foo_uint16(a, i, v) { + a[0] = v; + a[i] = v; +} + +function foo_uint32(a, i, v) { + a[0] = v; + a[i] = v; +} + +function foo_float(a, i, v) { + a[0] = v; + a[i] = v; +} + +function foo_double(a, i, v) { + a[0] = v; + a[i] = v; +} + +var A1_pixel = new Uint8ClampedArray(2); +var A2_pixel = new Uint8ClampedArray(2); +var A3_pixel = new Uint8ClampedArray(2); + +var A1_uint16 = new Uint16Array(2); +var A2_uint16 = new Uint16Array(2); +var A3_uint16 = new Uint16Array(2); + +var A1_uint32 = new Uint32Array(2); +var A2_uint32 = new Uint32Array(2); +var A3_uint32 = new Uint32Array(2); + +var A1_float = new Float32Array(2); +var A2_float = new Float32Array(2); +var A3_float = new Float32Array(2); + +var A1_double = new Float64Array(2); +var A2_double = new Float64Array(2); +var A3_double = new Float64Array(2); + +foo_pixel(A1_pixel, 1, 34); +foo_pixel(A2_pixel, 1, 34); +%OptimizeFunctionOnNextCall(foo_pixel); +foo_pixel(A3_pixel, 1, 34); + +foo_uint16(A1_uint16, 1, 3.4); +foo_uint16(A2_uint16, 1, 3.4); +%OptimizeFunctionOnNextCall(foo_uint16); +foo_uint16(A3_uint16, 1, 3.4); + +foo_uint32(A1_uint32, 1, 3.4); +foo_uint32(A2_uint32, 1, 3.4); +%OptimizeFunctionOnNextCall(foo_uint32); +foo_uint32(A3_uint32, 1, 3.4); + +foo_float(A1_float, 1, 3.4); +foo_float(A2_float, 1, 3.4); +%OptimizeFunctionOnNextCall(foo_float); +foo_float(A3_float, 1, 3.4); + +foo_double(A1_double, 1, 3.4); +foo_double(A2_double, 1, 3.4); +%OptimizeFunctionOnNextCall(foo_double); +foo_double(A3_double, 1, 3.4); + +assertEquals(A1_pixel[0], A3_pixel[0]); +assertEquals(A1_pixel[1], A3_pixel[1]); +assertEquals(A1_uint16[0], A3_uint16[0]); +assertEquals(A1_uint16[1], A3_uint16[1]); +assertEquals(A1_uint32[0], A3_uint32[0]); +assertEquals(A1_uint32[1], A3_uint32[1]); +assertEquals(A1_float[0], A3_float[0]); +assertEquals(A1_float[1], A3_float[1]); +assertEquals(A1_double[0], A3_double[0]); +assertEquals(A1_double[1], A3_double[1]); diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status index ee35af5a61..256bd3ecd4 100644 --- a/deps/v8/test/mjsunit/mjsunit.status +++ b/deps/v8/test/mjsunit/mjsunit.status @@ -25,184 +25,204 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -prefix mjsunit - -# All tests in the bug directory are expected to fail. -bugs/*: FAIL - -############################################################################## -# Fails. -regress/regress-1119: FAIL - -# Issue 1719: Slow to collect arrays over several contexts. -regress/regress-524: SKIP -# When that bug is fixed, revert the expectation to: -# Skip long running test in debug and allow it to timeout in release mode. -# regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug - -# This test non-deterministically runs out of memory on Windows ia32. -regress/regress-crbug-160010: SKIP - -############################################################################## -# Too slow in debug mode with --stress-opt mode. -compiler/regress-stacktrace-methods: PASS, SKIP if $mode == debug -compiler/regress-funcaller: PASS, SKIP if $mode == debug -regress/regress-2318: PASS, SKIP if $mode == debug -regress/regress-create-exception: PASS, SKIP if $mode == debug -regress/regress-2612: PASS, SKIP if $mode == debug - -############################################################################## -# Too slow in debug mode for GC stress mode. -regress/regress-crbug-217858: PASS, SKIP if $mode == debug +[ +[ALWAYS, { + # All tests in the bug directory are expected to fail. + 'bugs/*': [FAIL], + + # TODO(mvstanton) Re-enable when the performance is bearable again. + 'regress/regress-2185-2': [SKIP], + + ############################################################################## + # Flaky tests. + # BUG(v8:2921): Flaky on ia32 nosnap, arm and nacl. + 'debug-step-4-in-frame': [PASS, [('system == linux and arch == ia32 or ' + 'arch == arm or arch == nacl_ia32 or ' + 'arch == nacl_x64'), FLAKY]], + + ############################################################################## + # Fails. + 'regress/regress-1119': [FAIL], + + # Issue 1719: Slow to collect arrays over several contexts. + 'regress/regress-524': [SKIP], + # When that bug is fixed, revert the expectation to: + # Skip long running test in debug and allow it to timeout in release mode. + # regress/regress-524: [PASS, TIMEOUT, ['mode == debug', SKIP]], + + # This test non-deterministically runs out of memory on Windows ia32. + 'regress/regress-crbug-160010': [SKIP], + + ############################################################################## + # Too slow in debug mode with --stress-opt mode. + 'compiler/regress-stacktrace-methods': [PASS, ['mode == debug', SKIP]], + 'compiler/regress-funcaller': [PASS, ['mode == debug', SKIP]], + 'regress/regress-2318': [PASS, ['mode == debug', SKIP]], + 'regress/regress-create-exception': [PASS, ['mode == debug', SKIP]], + + ############################################################################## + # Too slow in debug mode for GC stress mode. + 'regress/regress-crbug-217858': [PASS, ['mode == debug', SKIP]], + + ############################################################################## + # Only regexp stuff tested, no need for extensive Crankshaft tests. + 'regexp-global': [PASS, NO_VARIANTS], + + ############################################################################## + # No need to waste time for this test. + 'd8-performance-now': [PASS, NO_VARIANTS], + + ############################################################################## + # These use a built-in that's only present in debug mode. They take + # too long to run in debug mode on ARM and MIPS. + 'fuzz-natives-part*': [PASS, ['mode == release or arch == arm or arch == android_arm or arch == mipsel', SKIP]], + + 'big-object-literal': [PASS, ['arch == arm or arch == android_arm', SKIP]], + + # Issue 488: this test sometimes times out. + 'array-constructor': [PASS, TIMEOUT], + + # Very slow on ARM and MIPS, contains no architecture dependent code. + 'unicode-case-overoptimization': [PASS, NO_VARIANTS, ['arch == arm or arch == android_arm or arch == mipsel', TIMEOUT]], + + ############################################################################## + # This test expects to reach a certain recursion depth, which may not work + # for debug mode. + 'json-recursive': [PASS, ['mode == debug', PASS, FAIL]], + + ############################################################################## + # Skip long running tests that time out in debug mode. + 'generated-transition-stub': [PASS, ['mode == debug', SKIP]], + + ############################################################################## + # This test sets the umask on a per-process basis and hence cannot be + # used in multi-threaded runs. + # On android there is no /tmp directory. + 'd8-os': [PASS, ['isolates or arch == android_arm or arch == android_ia32', SKIP]], + 'tools/tickprocessor': [PASS, ['arch == android_arm or arch == android_ia32', SKIP]], + + ############################################################################## + # Long running test that reproduces memory leak and should be run manually. + 'regress/regress-2073': [SKIP], +}], # ALWAYS ############################################################################## -# These use a built-in that's only present in debug mode. They take -# too long to run in debug mode on ARM and MIPS. -fuzz-natives-part*: PASS, SKIP if ($mode == release || $arch == arm || $arch == android_arm || $arch == mipsel) - -big-object-literal: PASS, SKIP if ($arch == arm || $arch == android_arm) - -# Issue 488: this test sometimes times out. -array-constructor: PASS || TIMEOUT - -# Very slow on ARM and MIPS, contains no architecture dependent code. -unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == android_arm || $arch == mipsel) +['arch == arm or arch == android_arm', { + + # Slow tests which times out in debug mode. + 'try': [PASS, ['mode == debug', SKIP]], + 'debug-scripts-request': [PASS, ['mode == debug', SKIP]], + 'array-constructor': [PASS, ['mode == debug', SKIP]], + 'regress/regress-1122': [PASS, ['mode == debug and arch == android_arm', SKIP]], + + # Flaky test that can hit compilation-time stack overflow in debug mode. + 'unicode-test': [PASS, ['mode == debug', PASS, FAIL]], + + # Times out often in release mode on ARM. + 'compiler/regress-stacktrace-methods': [PASS, PASS, ['mode == release', TIMEOUT]], + 'array-splice': [PASS, TIMEOUT], + + # Long running test. + 'string-indexof-2': [PASS, TIMEOUT], + 'mirror-object': [PASS, TIMEOUT], + + # BUG(3251035): Timeouts in long looping crankshaft optimization + # tests. Skipping because having them timeout takes too long on the + # buildbot. + 'compiler/alloc-number': [SKIP], + 'compiler/array-length': [SKIP], + 'compiler/assignment-deopt': [SKIP], + 'compiler/deopt-args': [SKIP], + 'compiler/inline-compare': [SKIP], + 'compiler/inline-global-access': [SKIP], + 'compiler/optimized-function-calls': [SKIP], + 'compiler/pic': [SKIP], + 'compiler/property-calls': [SKIP], + 'compiler/recursive-deopt': [SKIP], + 'compiler/regress-4': [SKIP], + 'compiler/regress-funcaller': [SKIP], + 'compiler/regress-rep-change': [SKIP], + 'compiler/regress-arguments': [SKIP], + 'compiler/regress-funarguments': [SKIP], + 'compiler/regress-3249650': [SKIP], + 'compiler/simple-deopt': [SKIP], + 'regress/regress-490': [SKIP], + 'regress/regress-634': [SKIP], + 'regress/regress-create-exception': [SKIP], + 'regress/regress-3218915': [SKIP], + 'regress/regress-3247124': [SKIP], + + # Requires bigger stack size in the Genesis and if stack size is increased, + # the test requires too much time to run. However, the problem test covers + # should be platform-independent. + 'regress/regress-1132': [SKIP], + + # Stack manipulations in LiveEdit is not implemented for this arch. + 'debug-liveedit-check-stack': [SKIP], + 'debug-liveedit-stack-padding': [SKIP], + 'debug-liveedit-restart-frame': [SKIP], + 'debug-liveedit-double-call': [SKIP], + + # Currently always deopt on minus zero + 'math-floor-of-div-minus-zero': [SKIP], +}], # 'arch == arm or arch == android_arm' ############################################################################## -# This test expects to reach a certain recursion depth, which may not work -# for debug mode. -json-recursive: PASS, (PASS || FAIL) if $mode == debug - -############################################################################## -# Skip long running tests that time out in debug mode. -generated-transition-stub: PASS, SKIP if $mode == debug - -############################################################################## -# This test sets the umask on a per-process basis and hence cannot be -# used in multi-threaded runs. -# On android there is no /tmp directory. -d8-os: PASS, SKIP if ($isolates || $arch == android_arm || $arch == android_ia32) -tools/tickprocessor: PASS, SKIP if ($arch == android_arm || $arch == android_ia32) - -############################################################################## -# Long running test that reproduces memory leak and should be run manually. -regress/regress-2073: SKIP - -############################################################################## -[ $arch == arm || $arch == android_arm ] - -# Slow tests which times out in debug mode. -try: PASS, SKIP if $mode == debug -debug-scripts-request: PASS, SKIP if $mode == debug -array-constructor: PASS, SKIP if $mode == debug -regress/regress-1122: PASS, SKIP if ($mode == debug && $arch == android_arm) - -# Flaky test that can hit compilation-time stack overflow in debug mode. -unicode-test: PASS, (PASS || FAIL) if $mode == debug - -# Times out often in release mode on ARM. -compiler/regress-stacktrace-methods: PASS, PASS || TIMEOUT if $mode == release -array-splice: PASS || TIMEOUT - -# Long running test. -string-indexof-2: PASS || TIMEOUT -mirror-object: PASS || TIMEOUT - -# BUG(3251035): Timeouts in long looping crankshaft optimization -# tests. Skipping because having them timeout takes too long on the -# buildbot. -compiler/alloc-number: SKIP -compiler/array-length: SKIP -compiler/assignment-deopt: SKIP -compiler/deopt-args: SKIP -compiler/inline-compare: SKIP -compiler/inline-global-access: SKIP -compiler/optimized-function-calls: SKIP -compiler/pic: SKIP -compiler/property-calls: SKIP -compiler/recursive-deopt: SKIP -compiler/regress-4: SKIP -compiler/regress-funcaller: SKIP -compiler/regress-rep-change: SKIP -compiler/regress-arguments: SKIP -compiler/regress-funarguments: SKIP -compiler/regress-3249650: SKIP -compiler/simple-deopt: SKIP -regress/regress-490: SKIP -regress/regress-634: SKIP -regress/regress-create-exception: SKIP -regress/regress-3218915: SKIP -regress/regress-3247124: SKIP - -# Requires bigger stack size in the Genesis and if stack size is increased, -# the test requires too much time to run. However, the problem test covers -# should be platform-independent. -regress/regress-1132: SKIP - -# Stack manipulations in LiveEdit is not implemented for this arch. -debug-liveedit-check-stack: SKIP -debug-liveedit-stack-padding: SKIP -debug-liveedit-restart-frame: SKIP -debug-liveedit-double-call: SKIP - -# Currently always deopt on minus zero -math-floor-of-div-minus-zero: SKIP - -############################################################################## -[ $arch == mipsel ] - -# Slow tests which times out in debug mode. -try: PASS, SKIP if $mode == debug -debug-scripts-request: PASS, SKIP if $mode == debug -array-constructor: PASS, SKIP if $mode == debug - -# Times out often in release mode on MIPS. -compiler/regress-stacktrace-methods: PASS, PASS || TIMEOUT if $mode == release -array-splice: PASS || TIMEOUT - -# Long running test. -mirror-object: PASS || TIMEOUT -string-indexof-2: PASS || TIMEOUT - -# BUG(3251035): Timeouts in long looping crankshaft optimization -# tests. Skipping because having them timeout takes too long on the -# buildbot. -compiler/alloc-number: SKIP -compiler/array-length: SKIP -compiler/assignment-deopt: SKIP -compiler/deopt-args: SKIP -compiler/inline-compare: SKIP -compiler/inline-global-access: SKIP -compiler/optimized-function-calls: SKIP -compiler/pic: SKIP -compiler/property-calls: SKIP -compiler/recursive-deopt: SKIP -compiler/regress-4: SKIP -compiler/regress-funcaller: SKIP -compiler/regress-rep-change: SKIP -compiler/regress-arguments: SKIP -compiler/regress-funarguments: SKIP -compiler/regress-3249650: SKIP -compiler/simple-deopt: SKIP -regress/regress-490: SKIP -regress/regress-634: SKIP -regress/regress-create-exception: SKIP -regress/regress-3218915: SKIP -regress/regress-3247124: SKIP - -# Requires bigger stack size in the Genesis and if stack size is increased, -# the test requires too much time to run. However, the problem test covers -# should be platform-independent. -regress/regress-1132: SKIP - -# Stack manipulations in LiveEdit is not implemented for this arch. -debug-liveedit-check-stack: SKIP -debug-liveedit-stack-padding: SKIP -debug-liveedit-restart-frame: SKIP -debug-liveedit-double-call: SKIP - -# Currently always deopt on minus zero -math-floor-of-div-minus-zero: SKIP +['arch == mipsel', { + + # Slow tests which times out in debug mode. + 'try': [PASS, ['mode == debug', SKIP]], + 'debug-scripts-request': [PASS, ['mode == debug', SKIP]], + 'array-constructor': [PASS, ['mode == debug', SKIP]], + + # Times out often in release mode on MIPS. + 'compiler/regress-stacktrace-methods': [PASS, PASS, ['mode == release', TIMEOUT]], + 'array-splice': [PASS, TIMEOUT], + + # Long running test. + 'mirror-object': [PASS, TIMEOUT], + 'string-indexof-2': [PASS, TIMEOUT], + + # BUG(3251035): Timeouts in long looping crankshaft optimization + # tests. Skipping because having them timeout takes too long on the + # buildbot. + 'compiler/alloc-number': [SKIP], + 'compiler/array-length': [SKIP], + 'compiler/assignment-deopt': [SKIP], + 'compiler/deopt-args': [SKIP], + 'compiler/inline-compare': [SKIP], + 'compiler/inline-global-access': [SKIP], + 'compiler/optimized-function-calls': [SKIP], + 'compiler/pic': [SKIP], + 'compiler/property-calls': [SKIP], + 'compiler/recursive-deopt': [SKIP], + 'compiler/regress-4': [SKIP], + 'compiler/regress-funcaller': [SKIP], + 'compiler/regress-rep-change': [SKIP], + 'compiler/regress-arguments': [SKIP], + 'compiler/regress-funarguments': [SKIP], + 'compiler/regress-3249650': [SKIP], + 'compiler/simple-deopt': [SKIP], + 'regress/regress-490': [SKIP], + 'regress/regress-634': [SKIP], + 'regress/regress-create-exception': [SKIP], + 'regress/regress-3218915': [SKIP], + 'regress/regress-3247124': [SKIP], + + # Requires bigger stack size in the Genesis and if stack size is increased, + # the test requires too much time to run. However, the problem test covers + # should be platform-independent. + 'regress/regress-1132': [SKIP], + + # Stack manipulations in LiveEdit is not implemented for this arch. + 'debug-liveedit-check-stack': [SKIP], + 'debug-liveedit-stack-padding': [SKIP], + 'debug-liveedit-restart-frame': [SKIP], + 'debug-liveedit-double-call': [SKIP], + + # Currently always deopt on minus zero + 'math-floor-of-div-minus-zero': [SKIP], +}], # 'arch == mipsel' ############################################################################## # Native Client uses the ARM simulator so will behave similarly to arm @@ -210,46 +230,52 @@ math-floor-of-div-minus-zero: SKIP # TODO(bradchen): enable more tests for NaCl V8 when it stops using # the ARM simulator. ############################################################################## -[ $arch == nacl_ia32 || $arch == nacl_x64 ] -# There is no /tmp directory for NaCl runs -d8-os: SKIP +['arch == nacl_ia32 or arch == nacl_x64', { + # There is no /tmp directory for NaCl runs + 'd8-os': [SKIP], + + # Stack manipulations in LiveEdit is not implemented for this arch. + 'debug-liveedit-check-stack': [SKIP], + 'debug-liveedit-stack-padding': [SKIP], + 'debug-liveedit-restart-frame': [SKIP], + 'debug-liveedit-double-call': [SKIP], -# Stack manipulations in LiveEdit is not implemented for this arch. -debug-liveedit-check-stack: SKIP -debug-liveedit-stack-padding: SKIP -debug-liveedit-restart-frame: SKIP -debug-liveedit-double-call: SKIP + # This test dumps core for arm.debug, so no reason to expect it to work + # for NaCl. The other three fuzz-natives tests seem to run fine. + # As noted above none of them are run in the arm.debug case. + 'fuzz-natives-part4': [SKIP], -# This test dumps core for arm.debug, so no reason to expect it to work -# for NaCl. The other three fuzz-natives tests seem to run fine. -# As noted above none of them are run in the arm.debug case. -fuzz-natives-part4: SKIP + # NaCl builds have problems with this test since Pepper_28. + # V8 Issue 2786 + 'math-exp-precision': [SKIP], -# NaCl builds have problems with this test since Pepper_28. -# V8 Issue 2786 -math-exp-precision: SKIP + # Requires bigger stack size in the Genesis and if stack size is increased, + # the test requires too much time to run. However, the problem test covers + # should be platform-independent. + 'regress/regress-1132': [SKIP], -# Requires bigger stack size in the Genesis and if stack size is increased, -# the test requires too much time to run. However, the problem test covers -# should be platform-independent. -regress/regress-1132: SKIP + # Poor performance for NaCl V8 causes an assertion failure for this test. + 'regress/regress-165637': [SKIP], -# Poor performance for NaCl V8 causes an assertion failure for this test. -regress/regress-165637: SKIP + # Skip long running test that times out in debug mode and goes OOM on NaCl. + 'regress/regress-crbug-160010': [SKIP], -# Skip long running test that times out in debug mode and goes OOM on NaCl. -regress/regress-crbug-160010: SKIP + # Bug(v8:2978). + 'lithium/MathExp': [PASS, FAIL], +}], # 'arch == nacl_ia32 or arch == nacl_x64' ############################################################################## -[ $deopt_fuzzer == True ] - -# Skip tests that are not suitable for deoptimization fuzzing. -assert-opt-and-deopt: SKIP -never-optimize: SKIP -regress/regress-2185-2: SKIP -harmony/object-observe: SKIP -readonly: SKIP -array-feedback: SKIP - -# Deopt every n garbage collections collides with the deopt every n times flag. -regress/regress-2653: SKIP +['deopt_fuzzer == True', { + + # Skip tests that are not suitable for deoptimization fuzzing. + 'assert-opt-and-deopt': [SKIP], + 'never-optimize': [SKIP], + 'regress/regress-2185-2': [SKIP], + 'harmony/object-observe': [SKIP], + 'readonly': [SKIP], + 'array-feedback': [SKIP], + + # Deopt every n garbage collections collides with deopt every n times. + 'regress/regress-2653': [SKIP], +}], # 'deopt_fuzzer == True' +] diff --git a/deps/v8/test/mjsunit/number-tostring-add.js b/deps/v8/test/mjsunit/number-tostring-add.js new file mode 100644 index 0000000000..41d3cbd525 --- /dev/null +++ b/deps/v8/test/mjsunit/number-tostring-add.js @@ -0,0 +1,89 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function add(a, b) { + return a + b; +} + +function testToString(a, b) { + assertEquals(a, b.toString()); + assertEquals(a, "" + b); + assertEquals(a, add("", b)); + assertEquals("yes" + a, add("yes", b)); +} + +testToString("NaN", (NaN)); +testToString("Infinity", (1/0)); +testToString("-Infinity", (-1/0)); +testToString("0", (0)); +testToString("9", (9)); +testToString("90", (90)); +testToString("90.12", (90.12)); +testToString("0.1", (0.1)); +testToString("0.01", (0.01)); +testToString("0.0123", (0.0123)); +testToString("111111111111111110000", (111111111111111111111)); +testToString("1.1111111111111111e+21", (1111111111111111111111)); +testToString("1.1111111111111111e+22", (11111111111111111111111)); +testToString("0.00001", (0.00001)); +testToString("0.000001", (0.000001)); +testToString("1e-7", (0.0000001)); +testToString("1.2e-7", (0.00000012)); +testToString("1.23e-7", (0.000000123)); +testToString("1e-8", (0.00000001)); +testToString("1.2e-8", (0.000000012)); +testToString("1.23e-8", (0.0000000123)); + +testToString("0", (-0)); +testToString("-9", (-9)); +testToString("-90", (-90)); +testToString("-90.12", (-90.12)); +testToString("-0.1", (-0.1)); +testToString("-0.01", (-0.01)); +testToString("-0.0123", (-0.0123)); +testToString("-111111111111111110000", (-111111111111111111111)); +testToString("-1.1111111111111111e+21", (-1111111111111111111111)); +testToString("-1.1111111111111111e+22", (-11111111111111111111111)); +testToString("-0.00001", (-0.00001)); +testToString("-0.000001", (-0.000001)); +testToString("-1e-7", (-0.0000001)); +testToString("-1.2e-7", (-0.00000012)); +testToString("-1.23e-7", (-0.000000123)); +testToString("-1e-8", (-0.00000001)); +testToString("-1.2e-8", (-0.000000012)); +testToString("-1.23e-8", (-0.0000000123)); + +testToString("1000", (1000)); +testToString("0.00001", (0.00001)); +testToString("1000000000000000100", (1000000000000000128)); +testToString("1e+21", (1000000000000000012800)); +testToString("-1e+21", (-1000000000000000012800)); +testToString("1e-7", (0.0000001)); +testToString("-1e-7", (-0.0000001)); +testToString("1.0000000000000001e+21", (1000000000000000128000)); +testToString("0.000001", (0.000001)); +testToString("1e-7", (0.0000001)); diff --git a/deps/v8/test/mjsunit/number-tostring-func.js b/deps/v8/test/mjsunit/number-tostring-func.js new file mode 100644 index 0000000000..c64706e703 --- /dev/null +++ b/deps/v8/test/mjsunit/number-tostring-func.js @@ -0,0 +1,367 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ---------------------------------------------------------------------- +// toString +function testToString(a, b) { + assertEquals(a, b.toString()); +} + +function testToStringP(a, b, c) { + assertEquals(a, b.toString(c)); +} + +testToString("NaN", (NaN)); +testToString("Infinity", (1/0)); +testToString("-Infinity", (-1/0)); +testToString("0", (0)); +testToString("9", (9)); +testToString("90", (90)); +testToString("90.12", (90.12)); +testToString("0.1", (0.1)); +testToString("0.01", (0.01)); +testToString("0.0123", (0.0123)); +testToString("111111111111111110000", (111111111111111111111)); +testToString("1.1111111111111111e+21", (1111111111111111111111)); +testToString("1.1111111111111111e+22", (11111111111111111111111)); +testToString("0.00001", (0.00001)); +testToString("0.000001", (0.000001)); +testToString("1e-7", (0.0000001)); +testToString("1.2e-7", (0.00000012)); +testToString("1.23e-7", (0.000000123)); +testToString("1e-8", (0.00000001)); +testToString("1.2e-8", (0.000000012)); +testToString("1.23e-8", (0.0000000123)); + +testToString("0", (-0)); +testToString("-9", (-9)); +testToString("-90", (-90)); +testToString("-90.12", (-90.12)); +testToString("-0.1", (-0.1)); +testToString("-0.01", (-0.01)); +testToString("-0.0123", (-0.0123)); +testToString("-111111111111111110000", (-111111111111111111111)); +testToString("-1.1111111111111111e+21", (-1111111111111111111111)); +testToString("-1.1111111111111111e+22", (-11111111111111111111111)); +testToString("-0.00001", (-0.00001)); +testToString("-0.000001", (-0.000001)); +testToString("-1e-7", (-0.0000001)); +testToString("-1.2e-7", (-0.00000012)); +testToString("-1.23e-7", (-0.000000123)); +testToString("-1e-8", (-0.00000001)); +testToString("-1.2e-8", (-0.000000012)); +testToString("-1.23e-8", (-0.0000000123)); + +testToString("1000", (1000)); +testToString("0.00001", (0.00001)); +testToString("1000000000000000100", (1000000000000000128)); +testToString("1e+21", (1000000000000000012800)); +testToString("-1e+21", (-1000000000000000012800)); +testToString("1e-7", (0.0000001)); +testToString("-1e-7", (-0.0000001)); +testToString("1.0000000000000001e+21", (1000000000000000128000)); +testToString("0.000001", (0.000001)); +testToString("1e-7", (0.0000001)); + +testToStringP("NaN", (NaN), 16); +testToStringP("Infinity", (1/0), 16); +testToStringP("-Infinity", (-1/0), 16); +testToStringP("0", (0), 16); +testToStringP("9", (9), 16); +testToStringP("5a", (90), 16); +testToStringP("5a.1eb851eb852", (90.12), 16); +testToStringP("0.1999999999999a", (0.1), 16); +testToStringP("0.028f5c28f5c28f6", (0.01), 16); +testToStringP("0.032617c1bda511a", (0.0123), 16); +testToStringP("605f9f6dd18bc8000", (111111111111111111111), 16); +testToStringP("3c3bc3a4a2f75c0000", (1111111111111111111111), 16); +testToStringP("25a55a46e5da9a00000", (11111111111111111111111), 16); +testToStringP("0.0000a7c5ac471b4788", (0.00001), 16); +testToStringP("0.000010c6f7a0b5ed8d", (0.000001), 16); +testToStringP("0.000001ad7f29abcaf48", (0.0000001), 16); +testToStringP("0.000002036565348d256", (0.00000012), 16); +testToStringP("0.0000021047ee22aa466", (0.000000123), 16); +testToStringP("0.0000002af31dc4611874", (0.00000001), 16); +testToStringP("0.000000338a23b87483be", (0.000000012), 16); +testToStringP("0.00000034d3fe36aaa0a2", (0.0000000123), 16); + +testToStringP("0", (-0), 16); +testToStringP("-9", (-9), 16); +testToStringP("-5a", (-90), 16); +testToStringP("-5a.1eb851eb852", (-90.12), 16); +testToStringP("-0.1999999999999a", (-0.1), 16); +testToStringP("-0.028f5c28f5c28f6", (-0.01), 16); +testToStringP("-0.032617c1bda511a", (-0.0123), 16); +testToStringP("-605f9f6dd18bc8000", (-111111111111111111111), 16); +testToStringP("-3c3bc3a4a2f75c0000", (-1111111111111111111111), 16); +testToStringP("-25a55a46e5da9a00000", (-11111111111111111111111), 16); +testToStringP("-0.0000a7c5ac471b4788", (-0.00001), 16); +testToStringP("-0.000010c6f7a0b5ed8d", (-0.000001), 16); +testToStringP("-0.000001ad7f29abcaf48", (-0.0000001), 16); +testToStringP("-0.000002036565348d256", (-0.00000012), 16); +testToStringP("-0.0000021047ee22aa466", (-0.000000123), 16); +testToStringP("-0.0000002af31dc4611874", (-0.00000001), 16); +testToStringP("-0.000000338a23b87483be", (-0.000000012), 16); +testToStringP("-0.00000034d3fe36aaa0a2", (-0.0000000123), 16); + +testToString("4294967296", Math.pow(2,32)); +testToStringP("ffffffff", (Math.pow(2,32)-1), 16); +testToStringP("11111111111111111111111111111111", (Math.pow(2,32)-1), 2); +testToStringP("5yc1z", (10000007), 36); +testToStringP("0", (0), 36); +testToStringP("0", (0), 16); +testToStringP("0", (0), 10); +testToStringP("0", (0), 8); +testToStringP("0", (0), 2); +testToStringP("100000000000000000000000000000000", Math.pow(2,32), 2); +testToStringP("100000000000000000000000000000001", (Math.pow(2,32) + 1), 2); +testToStringP("100000000000080", (0x100000000000081), 16); +testToStringP("1000000000000100", (-(-'0x1000000000000081')), 16); +testToStringP("1000000000000000", (-(-'0x1000000000000080')), 16); +testToStringP("1000000000000000", (-(-'0x100000000000007F')), 16); +testToStringP("100000000000000000000000000000000000000000000000010000000", (0x100000000000081), 2); +testToStringP("-11111111111111111111111111111111", (-(Math.pow(2,32)-1)), 2); +testToStringP("-5yc1z", (-10000007), 36); +testToStringP("-100000000000000000000000000000000", (-Math.pow(2,32)), 2); +testToStringP("-100000000000000000000000000000001", (-(Math.pow(2,32) + 1)), 2); +testToStringP("-100000000000080", (-0x100000000000081), 16); +testToStringP("-100000000000000000000000000000000000000000000000010000000", (-0x100000000000081), 2); +testToStringP("8.8", (8.5), 16); +testToStringP("-8.8", (-8.5), 16); + +// ---------------------------------------------------------------------- +// toFixed +function testToFixed(a, b, c) { + assertEquals(a, b.toFixed(c)); +} + +testToFixed("NaN", (NaN), (2)); +testToFixed("Infinity", (1/0), (2)); +testToFixed("-Infinity", (-1/0), (2)); + +testToFixed("1.1111111111111111e+21", (1111111111111111111111), (8)); +testToFixed("0.1", (0.1), (1)); +testToFixed("0.10", (0.1), (2)); +testToFixed("0.100", (0.1), (3)); +testToFixed("0.01", (0.01), (2)); +testToFixed("0.010", (0.01), (3)); +testToFixed("0.0100", (0.01), (4)); +testToFixed("0.00", (0.001), (2)); +testToFixed("0.001", (0.001), (3)); +testToFixed("0.0010", (0.001), (4)); +testToFixed("1.0000", (1), (4)); +testToFixed("1.0", (1), (1)); +testToFixed("1", (1), (0)); +testToFixed("12", (12), (0)); +testToFixed("1", (1.1), (0)); +testToFixed("12", (12.1), (0)); +testToFixed("1", (1.12), (0)); +testToFixed("12", (12.12), (0)); +testToFixed("0.0000006", (0.0000006), (7)); +testToFixed("0.00000006", (0.00000006), (8)); +testToFixed("0.000000060", (0.00000006), (9)); +testToFixed("0.0000000600", (0.00000006), (10)); +testToFixed("0", (0), (0)); +testToFixed("0.0", (0), (1)); +testToFixed("0.00", (0), (2)); + +testToFixed("-1.1111111111111111e+21", (-1111111111111111111111), (8)); +testToFixed("-0.1", (-0.1), (1)); +testToFixed("-0.10", (-0.1), (2)); +testToFixed("-0.100", (-0.1), (3)); +testToFixed("-0.01", (-0.01), (2)); +testToFixed("-0.010", (-0.01), (3)); +testToFixed("-0.0100", (-0.01), (4)); +testToFixed("-0.00", (-0.001), (2)); +testToFixed("-0.001", (-0.001), (3)); +testToFixed("-0.0010", (-0.001), (4)); +testToFixed("-1.0000", (-1), (4)); +testToFixed("-1.0", (-1), (1)); +testToFixed("-1", (-1), (0)); +testToFixed("-1", (-1.1), (0)); +testToFixed("-12", (-12.1), (0)); +testToFixed("-1", (-1.12), (0)); +testToFixed("-12", (-12.12), (0)); +testToFixed("-0.0000006", (-0.0000006), (7)); +testToFixed("-0.00000006", (-0.00000006), (8)); +testToFixed("-0.000000060", (-0.00000006), (9)); +testToFixed("-0.0000000600", (-0.00000006), (10)); +testToFixed("0", (-0), (0)); +testToFixed("0.0", (-0), (1)); +testToFixed("0.00", (-0), (2)); + +testToFixed("0.00001", (0.00001), (5)); +testToFixed("0.00000000000000000010", (0.0000000000000000001), (20)); +testToFixed("0.00001000000000000", (0.00001), (17)); +testToFixed("1.00000000000000000", (1), (17)); +testToFixed("100000000000000128.0", (100000000000000128), (1)); +testToFixed("10000000000000128.00", (10000000000000128), (2)); +testToFixed("10000000000000128.00000000000000000000", (10000000000000128), (20)); +testToFixed("-42.000", (-42), (3)); +testToFixed("-0.00000000000000000010", (-0.0000000000000000001), (20)); +testToFixed("0.12312312312312299889", (0.123123123123123), (20)); + +assertEquals("-1000000000000000128", (-1000000000000000128).toFixed()); +assertEquals("0", (0).toFixed()); +assertEquals("1000000000000000128", (1000000000000000128).toFixed()); +assertEquals("1000", (1000).toFixed()); +assertEquals("0", (0.00001).toFixed()); +// Test that we round up even when the last digit generated is even. +// dtoa does not do this in its original form. +assertEquals("1", 0.5.toFixed(0), "0.5.toFixed(0)"); +assertEquals("-1", (-0.5).toFixed(0), "(-0.5).toFixed(0)"); +assertEquals("1.3", 1.25.toFixed(1), "1.25.toFixed(1)"); +// This is bizare, but Spidermonkey and KJS behave the same. +assertEquals("234.2040", (234.20405).toFixed(4), "234.2040.toFixed(4)"); +assertEquals("234.2041", (234.2040506).toFixed(4)); + +// ---------------------------------------------------------------------- +// toExponential +function testToExponential(a, b) { + assertEquals(a, b.toExponential()); +} + +function testToExponentialP(a, b, c) { + assertEquals(a, b.toExponential(c)); +} + +testToExponential("1e+0", (1)); +testToExponential("1.1e+1", (11)); +testToExponential("1.12e+2", (112)); +testToExponential("1e-1", (0.1)); +testToExponential("1.1e-1", (0.11)); +testToExponential("1.12e-1", (0.112)); +testToExponential("-1e+0", (-1)); +testToExponential("-1.1e+1", (-11)); +testToExponential("-1.12e+2", (-112)); +testToExponential("-1e-1", (-0.1)); +testToExponential("-1.1e-1", (-0.11)); +testToExponential("-1.12e-1", (-0.112)); +testToExponential("0e+0", (0)); +testToExponential("1.12356e-4", (0.000112356)); +testToExponential("-1.12356e-4", (-0.000112356)); + +testToExponentialP("1e+0", (1), (0)); +testToExponentialP("1e+1", (11), (0)); +testToExponentialP("1e+2", (112), (0)); +testToExponentialP("1.0e+0", (1), (1)); +testToExponentialP("1.1e+1", (11), (1)); +testToExponentialP("1.1e+2", (112), (1)); +testToExponentialP("1.00e+0", (1), (2)); +testToExponentialP("1.10e+1", (11), (2)); +testToExponentialP("1.12e+2", (112), (2)); +testToExponentialP("1.000e+0", (1), (3)); +testToExponentialP("1.100e+1", (11), (3)); +testToExponentialP("1.120e+2", (112), (3)); +testToExponentialP("1e-1", (0.1), (0)); +testToExponentialP("1e-1", (0.11), (0)); +testToExponentialP("1e-1", (0.112), (0)); +testToExponentialP("1.0e-1", (0.1), (1)); +testToExponentialP("1.1e-1", (0.11), (1)); +testToExponentialP("1.1e-1", (0.112), (1)); +testToExponentialP("1.00e-1", (0.1), (2)); +testToExponentialP("1.10e-1", (0.11), (2)); +testToExponentialP("1.12e-1", (0.112), (2)); +testToExponentialP("1.000e-1", (0.1), (3)); +testToExponentialP("1.100e-1", (0.11), (3)); +testToExponentialP("1.120e-1", (0.112), (3)); + +testToExponentialP("-1e+0", (-1), (0)); +testToExponentialP("-1e+1", (-11), (0)); +testToExponentialP("-1e+2", (-112), (0)); +testToExponentialP("-1.0e+0", (-1), (1)); +testToExponentialP("-1.1e+1", (-11), (1)); +testToExponentialP("-1.1e+2", (-112), (1)); +testToExponentialP("-1.00e+0", (-1), (2)); +testToExponentialP("-1.10e+1", (-11), (2)); +testToExponentialP("-1.12e+2", (-112), (2)); +testToExponentialP("-1.000e+0", (-1), (3)); +testToExponentialP("-1.100e+1", (-11), (3)); +testToExponentialP("-1.120e+2", (-112), (3)); +testToExponentialP("-1e-1", (-0.1), (0)); +testToExponentialP("-1e-1", (-0.11), (0)); +testToExponentialP("-1e-1", (-0.112), (0)); +testToExponentialP("-1.0e-1", (-0.1), (1)); +testToExponentialP("-1.1e-1", (-0.11), (1)); +testToExponentialP("-1.1e-1", (-0.112), (1)); +testToExponentialP("-1.00e-1", (-0.1), (2)); +testToExponentialP("-1.10e-1", (-0.11), (2)); +testToExponentialP("-1.12e-1", (-0.112), (2)); +testToExponentialP("-1.000e-1", (-0.1), (3)); +testToExponentialP("-1.100e-1", (-0.11), (3)); +testToExponentialP("-1.120e-1", (-0.112), (3)); + +testToExponentialP("NaN", (NaN), (2)); +testToExponentialP("Infinity", (Infinity), (2)); +testToExponentialP("-Infinity", (-Infinity), (2)); +testToExponentialP("1e+0", (1), (0)); +testToExponentialP("0.00e+0", (0), (2)); +testToExponentialP("1e+1", (11.2356), (0)); +testToExponentialP("1.1236e+1", (11.2356), (4)); +testToExponentialP("1.1236e-4", (0.000112356), (4)); +testToExponentialP("-1.1236e-4", (-0.000112356), (4)); + +// ---------------------------------------------------------------------- +// toPrecision +function testToPrecision(a, b, c) { + assertEquals(a, b.toPrecision(c)); +} + +testToPrecision("NaN", (NaN), (1)); +testToPrecision("Infinity", (Infinity), (2)); +testToPrecision("-Infinity", (-Infinity), (2)); +testToPrecision("0.000555000000000000", (0.000555), (15)); +testToPrecision("5.55000000000000e-7", (0.000000555), (15)); +testToPrecision("-5.55000000000000e-7", (-0.000000555), (15)); +testToPrecision("1e+8", (123456789), (1)); +testToPrecision("123456789", (123456789), (9)); +testToPrecision("1.2345679e+8", (123456789), (8)); +testToPrecision("1.234568e+8", (123456789), (7)); +testToPrecision("-1.234568e+8", (-123456789), (7)); +testToPrecision("-1.2e-9", Number(-.0000000012345), (2)); +testToPrecision("-1.2e-8", Number(-.000000012345), (2)); +testToPrecision("-1.2e-7", Number(-.00000012345), (2)); +testToPrecision("-0.0000012", Number(-.0000012345), (2)); +testToPrecision("-0.000012", Number(-.000012345), (2)); +testToPrecision("-0.00012", Number(-.00012345), (2)); +testToPrecision("-0.0012", Number(-.0012345), (2)); +testToPrecision("-0.012", Number(-.012345), (2)); +testToPrecision("-0.12", Number(-.12345), (2)); +testToPrecision("-1.2", Number(-1.2345), (2)); +testToPrecision("-12", Number(-12.345), (2)); +testToPrecision("-1.2e+2", Number(-123.45), (2)); +testToPrecision("-1.2e+3", Number(-1234.5), (2)); +testToPrecision("-1.2e+4", Number(-12345), (2)); +testToPrecision("-1.235e+4", Number(-12345.67), (4)); +testToPrecision("-1.234e+4", Number(-12344.67), (4)); +// Test that we round up even when the last digit generated is even. +// dtoa does not do this in its original form. +assertEquals("1.3", 1.25.toPrecision(2), "1.25.toPrecision(2)"); +assertEquals("1.4", 1.35.toPrecision(2), "1.35.toPrecision(2)"); + + + diff --git a/deps/v8/test/mjsunit/opt-elements-kind.js b/deps/v8/test/mjsunit/opt-elements-kind.js index 83ad702c2d..fe6b8b9bfb 100644 --- a/deps/v8/test/mjsunit/opt-elements-kind.js +++ b/deps/v8/test/mjsunit/opt-elements-kind.js @@ -40,6 +40,11 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. +// Reset the GC stress mode to be off. Needed because AllocationMementos only +// live for one gc, so a gc that happens in certain fragile areas of the test +// can break assumptions. +%SetFlags("--gc-interval=-1") + support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); if (support_smi_only_arrays) { diff --git a/deps/v8/test/mjsunit/osr-elements-kind.js b/deps/v8/test/mjsunit/osr-elements-kind.js index 6d3c8176af..8d43377321 100644 --- a/deps/v8/test/mjsunit/osr-elements-kind.js +++ b/deps/v8/test/mjsunit/osr-elements-kind.js @@ -40,6 +40,11 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. +// Reset the GC stress mode to be off. Needed because AllocationMementos only +// live for one gc, so a gc that happens in certain fragile areas of the test +// can break assumptions. +%SetFlags("--gc-interval=-1") + support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); if (support_smi_only_arrays) { diff --git a/deps/v8/test/mjsunit/regexp-global.js b/deps/v8/test/mjsunit/regexp-global.js index 093dba17c1..8501699458 100644 --- a/deps/v8/test/mjsunit/regexp-global.js +++ b/deps/v8/test/mjsunit/regexp-global.js @@ -214,7 +214,7 @@ function test_match(result_expectation, // Test for different number of matches. -for (var m = 0; m < 200; m++) { +for (var m = 0; m < 33; m++) { // Create string that matches m times. var subject = ""; var test_1_expectation = ""; diff --git a/deps/v8/test/mjsunit/regress/regress-1713.js b/deps/v8/test/mjsunit/regress/regress-1713.js deleted file mode 100644 index 0af1144a15..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-1713.js +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --always-compact --expose-gc - -var O = { get f() { return 0; } }; - -var CODE = []; - -var R = []; - -function Allocate4Kb(N) { - var arr = []; - do {arr.push(new Array(1024));} while (--N > 0); - return arr; -} - -function AllocateXMb(X) { - return Allocate4Kb((1024 * X) / 4); -} - -function Node(v, next) { this.v = v; this.next = next; } - -Node.prototype.execute = function (O) { - var n = this; - while (n.next !== null) n = n.next; - n.v(O); -}; - -function LongList(N, x) { - if (N == 0) return new Node(x, null); - return new Node(new Array(1024), LongList(N - 1, x)); -} - -var L = LongList(1024, function (O) { - for (var i = 0; i < 5; i++) O.f; -}); - - - -function Incremental(O, x) { - if (!x) { - return; - } - function CreateCode(i) { - var f = new Function("return O.f_" + i); - CODE.push(f); - f(); // compile - f(); // compile - f(); // compile - } - - for (var i = 0; i < 1e4; i++) CreateCode(i); - gc(); - gc(); - gc(); - - print(">>> 1 <<<"); - - L.execute(O); - - try {} catch (e) {} - - L = null; - print(">>> 2 <<<"); - AllocateXMb(8); - //rint("1"); - //llocateXMb(8); - //rint("1"); - //llocateXMb(8); - -} - -function foo(O, x) { - Incremental(O, x); - - print('f'); - - for (var i = 0; i < 5; i++) O.f; - - - print('g'); - - bar(x); -} - -function bar(x) { - if (!x) return; - %DeoptimizeFunction(foo); - AllocateXMb(8); - AllocateXMb(8); -} - -var O1 = {}; -var O2 = {}; -var O3 = {}; -var O4 = {f:0}; - -foo(O1, false); -foo(O2, false); -foo(O3, false); -%OptimizeFunctionOnNextCall(foo); -foo(O4, true); diff --git a/deps/v8/test/mjsunit/regress/regress-1713b.js b/deps/v8/test/mjsunit/regress/regress-1713b.js deleted file mode 100644 index cc16bf5119..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-1713b.js +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --always-compact --expose-gc - -var O = { get f() { return 0; } }; - -var CODE = []; - -var R = []; - -function Allocate4Kb(N) { - var arr = []; - do {arr.push(new Array(1024));} while (--N > 0); - return arr; -} - -function AllocateXMb(X) { - return Allocate4Kb((1024 * X) / 4); -} - -function Node(v, next) { this.v = v; this.next = next; } - -Node.prototype.execute = function (O) { - var n = this; - while (n.next !== null) n = n.next; - n.v(O); -}; - -function LongList(N, x) { - if (N == 0) return new Node(x, null); - return new Node(new Array(1024), LongList(N - 1, x)); -} - -var L = LongList(1024, function (O) { - for (var i = 0; i < 5; i++) O.f; -}); - - - -%NeverOptimizeFunction(Incremental); -function Incremental(O, x) { - if (!x) { - return; - } - function CreateCode(i) { - var f = new Function("return O.f_" + i); - CODE.push(f); - f(); // compile - f(); // compile - f(); // compile - } - - for (var i = 0; i < 1e4; i++) CreateCode(i); - gc(); - gc(); - gc(); - - print(">>> 1 <<<"); - - L.execute(O); - - L = null; - print(">>> 2 <<<"); - AllocateXMb(8); - //rint("1"); - //llocateXMb(8); - //rint("1"); - //llocateXMb(8); - -} - -function foo(O, x) { - Incremental(O, x); - - print('f'); - - for (var i = 0; i < 5; i++) O.f; - - - print('g'); - - bar(x); -} - -function bar(x) { - if (!x) return; - %DeoptimizeFunction(foo); - AllocateXMb(8); - AllocateXMb(8); -} - -var O1 = {}; -var O2 = {}; -var O3 = {}; -var O4 = {f:0}; - -foo(O1, false); -foo(O2, false); -foo(O3, false); -%OptimizeFunctionOnNextCall(foo); -foo(O4, true); diff --git a/deps/v8/test/mjsunit/regress/regress-2612.js b/deps/v8/test/mjsunit/regress/regress-2612.js index 06db07733d..ac6028f14c 100644 --- a/deps/v8/test/mjsunit/regress/regress-2612.js +++ b/deps/v8/test/mjsunit/regress/regress-2612.js @@ -57,11 +57,11 @@ function varname(i) { var source = "var "; -for (var i = 0; i < 1000; i++) { +for (var i = 0; i < 750; i++) { source += [varname(i), "=", rand(), ","].join(""); } -for (var i = 1000; i < 100000; i++) { +for (var i = 750; i < 3000; i++) { source += [varname(i), "=", varname(randi(i)), "+", varname(randi(i)), ","].join(""); @@ -73,4 +73,3 @@ var f = new Function(source); f(); %OptimizeFunctionOnNextCall(f); f(); - diff --git a/deps/v8/test/mjsunit/regress/regress-2931.js b/deps/v8/test/mjsunit/regress/regress-2931.js new file mode 100644 index 0000000000..a2ea912682 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-2931.js @@ -0,0 +1,34 @@ +// Copyright 2009 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Typed array constructors should be immune from changes to +// value of ArrayBuffer on global object. +// See http://code.google.com/p/v8/issues/detail?id=294 + +this.ArrayBuffer = function() { throw Error('BAM'); }; +var u8 = new Uint8Array(100); +assertSame(100, u8.byteLength); diff --git a/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js b/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js new file mode 100644 index 0000000000..0b4af75424 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js @@ -0,0 +1,38 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +var o = { a: 0 }; + +function f(x) { return -o.a + 0; }; + +assertEquals("Infinity", String(1/f())); +assertEquals("Infinity", String(1/f())); +%OptimizeFunctionOnNextCall(f); +assertEquals("Infinity", String(1/f())); + diff --git a/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js b/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js new file mode 100644 index 0000000000..129e1980a4 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js @@ -0,0 +1,31 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var a = []; +Object.defineProperty(a, 0, {}); +assertThrows(function() { a.pop(); }); + diff --git a/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js b/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js new file mode 100644 index 0000000000..c6cbaf7ebf --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js @@ -0,0 +1,168 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --noenable-sse2 + +// general tests +var e31 = Math.pow(2, 31); + +assertEquals(-e31, -1*e31); +assertEquals(e31, -1*e31*(-1)); +assertEquals(e31, -1*-e31); +assertEquals(e31, -e31*(-1)); + +var x = {toString : function() {return 1}} +function add(a,b){return a+b;} +add(1,x); +add(1,x); +%OptimizeFunctionOnNextCall(add); +add(1,x); +x.toString = function() {return "2"}; + +assertEquals(add(1,x), "12"); + +// Test the correct placement of the simulates in TruncateToNumber: +function Checker() { + this.str = "1"; + var toStringCalled = 0; + var toStringExpected = 0; + this.toString = function() { + toStringCalled++; + return this.str; + }; + this.check = function() { + toStringExpected++; + assertEquals(toStringExpected, toStringCalled); + }; +}; +var left = new Checker(); +var right = new Checker(); + +function test(fun,check_fun,a,b,does_throw) { + left.str = a; + right.str = b; + try { + assertEquals(check_fun(a,b), fun(left, right)); + assertTrue(!does_throw); + } catch(e) { + if (e instanceof TypeError) { + assertTrue(!!does_throw); + } else { + throw e; + } + } finally { + left.check(); + if (!does_throw || does_throw>1) { + right.check(); + } + } +} + +function minus(a,b) { return a-b }; +function check_minus(a,b) { return a-b }; +function mod(a,b) { return a%b }; +function check_mod(a,b) { return a%b }; + +test(minus,check_minus,1,2); +// Bailout on left +test(minus,check_minus,1<<30,1); +// Bailout on right +test(minus,check_minus,1,1<<30); +// Bailout on result +test(minus,check_minus,1<<30,-(1<<30)); + +// Some more interesting things +test(minus,check_minus,1,1.4); +test(minus,check_minus,1.3,4); +test(minus,check_minus,1.3,1.4); +test(minus,check_minus,1,2); +test(minus,check_minus,1,undefined); +test(minus,check_minus,1,2); +test(minus,check_minus,1,true); +test(minus,check_minus,1,2); +test(minus,check_minus,1,null); +test(minus,check_minus,1,2); +test(minus,check_minus,1,""); +test(minus,check_minus,1,2); + +// Throw on left +test(minus,check_minus,{},1,1); +// Throw on right +test(minus,check_minus,1,{},2); +// Throw both +test(minus,check_minus,{},{},1); + +test(minus,check_minus,1,2); + +// Now with optimized code +test(mod,check_mod,1,2); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1,2); + +test(mod,check_mod,1<<30,1); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1<<30,1); +test(mod,check_mod,1,1<<30); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1,1<<30); +test(mod,check_mod,1<<30,-(1<<30)); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1<<30,-(1<<30)); + +test(mod,check_mod,1,{},2); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1,{},2); + +test(mod,check_mod,1,2); + + +// test oddballs +function t1(a, b) {return a-b} +assertEquals(t1(1,2), 1-2); +assertEquals(t1(2,true), 2-1); +assertEquals(t1(false,2), 0-2); +assertEquals(t1(1,2.4), 1-2.4); +assertEquals(t1(1.3,2.4), 1.3-2.4); +assertEquals(t1(true,2.4), 1-2.4); +assertEquals(t1(1,undefined), 1-NaN); +assertEquals(t1(1,1<<30), 1-(1<<30)); +assertEquals(t1(1,2), 1-2); + +function t2(a, b) {return a/b} +assertEquals(t2(1,2), 1/2); +assertEquals(t2(null,2), 0/2); +assertEquals(t2(null,-2), 0/-2); +assertEquals(t2(2,null), 2/0); +assertEquals(t2(-2,null), -2/0); +assertEquals(t2(1,2.4), 1/2.4); +assertEquals(t2(1.3,2.4), 1.3/2.4); +assertEquals(t2(null,2.4), 0/2.4); +assertEquals(t2(1.3,null), 1.3/0); +assertEquals(t2(undefined,2), NaN/2); +assertEquals(t2(1,1<<30), 1/(1<<30)); +assertEquals(t2(1,2), 1/2); + diff --git a/deps/v8/test/mjsunit/regress/regress-binop.js b/deps/v8/test/mjsunit/regress/regress-binop.js new file mode 100644 index 0000000000..7a8b41924d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-binop.js @@ -0,0 +1,181 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// general tests +var e31 = Math.pow(2, 31); + +assertEquals(-e31, -1*e31); +assertEquals(e31, -1*e31*(-1)); +assertEquals(e31, -1*-e31); +assertEquals(e31, -e31*(-1)); + +var x = {toString : function() {return 1}} +function add(a,b){return a+b;} +add(1,x); +add(1,x); +%OptimizeFunctionOnNextCall(add); +add(1,x); +x.toString = function() {return "2"}; + +assertEquals(add(1,x), "12"); + +// Test the correct placement of the simulates in TruncateToNumber: +function Checker() { + this.str = "1"; + var toStringCalled = 0; + var toStringExpected = 0; + this.toString = function() { + toStringCalled++; + return this.str; + }; + this.check = function() { + toStringExpected++; + assertEquals(toStringExpected, toStringCalled); + }; +}; +var left = new Checker(); +var right = new Checker(); + +function test(fun,check_fun,a,b,does_throw) { + left.str = a; + right.str = b; + try { + assertEquals(check_fun(a,b), fun(left, right)); + assertTrue(!does_throw); + } catch(e) { + if (e instanceof TypeError) { + assertTrue(!!does_throw); + } else { + throw e; + } + } finally { + left.check(); + if (!does_throw || does_throw>1) { + right.check(); + } + } +} + +function minus(a,b) { return a-b }; +function check_minus(a,b) { return a-b }; +function mod(a,b) { return a%b }; +function check_mod(a,b) { return a%b }; + +test(minus,check_minus,1,2); +// Bailout on left +test(minus,check_minus,1<<30,1); +// Bailout on right +test(minus,check_minus,1,1<<30); +// Bailout on result +test(minus,check_minus,1<<30,-(1<<30)); + +// Some more interesting things +test(minus,check_minus,1,1.4); +test(minus,check_minus,1.3,4); +test(minus,check_minus,1.3,1.4); +test(minus,check_minus,1,2); +test(minus,check_minus,1,undefined); +test(minus,check_minus,1,2); +test(minus,check_minus,1,true); +test(minus,check_minus,1,2); +test(minus,check_minus,1,null); +test(minus,check_minus,1,2); +test(minus,check_minus,1,""); +test(minus,check_minus,1,2); + +// Throw on left +test(minus,check_minus,{},1,1); +// Throw on right +test(minus,check_minus,1,{},2); +// Throw both +test(minus,check_minus,{},{},1); + +test(minus,check_minus,1,2); + +// Now with optimized code +test(mod,check_mod,1,2); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1,2); + +test(mod,check_mod,1<<30,1); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1<<30,1); +test(mod,check_mod,1,1<<30); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1,1<<30); +test(mod,check_mod,1<<30,-(1<<30)); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1<<30,-(1<<30)); + +test(mod,check_mod,1,{},2); +%OptimizeFunctionOnNextCall(mod); +test(mod,check_mod,1,{},2); + +test(mod,check_mod,1,2); + + +// test oddballs +function t1(a, b) {return a-b} +assertEquals(t1(1,2), 1-2); +assertEquals(t1(2,true), 2-1); +assertEquals(t1(false,2), 0-2); +assertEquals(t1(1,2.4), 1-2.4); +assertEquals(t1(1.3,2.4), 1.3-2.4); +assertEquals(t1(true,2.4), 1-2.4); +assertEquals(t1(1,undefined), 1-NaN); +assertEquals(t1(1,1<<30), 1-(1<<30)); +assertEquals(t1(1,2), 1-2); + +function t2(a, b) {return a/b} +assertEquals(t2(1,2), 1/2); +assertEquals(t2(null,2), 0/2); +assertEquals(t2(null,-2), 0/-2); +assertEquals(t2(2,null), 2/0); +assertEquals(t2(-2,null), -2/0); +assertEquals(t2(1,2.4), 1/2.4); +assertEquals(t2(1.3,2.4), 1.3/2.4); +assertEquals(t2(null,2.4), 0/2.4); +assertEquals(t2(1.3,null), 1.3/0); +assertEquals(t2(undefined,2), NaN/2); +assertEquals(t2(1,1<<30), 1/(1<<30)); +assertEquals(t2(1,2), 1/2); + + +// Assert that the hole is not truncated to nan for string add. +function string_add(a,i) { + var d = [0.1, ,0.3]; + return a + d[i]; +} + +string_add(1.1, 0); +string_add("", 0); +%OptimizeFunctionOnNextCall(string_add); +string_add(1.1, 0); +// There comes the hole +assertEquals("undefined", string_add("", 1)); diff --git a/deps/v8/test/mjsunit/regress/regress-compare-constant-doubles.js b/deps/v8/test/mjsunit/regress/regress-compare-constant-doubles.js new file mode 100644 index 0000000000..0f8ffe307d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-compare-constant-doubles.js @@ -0,0 +1,58 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +var left = 1.5; +var right; + +var keepalive; + +function foo() { + // Fill XMM registers with cruft. + var a1 = Math.sin(1) + 10; + var a2 = a1 + 1; + var a3 = a2 + 1; + var a4 = a3 + 1; + var a5 = a4 + 1; + var a6 = a5 + 1; + keepalive = [a1, a2, a3, a4, a5, a6]; + + // Actual test. + if (left < right) return "ok"; + return "bad"; +} + +function prepare(base) { + right = 0.5 * base; +} + +prepare(21); +assertEquals("ok", foo()); +assertEquals("ok", foo()); +%OptimizeFunctionOnNextCall(foo); +assertEquals("ok", foo()); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-305309.js b/deps/v8/test/mjsunit/regress/regress-crbug-305309.js new file mode 100644 index 0000000000..cd89bedc11 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-305309.js @@ -0,0 +1,49 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function BadProto() { + this.constant_function = function() {}; + this.one = 1; + this.two = 2; +} +var b1 = new BadProto(); +var b2 = new BadProto(); + +function Ctor() {} +Ctor.prototype = b1; +var a = new Ctor(); + +function Two(x) { + return x.two; +} +assertEquals(2, Two(a)); +assertEquals(2, Two(a)); +b2.constant_function = "no longer constant!"; +%OptimizeFunctionOnNextCall(Two); +assertEquals(2, Two(a)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-306851.js b/deps/v8/test/mjsunit/regress/regress-crbug-306851.js new file mode 100644 index 0000000000..77b711a656 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-306851.js @@ -0,0 +1,52 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function Counter() { + this.value = 0; +}; + +Object.defineProperty(Counter.prototype, 'count', { + get: function() { return this.value; }, + set: function(value) { this.value = value; } +}); + +var obj = new Counter(); + +function bummer() { + obj.count++; + return obj.count; +} + +assertEquals(1, bummer()); +assertEquals(2, bummer()); +assertEquals(3, bummer()); +%OptimizeFunctionOnNextCall(bummer); +assertEquals(4, bummer()); +assertEquals(5, bummer()); +assertEquals(6, bummer()); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-84186.js b/deps/v8/test/mjsunit/regress/regress-crbug-309623.js index 865bf9eb91..12473c7947 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-84186.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-309623.js @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2013 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -25,17 +25,22 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Test that the expected string is parsed in the json parser when the length -// is so big that the string can't fit in new space, and it includes special -// characters. +// Flags: --allow-natives-syntax -var json = '{"key":"'; -var key = ''; -var expected = ''; -for(var i = 0; i < 60000; i++) { - key = key + "TESTING" + i + "\\n"; - expected = expected + "TESTING" + i + "\n"; +var u = new Uint32Array(2); +u[0] = 1; +u[1] = 0xEE6B2800; + +var a = [0, 1, 2]; +a[0] = 0; // Kill the COW. +assertTrue(%HasFastSmiElements(a)); + +function foo(i) { + a[0] = u[i]; + return a[0]; } -json = json + key + '"}'; -var out = JSON.parse(json); -assertEquals(expected, out.key); + +assertEquals(u[0], foo(0)); +assertEquals(u[0], foo(0)); +%OptimizeFunctionOnNextCall(foo); +assertEquals(u[1], foo(1)); diff --git a/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js b/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js index 58a0b1c869..b08a94257c 100644 --- a/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js +++ b/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js @@ -27,7 +27,7 @@ // Flags: --fold-constants --nodead-code-elimination // Flags: --expose-gc --allow-natives-syntax -// Flags: --concurrent-recompilation --concurrent-recompilation-delay=300 +// Flags: --concurrent-recompilation --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -39,12 +39,14 @@ function test(fun) { fun(); // Mark for concurrent optimization. %OptimizeFunctionOnNextCall(fun, "concurrent"); - //Trigger optimization in the background. + // Kick off recompilation. fun(); - //Tenure cons string. + // Tenure cons string after compile graph has been created. gc(); - // In the mean time, concurrent recompiling is not complete yet. + // In the mean time, concurrent recompiling is still blocked. assertUnoptimized(fun, "no sync"); + // Let concurrent recompilation proceed. + %UnblockConcurrentRecompilation(); // Concurrent recompilation eventually finishes, embeds tenured cons string. assertOptimized(fun, "sync"); // Visit embedded cons string during mark compact. diff --git a/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js b/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js index 8bf95ec5aa..c637be5497 100644 --- a/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js +++ b/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --expose-debug-as debug --allow-natives-syntax -// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100 +// Flags: --concurrent-recompilation --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -60,8 +60,14 @@ f(); %OptimizeFunctionOnNextCall(f, "concurrent"); // Mark with builtin. f(); // Kick off concurrent recompilation. +// After compile graph has been created... Debug.setListener(listener); // Activate debugger. Debug.setBreakPoint(f, 2, 0); // Force deopt. + +// At this point, concurrent recompilation is still being blocked. +assertUnoptimized(f, "no sync"); +// Let concurrent recompilation proceed. +%UnblockConcurrentRecompilation(); // Sync with optimization thread. But no optimized code is installed. assertUnoptimized(f, "sync"); diff --git a/deps/v8/test/mjsunit/regress/regress-parse-object-literal.js b/deps/v8/test/mjsunit/regress/regress-parse-object-literal.js new file mode 100644 index 0000000000..96d63c2c12 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-parse-object-literal.js @@ -0,0 +1,29 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Should throw, not crash. +assertThrows("var o = { get /*space*/ () {} }"); diff --git a/deps/v8/test/mjsunit/regress/regress-parse-use-strict.js b/deps/v8/test/mjsunit/regress/regress-parse-use-strict.js new file mode 100644 index 0000000000..9dd0f4c97c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-parse-use-strict.js @@ -0,0 +1,42 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Filler long enough to trigger lazy parsing. +var filler = "/*" + new Array(1024).join('x') + "*/"; + +// Snippet trying to switch to strict mode. +var strict = '"use strict"; with({}) {}'; + +// Test switching to strict mode after string literal. +assertThrows('function f() { "use sanity";' + strict + '}'); +assertThrows('function f() { "use sanity";' + strict + filler + '}'); + +// Test switching to strict mode after function declaration. +// We must use eval instead of assertDoesNotThrow here to make sure that +// lazy parsing is triggered. Otherwise the bug won't reproduce. +eval('function f() { function g() {}' + strict + '}'); +eval('function f() { function g() {}' + strict + filler + '}'); diff --git a/deps/v8/test/mjsunit/regress/regress-polymorphic-load.js b/deps/v8/test/mjsunit/regress/regress-polymorphic-load.js new file mode 100644 index 0000000000..2545e85f60 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-polymorphic-load.js @@ -0,0 +1,43 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(o) { + return o.x; +} + +var o1 = {x:1}; +var o2 = {__proto__: {x:2}}; + +f(o2); +f(o2); +f(o2); +f(o1); +%OptimizeFunctionOnNextCall(f); +assertEquals(1, f(o1)); +assertEquals(2, f(o2)); diff --git a/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js b/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js index 2fad5ca0d2..a9c20ec844 100644 --- a/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js +++ b/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --expose-debug-as debug --allow-natives-syntax -// Flags: --concurrent-recompilation-delay=300 +// Flags: --block-concurrent-recompilation if (!%IsConcurrentRecompilationSupported()) { print("Concurrent recompilation is disabled. Skipping this test."); @@ -46,17 +46,22 @@ function bar() { } foo(); -// Mark and trigger concurrent optimization. +// Mark and kick off recompilation. %OptimizeFunctionOnNextCall(foo, "concurrent"); foo(); // Set break points on an unrelated function. This clears both optimized // and (shared) unoptimized code on foo, and sets both to lazy-compile builtin. // Clear the break point immediately after to deactivate the debugger. +// Do all of this after compile graph has been created. Debug.setBreakPoint(bar, 0, 0); Debug.clearAllBreakPoints(); +// At this point, concurrent recompilation is still blocked. +assertUnoptimized(foo, "no sync"); +// Let concurrent recompilation proceed. +%UnblockConcurrentRecompilation(); + // Install optimized code when concurrent optimization finishes. // This needs to be able to deal with shared code being a builtin. assertUnoptimized(foo, "sync"); - diff --git a/deps/v8/test/mjsunit/unbox-double-arrays.js b/deps/v8/test/mjsunit/unbox-double-arrays.js index 4e8718eb3f..5ed404025f 100644 --- a/deps/v8/test/mjsunit/unbox-double-arrays.js +++ b/deps/v8/test/mjsunit/unbox-double-arrays.js @@ -345,8 +345,6 @@ function testOneArrayType(allocator) { -Infinity, expected_array_value(7)); - assertOptimized(test_various_stores); - // Make sure that we haven't converted from fast double. assertTrue(%HasFastDoubleElements(large_array)); } diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status index 9878730b2c..b27e991b98 100644 --- a/deps/v8/test/mozilla/mozilla.status +++ b/deps/v8/test/mozilla/mozilla.status @@ -42,807 +42,816 @@ # debugging. # -------------------------------------------------------------------- -prefix mozilla -def FAIL_OK = FAIL, OKAY +[ +[ALWAYS, { + ##################### NEEDS INVESTIGATION ############## + + # BUG(2893): These tests started to fail after i18n support was turned on. + # Need to investigate why. + 'ecma_3/Number/15.7.4.3-02': [PASS, FAIL], + 'ecma_3/Date/15.9.5.5-02': [PASS, FAIL], + + ##################### SKIPPED TESTS ##################### + + # This test checks that we behave properly in an out-of-memory + # situation. The test fails in V8 with an exception and takes a long + # time to do so. + 'js1_5/Regress/regress-271716-n': [SKIP], + + # BUG(960): This test has an insane amount of output when it times out, + # messing up ability to see other failures on the waterfall. + 'js1_5/extensions/regress-342960': [SKIP], + + # This test uses a unitialized variable. A Bug has been filed: + # https://bugzilla.mozilla.org/show_bug.cgi?id=575575 + 'js1_5/Array/regress-465980-02': [SKIP], + + # These tests are simply wrong (i.e., they do not test what they intend + # to test). + # In particular, these two compare numbers to NaN with != in the current + # version of the Mozilla tests. This is *fixed* in a later version. + # The tests should be re-enabled when switching to a new version. + 'ecma_3/Date/15.9.3.2-1': [SKIP], + 'js1_2/function/Number': [SKIP], + + # TODO(2018): Temporarily allow timeout in debug mode. + 'js1_5/GC/regress-203278-2': [PASS, ['mode == debug', TIMEOUT, FAIL]], + + ##################### SLOW TESTS ##################### + + # This takes a long time to run (~100 seconds). It should only be run + # by the really patient. + 'js1_5/GC/regress-324278': [SLOW], + + # This takes a long time to run because our indexOf operation is + # pretty slow - it causes a lot of GCs; see issue + # #926379. We could consider marking this SKIP because it takes a + # while to run to completion. + 'js1_5/GC/regress-338653': [SLOW], + + # This test is designed to run until it runs out of memory. This takes + # a very long time because it builds strings character by character + # and compiles a lot of regular expressions. We could consider marking + # this SKIP because it takes a while to run to completion. + 'js1_5/GC/regress-346794': [SLOW], + + # Runs out of memory while trying to build huge string of 'x' + # characters. This takes a long time to run (~32 seconds). + 'js1_5/GC/regress-348532': [SLOW], + + + ##################### FLAKY TESTS ##################### + + # These tests time out in debug mode but pass in product mode + 'js1_5/Regress/regress-360969-03': [PASS, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-360969-04': [PASS, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-360969-05': [PASS, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-360969-06': [PASS, ['mode == debug', TIMEOUT]], + 'js1_5/extensions/regress-365527': [PASS, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-280769-3': [PASS, ['mode == debug', FAIL]], + 'js1_5/Regress/regress-203278-1': [PASS, ['mode == debug', FAIL]], + 'js1_5/Regress/regress-244470': [PASS, ['mode == debug', FAIL]], + 'ecma_3/RegExp/regress-209067': [PASS, ['mode == debug', FAIL]], + 'js1_5/GC/regress-278725': [PASS, ['mode == debug', FAIL]], + # http://b/issue?id=1206983 + 'js1_5/Regress/regress-367561-03': [PASS, ['mode == debug', FAIL]], + 'ecma/Date/15.9.5.10-2': [PASS, FAIL, ['mode == debug', TIMEOUT]], -##################### SKIPPED TESTS ##################### - -# This test checks that we behave properly in an out-of-memory -# situation. The test fails in V8 with an exception and takes a long -# time to do so. -js1_5/Regress/regress-271716-n: SKIP - -# BUG(960): This test has an insane amount of output when it times out, -# messing up ability to see other failures on the waterfall. -js1_5/extensions/regress-342960: SKIP - -# This test uses a unitialized variable. A Bug has been filed: -# https://bugzilla.mozilla.org/show_bug.cgi?id=575575 -js1_5/Array/regress-465980-02: SKIP - -# These tests are simply wrong (i.e., they do not test what they intend -# to test). -# In particular, these two compare numbers to NaN with != in the current -# version of the Mozilla tests. This is *fixed* in a later version. -# The tests should be re-enabled when switching to a new version. -ecma_3/Date/15.9.3.2-1: SKIP -js1_2/function/Number: SKIP - -# TODO(2018): Temporarily allow timeout in debug mode. -js1_5/GC/regress-203278-2: PASS || (TIMEOUT || FAIL) if $mode == debug - -##################### SLOW TESTS ##################### - -# This takes a long time to run (~100 seconds). It should only be run -# by the really patient. -js1_5/GC/regress-324278: SLOW - -# This takes a long time to run because our indexOf operation is -# pretty slow - it causes a lot of GCs; see issue -# #926379. We could consider marking this SKIP because it takes a -# while to run to completion. -js1_5/GC/regress-338653: SLOW - -# This test is designed to run until it runs out of memory. This takes -# a very long time because it builds strings character by character -# and compiles a lot of regular expressions. We could consider marking -# this SKIP because it takes a while to run to completion. -js1_5/GC/regress-346794: SLOW - -# Runs out of memory while trying to build huge string of 'x' -# characters. This takes a long time to run (~32 seconds). -js1_5/GC/regress-348532: SLOW + # These tests create two Date objects just after each other and + # expects them to match. Sometimes this happens on the border + # between one second and the next. + 'ecma/Date/15.9.2.1': [PASS, FAIL], + 'ecma/Date/15.9.2.2-1': [PASS, FAIL], + 'ecma/Date/15.9.2.2-2': [PASS, FAIL], + 'ecma/Date/15.9.2.2-3': [PASS, FAIL], + 'ecma/Date/15.9.2.2-4': [PASS, FAIL], + 'ecma/Date/15.9.2.2-5': [PASS, FAIL], + 'ecma/Date/15.9.2.2-6': [PASS, FAIL], + # 1026139: These date tests fail on arm and mips + 'ecma/Date/15.9.5.29-1': [PASS, ['arch == arm or arch == mipsel', FAIL]], + 'ecma/Date/15.9.5.28-1': [PASS, ['arch == arm or arch == mipsel', FAIL]], -##################### FLAKY TESTS ##################### + # 1050186: Arm/MIPS vm is broken; probably unrelated to dates + 'ecma/Array/15.4.4.5-3': [PASS, ['arch == arm or arch == mipsel', FAIL]], + 'ecma/Date/15.9.5.22-2': [PASS, ['arch == arm or arch == mipsel', FAIL]], -# These tests time out in debug mode but pass in product mode -js1_5/Regress/regress-360969-03: PASS || TIMEOUT if $mode == debug -js1_5/Regress/regress-360969-04: PASS || TIMEOUT if $mode == debug -js1_5/Regress/regress-360969-05: PASS || TIMEOUT if $mode == debug -js1_5/Regress/regress-360969-06: PASS || TIMEOUT if $mode == debug -js1_5/extensions/regress-365527: PASS || TIMEOUT if $mode == debug + # Flaky test that fails due to what appears to be a bug in the test. + # Occurs depending on current time + 'ecma/Date/15.9.5.8': [PASS, FAIL], -js1_5/Regress/regress-280769-3: PASS || FAIL if $mode == debug -js1_5/Regress/regress-203278-1: PASS || FAIL if $mode == debug -js1_5/Regress/regress-244470: PASS || FAIL if $mode == debug -ecma_3/RegExp/regress-209067: PASS || FAIL if $mode == debug -js1_5/GC/regress-278725: PASS || FAIL if $mode == debug -# http://b/issue?id=1206983 -js1_5/Regress/regress-367561-03: PASS || FAIL if $mode == debug -ecma/Date/15.9.5.10-2: PASS || (FAIL || TIMEOUT if $mode == debug) + # Severely brain-damaged test. Access to local variables must not + # be more than 2.5 times faster than access to global variables? WTF? + 'js1_5/Regress/regress-169559': [PASS, FAIL], -# These tests create two Date objects just after each other and -# expects them to match. Sometimes this happens on the border -# between one second and the next. -ecma/Date/15.9.2.1: PASS || FAIL -ecma/Date/15.9.2.2-1: PASS || FAIL -ecma/Date/15.9.2.2-2: PASS || FAIL -ecma/Date/15.9.2.2-3: PASS || FAIL -ecma/Date/15.9.2.2-4: PASS || FAIL -ecma/Date/15.9.2.2-5: PASS || FAIL -ecma/Date/15.9.2.2-6: PASS || FAIL -# 1026139: These date tests fail on arm and mips -ecma/Date/15.9.5.29-1: PASS || FAIL if ($arch == arm || $arch == mipsel) -ecma/Date/15.9.5.28-1: PASS || FAIL if ($arch == arm || $arch == mipsel) + # Test that rely on specific timezone (not working in Denmark). + 'js1_5/Regress/regress-58116': [PASS, FAIL], -# 1050186: Arm/MIPS vm is broken; probably unrelated to dates -ecma/Array/15.4.4.5-3: PASS || FAIL if ($arch == arm || $arch == mipsel) -ecma/Date/15.9.5.22-2: PASS || FAIL if ($arch == arm || $arch == mipsel) -# Flaky test that fails due to what appears to be a bug in the test. -# Occurs depending on current time -ecma/Date/15.9.5.8: PASS || FAIL + # Flaky random() test. Tests the distribution of calls to Math.random(). + 'js1_5/Regress/regress-211590': [PASS, FAIL], -# Severely brain-damaged test. Access to local variables must not -# be more than 2.5 times faster than access to global variables? WTF? -js1_5/Regress/regress-169559: PASS || FAIL + # Flaky tests; expect BigO-order computations to yield 1, but the code + # cannot handle outliers. See bug #925864. + 'ecma_3/RegExp/regress-311414': [PASS, FAIL], + 'ecma_3/RegExp/regress-289669': [PASS, FAIL], + 'js1_5/String/regress-314890': [PASS, FAIL], + 'js1_5/String/regress-56940-01': [PASS, FAIL], + 'js1_5/String/regress-56940-02': [PASS, FAIL], + 'js1_5/String/regress-157334-01': [PASS, FAIL], + 'js1_5/String/regress-322772': [PASS, FAIL], + 'js1_5/Array/regress-99120-01': [PASS, FAIL], + 'js1_5/Array/regress-99120-02': [PASS, FAIL], + 'js1_5/Regress/regress-347306-01': [PASS, FAIL], + 'js1_5/Regress/regress-416628': [PASS, FAIL, ['mode == debug', TIMEOUT]], -# Test that rely on specific timezone (not working in Denmark). -js1_5/Regress/regress-58116: PASS || FAIL + # The following two tests assume that daylight savings time starts first + # Sunday in April. This is not true when executing the tests outside + # California! In Denmark the adjustment starts one week earlier. + # Tests based on shell that use dates in this gap are flaky. + 'ecma/Date/15.9.5.10-1': [PASS, FAIL], + 'ecma/Date/15.9.5.12-1': [PASS, FAIL], + 'ecma/Date/15.9.5.14': [PASS, FAIL], + 'ecma/Date/15.9.5.34-1': [PASS, FAIL], -# Flaky random() test. Tests the distribution of calls to Math.random(). -js1_5/Regress/regress-211590: PASS || FAIL + # These tests sometimes pass (in particular on Windows). They build up + # a lot of stuff on the stack, which normally causes a stack overflow, + # but sometimes it makes it through? + 'js1_5/Regress/regress-98901': [PASS, FAIL], -# Flaky tests; expect BigO-order computations to yield 1, but the code -# cannot handle outliers. See bug #925864. -ecma_3/RegExp/regress-311414: PASS || FAIL -ecma_3/RegExp/regress-289669: PASS || FAIL -js1_5/String/regress-314890: PASS || FAIL -js1_5/String/regress-56940-01: PASS || FAIL -js1_5/String/regress-56940-02: PASS || FAIL -js1_5/String/regress-157334-01: PASS || FAIL -js1_5/String/regress-322772: PASS || FAIL -js1_5/Array/regress-99120-01: PASS || FAIL -js1_5/Array/regress-99120-02: PASS || FAIL -js1_5/Regress/regress-347306-01: PASS || FAIL -js1_5/Regress/regress-416628: PASS || FAIL || TIMEOUT if $mode == debug + # Tests that sorting arrays of ints is less than 3 times as fast + # as sorting arrays of strings. + 'js1_5/extensions/regress-371636': [PASS, FAIL, ['mode == debug', TIMEOUT]], -# The following two tests assume that daylight savings time starts first Sunday -# in April. This is not true when executing the tests outside California! -# In Denmark the adjustment starts one week earlier!. -# Tests based on shell that use dates in this gap are flaky. -ecma/Date/15.9.5.10-1: PASS || FAIL -ecma/Date/15.9.5.12-1: PASS || FAIL -ecma/Date/15.9.5.14: PASS || FAIL -ecma/Date/15.9.5.34-1: PASS || FAIL + # Tests depend on GC timings. Inherently flaky. + 'js1_5/GC/regress-383269-01': [PASS, FAIL], + 'js1_5/GC/regress-383269-02': [PASS, FAIL], + 'js1_5/Regress/regress-404755': [PASS, FAIL], -# These tests sometimes pass (in particular on Windows). They build up -# a lot of stuff on the stack, which normally causes a stack overflow, -# but sometimes it makes it through? -js1_5/Regress/regress-98901: PASS || FAIL + # Test that depends on timer resolution. Fails every now and then + # if we're unlucky enough to get a context switch at a bad time. + 'js1_5/extensions/regress-363258': [PASS, FAIL], -# Tests that sorting arrays of ints is less than 3 times as fast -# as sorting arrays of strings. -js1_5/extensions/regress-371636: PASS || FAIL || TIMEOUT if $mode == debug + # Test that assumes specific runtime for a regexp, flaky in debug mode. + 'ecma_3/RegExp/regress-85721': [PASS, ['mode == debug', FAIL]], -# Tests depend on GC timings. Inherently flaky. -js1_5/GC/regress-383269-01: PASS || FAIL -js1_5/GC/regress-383269-02: PASS || FAIL -js1_5/Regress/regress-404755: PASS || FAIL + # Test that assumes specific execution time, flaky in debug mode. + 'js1_5/Array/regress-101964': [PASS, ['mode == debug', FAIL]], -# Test that depends on timer resolution. Fails every now and then -# if we're unlucky enough to get a context switch at a bad time. -js1_5/extensions/regress-363258: PASS || FAIL + ##################### INCOMPATIBLE TESTS ##################### -# Test that assumes specific runtime for a regexp, flaky in debug mode. -ecma_3/RegExp/regress-85721: PASS || FAIL if $mode == debug + # This section is for tests that fail in both V8 and JSC. Thus they + # have been determined to be incompatible between Mozilla and V8/JSC. + # toPrecision argument restricted to range 1..21 in JSC/V8 and ECMA-262 + 'js1_5/Regress/regress-452346': [FAIL_OK], -# Test that assumes specific execution time, flaky in debug mode. -js1_5/Array/regress-101964: PASS || FAIL if $mode == debug + # Fail because it calls builtins as functions and do not expect the + # builtin to have undefined as the receiver. + 'ecma/String/15.5.4.6-2': [FAIL_OK], + # Fail because it expects String.prototype.split to distinguish whether + # separator was undefined or not passed at all. + 'ecma/String/15.5.4.8-2': [FAIL_OK], -##################### INCOMPATIBLE TESTS ##################### + # Fail because of toLowerCase and toUpperCase conversion. + 'ecma/String/15.5.4.11-2': [FAIL_OK], + 'ecma/String/15.5.4.11-5': [FAIL_OK], + 'ecma/String/15.5.4.12-1': [FAIL_OK], + 'ecma/String/15.5.4.12-4': [FAIL_OK], -# This section is for tests that fail in both V8 and JSC. Thus they -# have been determined to be incompatible between Mozilla and V8/JSC. + # This test uses an older version of the unicode standard that fails + # us because we correctly convert the armenian small ligature ech-yiwn + # to the two upper-case characters ECH and YIWN, whereas the older + # unicode version converts it to itself. + 'ecma/String/15.5.4.12-5': [FAIL_OK], -# toPrecision argument restricted to range 1..21 in JSC/V8 and ECMA-262 -js1_5/Regress/regress-452346: FAIL_OK + # Creates a linked list of arrays until we run out of memory or timeout. + 'js1_5/Regress/regress-312588': [SKIP], -# Fail because it calls builtins as functions and do not expect the -# builtin to have undefined as the receiver. -ecma/String/15.5.4.6-2: FAIL_OK -# Fail because it expects String.prototype.split to distinguish whether -# separator was undefined or not passed at all. -ecma/String/15.5.4.8-2: FAIL_OK + # Runs out of memory because it compiles huge functions. + 'js1_5/Function/regress-338001': [FAIL_OK], + 'js1_5/Function/regress-338121-01': [FAIL_OK], + 'js1_5/Function/regress-338121-02': [FAIL_OK], + 'js1_5/Function/regress-338121-03': [FAIL_OK], -# Fail because of toLowerCase and toUpperCase conversion. -ecma/String/15.5.4.11-2: FAIL_OK -ecma/String/15.5.4.11-5: FAIL_OK -ecma/String/15.5.4.12-1: FAIL_OK -ecma/String/15.5.4.12-4: FAIL_OK + # Expectes 'prototype' property of functions to be enumerable. + 'js1_5/Function/10.1.6-01': [FAIL_OK], -# This test uses an older version of the unicode standard that fails -# us because we correctly convert the armenian small ligature ech-yiwn -# to the two upper-case characters ECH and YIWN, whereas the older -# unicode version converts it to itself. -ecma/String/15.5.4.12-5: FAIL_OK + #:=== RegExp:=== + # We don't match the syntax error message of Mozilla for invalid + # RegExp flags. + 'ecma_3/RegExp/15.10.4.1-6': [FAIL_OK], -# Creates a linked list of arrays until we run out of memory or timeout. -js1_5/Regress/regress-312588: SKIP + # PCRE doesn't allow subpattern nesting deeper than 200, this tests + # depth 500. JSC detects the case, and return null from the match, + # and passes this test (the test doesn't check for a correct return + # value). + 'ecma_3/RegExp/regress-119909': [PASS, FAIL_OK], -# Runs out of memory because it compiles huge functions. -js1_5/Function/regress-338001: FAIL_OK -js1_5/Function/regress-338121-01: FAIL_OK -js1_5/Function/regress-338121-02: FAIL_OK -js1_5/Function/regress-338121-03: FAIL_OK + # Difference in the way capturing subpatterns work. In JS, when the + # 'minimum repeat count' is reached, the empty string must not match. + # In this case, we are similar but not identical to JSC. Hard to + # support the JS behavior with PCRE, so maybe emulate JSC? + 'ecma_3/RegExp/regress-209919': [PASS, FAIL_OK], + 'js1_5/extensions/regress-459606': [PASS, FAIL_OK], -# Expectes 'prototype' property of functions to be enumerable. -js1_5/Function/10.1.6-01: FAIL_OK -#:=== RegExp:=== -# We don't match the syntax error message of Mozilla for invalid -# RegExp flags. -ecma_3/RegExp/15.10.4.1-6: FAIL_OK + # PCRE's match limit is reached. SpiderMonkey hangs on the first one, + # JSC returns true somehow. Maybe they up the match limit? There is + # an open V8 bug 676063 about this. + 'ecma_3/RegExp/regress-330684': [TIMEOUT], -# PCRE doesn't allow subpattern nesting deeper than 200, this tests -# depth 500. JSC detects the case, and return null from the match, -# and passes this test (the test doesn't check for a correct return -# value). -ecma_3/RegExp/regress-119909: PASS || FAIL_OK + # This test contains a regexp that runs exponentially long. Spidermonkey + # standalone will hang, though apparently inside Firefox it will trigger a + # long-running-script timeout. JSCRE passes by hitting the matchLimit and + # just pretending that an exhaustive search found no match. + 'ecma_3/RegExp/regress-307456': [PASS, TIMEOUT], -# Difference in the way capturing subpatterns work. In JS, when the -# 'minimum repeat count' is reached, the empty string must not match. -# In this case, we are similar but not identical to JSC. Hard to -# support the JS behavior with PCRE, so maybe emulate JSC? -ecma_3/RegExp/regress-209919: PASS || FAIL_OK -js1_5/extensions/regress-459606: PASS || FAIL_OK + # We do not detect overflow in bounds for back references and {} + # quantifiers. Might fix by parsing numbers differently? + 'js1_5/Regress/regress-230216-2': [FAIL_OK], -# PCRE's match limit is reached. SpiderMonkey hangs on the first one, -# JSC returns true somehow. Maybe they up the match limit? There is -# an open V8 bug 676063 about this. -ecma_3/RegExp/regress-330684: TIMEOUT + # Regexp too long for PCRE. + 'js1_5/Regress/regress-280769': [PASS, FAIL], + 'js1_5/Regress/regress-280769-1': [PASS, FAIL], + 'js1_5/Regress/regress-280769-2': [PASS, FAIL], + 'js1_5/Regress/regress-280769-4': [PASS, FAIL], + 'js1_5/Regress/regress-280769-5': [PASS, FAIL], -# This test contains a regexp that runs exponentially long. Spidermonkey -# standalone will hang, though apparently inside Firefox it will trigger a -# long-running-script timeout. JSCRE passes by hitting the matchLimit and -# just pretending that an exhaustive search found no match. -ecma_3/RegExp/regress-307456: PASS || TIMEOUT + # We do not support static RegExp.multiline - should we?. + 'js1_2/regexp/RegExp_multiline': [FAIL_OK], + 'js1_2/regexp/RegExp_multiline_as_array': [FAIL_OK], + 'js1_2/regexp/beginLine': [FAIL_OK], + 'js1_2/regexp/endLine': [FAIL_OK], -# We do not detect overflow in bounds for back references and {} -# quantifiers. Might fix by parsing numbers differently? -js1_5/Regress/regress-230216-2: FAIL_OK + # We no longer let calls to test and exec with no argument implicitly + # use the previous input. + 'js1_2/regexp/RegExp_input': [FAIL_OK], + 'js1_2/regexp/RegExp_input_as_array': [FAIL_OK], -# Regexp too long for PCRE. -js1_5/Regress/regress-280769: PASS || FAIL -js1_5/Regress/regress-280769-1: PASS || FAIL -js1_5/Regress/regress-280769-2: PASS || FAIL -js1_5/Regress/regress-280769-4: PASS || FAIL -js1_5/Regress/regress-280769-5: PASS || FAIL + # To be compatible with safari typeof a regexp yields 'function'; + # in firefox it yields 'object'. + 'js1_2/function/regexparg-1': [FAIL_OK], -# We do not support static RegExp.multiline - should we?. -js1_2/regexp/RegExp_multiline: FAIL_OK -js1_2/regexp/RegExp_multiline_as_array: FAIL_OK -js1_2/regexp/beginLine: FAIL_OK -js1_2/regexp/endLine: FAIL_OK + # Date trouble? + 'js1_5/Date/regress-301738-02': [FAIL_OK], -# We no longer let calls to test and exec with no argument implicitly -# use the previous input. -js1_2/regexp/RegExp_input: FAIL_OK -js1_2/regexp/RegExp_input_as_array: FAIL_OK + # This test fails for all browsers on in the CET timezone. + 'ecma/Date/15.9.5.35-1': [PASS, FAIL_OK], -# To be compatible with safari typeof a regexp yields 'function'; -# in firefox it yields 'object'. -js1_2/function/regexparg-1: FAIL_OK + # Spidermonkey allows stuff in parenthesis directly after the minutes + # in a date. JSC does not, so we don't either. + 'js1_5/Date/regress-309925-02': [FAIL_OK], -# Date trouble? -js1_5/Date/regress-301738-02: FAIL_OK + # Print string after deleting array element? + 'js1_5/Expressions/regress-96526-delelem': [FAIL_OK], -# This test fails for all browsers on in the CET timezone. -ecma/Date/15.9.5.35-1: PASS || FAIL_OK + # Stack overflows should be InternalError: too much recursion? + 'js1_5/Regress/regress-234389': [FAIL_OK], -# Spidermonkey allows stuff in parenthesis directly after the minutes -# in a date. JSC does not, so we don't either. -js1_5/Date/regress-309925-02: FAIL_OK + # This may very well be a bogus test. I'm not sure yet. + 'js1_5/Regress/regress-320119': [FAIL_OK], -# Print string after deleting array element? -js1_5/Expressions/regress-96526-delelem: FAIL_OK + # No support for toSource(). + 'js1_5/Regress/regress-248444': [FAIL_OK], + 'js1_5/Regress/regress-313967-01': [FAIL_OK], + 'js1_5/Regress/regress-313967-02': [FAIL_OK], -# Stack overflows should be InternalError: too much recursion? -js1_5/Regress/regress-234389: FAIL_OK + # This fails because we don't have stack space for Function.prototype.apply + # with very large numbers of arguments. The test uses 2^24 arguments. + 'js1_5/Array/regress-350256-03': [FAIL_OK], -# This may very well be a bogus test. I'm not sure yet. -js1_5/Regress/regress-320119: FAIL_OK + # Extra arguments not handled properly in String.prototype.match + 'js1_5/Regress/regress-179524': [FAIL_OK], -# No support for toSource(). -js1_5/Regress/regress-248444: FAIL_OK -js1_5/Regress/regress-313967-01: FAIL_OK -js1_5/Regress/regress-313967-02: FAIL_OK + # Uncategorized failures. Please help categorize (or fix) these failures. + 'js1_5/Regress/regress-172699': [FAIL_OK], -# This fails because we don't have stack space for Function.prototype.apply -# with very large numbers of arguments. The test uses 2^24 arguments. -js1_5/Array/regress-350256-03: FAIL_OK + # Assumes that the prototype of a function is enumerable. Non-ECMA, + # see section 15.3.3.1, page 86. + 'ecma/GlobalObject/15.1.2.2-1': [FAIL_OK], + 'ecma/GlobalObject/15.1.2.3-1': [FAIL_OK], + 'ecma/GlobalObject/15.1.2.4': [FAIL_OK], + 'ecma/GlobalObject/15.1.2.5-1': [FAIL_OK], + 'ecma/GlobalObject/15.1.2.6': [FAIL_OK], + 'ecma/GlobalObject/15.1.2.7': [FAIL_OK], -# Extra arguments not handled properly in String.prototype.match -js1_5/Regress/regress-179524: FAIL_OK + # Leading zero no longer signal octal numbers (ECMA-262 Annex E 15.1.2.2). + 'ecma/GlobalObject/15.1.2.2-2': [FAIL_OK], -# Uncategorized failures. Please help categorize (or fix) these failures. -js1_5/Regress/regress-172699: FAIL_OK + # Tests that rely on specific details of function decompilation or + # print strings for errors. Non-ECMA behavior. + 'js1_2/function/tostring-2': [FAIL_OK], + 'js1_2/Objects/toString-001': [FAIL_OK], + 'js1_5/LexicalConventions/regress-469940': [FAIL_OK], + 'js1_5/Exceptions/regress-332472': [FAIL_OK], + 'js1_5/Regress/regress-173067': [FAIL_OK], + 'js1_5/Regress/regress-355556': [FAIL_OK], + 'js1_5/Regress/regress-328664': [FAIL_OK], + 'js1_5/Regress/regress-252892': [FAIL_OK], + 'js1_5/Regress/regress-352208': [FAIL_OK], + 'ecma_3/Array/15.4.5.1-01': [FAIL_OK], + 'ecma_3/Array/regress-387501': [FAIL_OK], + 'ecma_3/LexicalConventions/7.9.1': [FAIL_OK], + 'ecma_3/RegExp/regress-375711': [FAIL_OK], + 'ecma_3/Unicode/regress-352044-01': [FAIL_OK], + 'ecma_3/extensions/regress-274152': [FAIL_OK], + 'js1_5/Regress/regress-372364': [FAIL_OK], + 'js1_5/Regress/regress-420919': [FAIL_OK], + 'js1_5/Regress/regress-422348': [FAIL_OK], + 'js1_5/Regress/regress-410852': [FAIL_OK], + 'ecma_3/RegExp/regress-375715-04': [FAIL_OK], + 'js1_5/decompilation/regress-456964-01': [FAIL_OK], + 'js1_5/decompilation/regress-437288-02': [FAIL_OK], + 'js1_5/decompilation/regress-457824': [FAIL_OK], + 'js1_5/decompilation/regress-460116-01': [FAIL_OK], + 'js1_5/decompilation/regress-460116-02': [FAIL_OK], + 'js1_5/decompilation/regress-460501': [FAIL_OK], + 'js1_5/decompilation/regress-460116-03': [FAIL_OK], + 'js1_5/decompilation/regress-461110': [FAIL_OK], -# Assumes that the prototype of a function is enumerable. Non-ECMA, -# see section 15.3.3.1, page 86. -ecma/GlobalObject/15.1.2.2-1: FAIL_OK -ecma/GlobalObject/15.1.2.3-1: FAIL_OK -ecma/GlobalObject/15.1.2.4: FAIL_OK -ecma/GlobalObject/15.1.2.5-1: FAIL_OK -ecma/GlobalObject/15.1.2.6: FAIL_OK -ecma/GlobalObject/15.1.2.7: FAIL_OK + # Tests that use uneval. Non-ECMA. + 'js1_5/GC/regress-418128': [FAIL_OK], + 'js1_5/extensions/regress-465276': [FAIL_OK], + 'js1_5/Error/regress-465377': [FAIL_OK], -# Leading zero no longer signal octal numbers (ECMA-262 Annex E 15.1.2.2). -ecma/GlobalObject/15.1.2.2-2: FAIL_OK + # Tests that use the watch method. Non-ECMA. + 'js1_5/extensions/regress-435345-01': [FAIL_OK], + 'js1_5/extensions/regress-455413': [FAIL_OK], -# Tests that rely on specific details of function decompilation or -# print strings for errors. Non-ECMA behavior. -js1_2/function/tostring-2: FAIL_OK -js1_2/Objects/toString-001: FAIL_OK -js1_5/LexicalConventions/regress-469940: FAIL_OK -js1_5/Exceptions/regress-332472: FAIL_OK -js1_5/Regress/regress-173067: FAIL_OK -js1_5/Regress/regress-355556: FAIL_OK -js1_5/Regress/regress-328664: FAIL_OK -js1_5/Regress/regress-252892: FAIL_OK -js1_5/Regress/regress-352208: FAIL_OK -ecma_3/Array/15.4.5.1-01: FAIL_OK -ecma_3/Array/regress-387501: FAIL_OK -ecma_3/LexicalConventions/7.9.1: FAIL_OK -ecma_3/RegExp/regress-375711: FAIL_OK -ecma_3/Unicode/regress-352044-01: FAIL_OK -ecma_3/extensions/regress-274152: FAIL_OK -js1_5/Regress/regress-372364: FAIL_OK -js1_5/Regress/regress-420919: FAIL_OK -js1_5/Regress/regress-422348: FAIL_OK -js1_5/Regress/regress-410852: FAIL_OK -ecma_3/RegExp/regress-375715-04: FAIL_OK -js1_5/decompilation/regress-456964-01: FAIL_OK -js1_5/decompilation/regress-437288-02: FAIL_OK -js1_5/decompilation/regress-457824: FAIL_OK -js1_5/decompilation/regress-460116-01: FAIL_OK -js1_5/decompilation/regress-460116-02: FAIL_OK -js1_5/decompilation/regress-460501: FAIL_OK -js1_5/decompilation/regress-460116-03: FAIL_OK -js1_5/decompilation/regress-461110: FAIL_OK + # Uses Mozilla-specific QName, XML, XMLList and Iterator. + 'js1_5/Regress/regress-407323': [FAIL_OK], + 'js1_5/Regress/regress-407957': [FAIL_OK], -# Tests that use uneval. Non-ECMA. -js1_5/GC/regress-418128: FAIL_OK -js1_5/extensions/regress-465276: FAIL_OK -js1_5/Error/regress-465377: FAIL_OK + # Relies on JavaScript 1.2 / 1.3 deprecated features. + 'js1_2/function/String': [FAIL_OK], + 'js1_2/operator/equality': [FAIL_OK], + 'js1_2/version120/boolean-001': [FAIL_OK], + 'js1_2/String/concat': [FAIL_OK], + 'js1_2/function/Function_object': [FAIL_OK], + 'js1_2/function/tostring-1': [FAIL_OK], + 'js1_2/version120/regress-99663': [FAIL_OK], + 'js1_2/regexp/RegExp_lastIndex': [FAIL_OK], + 'js1_2/regexp/string_split': [FAIL_OK], -# Tests that use the watch method. Non-ECMA. -js1_5/extensions/regress-435345-01: FAIL_OK -js1_5/extensions/regress-455413: FAIL_OK + # RegExps are not callable. + 'js1_2/regexp/simple_form': [FAIL_OK], + 'js1_2/regexp/regress-6359': [FAIL_OK], + 'js1_2/regexp/regress-9141': [FAIL_OK], + 'js1_5/Regress/regress-224956': [FAIL_OK], + 'js1_5/Regress/regress-325925': [FAIL_OK], + 'ecma_2/RegExp/regress-001': [FAIL_OK], -# Uses Mozilla-specific QName, XML, XMLList and Iterator. -js1_5/Regress/regress-407323: FAIL_OK -js1_5/Regress/regress-407957: FAIL_OK + # We do not check for bad surrogate pairs when quoting strings. + 'js1_5/Regress/regress-315974': [FAIL_OK], -# Relies on JavaScript 1.2 / 1.3 deprecated features. -js1_2/function/String: FAIL_OK -js1_2/operator/equality: FAIL_OK -js1_2/version120/boolean-001: FAIL_OK -js1_2/String/concat: FAIL_OK -js1_2/function/Function_object: FAIL_OK -js1_2/function/tostring-1: FAIL_OK -js1_2/version120/regress-99663: FAIL_OK -js1_2/regexp/RegExp_lastIndex: FAIL_OK -js1_2/regexp/string_split: FAIL_OK + # Use unsupported "watch". + 'js1_5/Regress/regress-213482': [FAIL_OK], + 'js1_5/Regress/regress-240577': [FAIL_OK], + 'js1_5/Regress/regress-355344': [FAIL_OK], + 'js1_5/Object/regress-362872-01': [FAIL_OK], + 'js1_5/Object/regress-362872-02': [FAIL_OK], + 'js1_5/Regress/regress-361467': [FAIL_OK], + 'js1_5/Regress/regress-385393-06': [FAIL_OK], + 'js1_5/Regress/regress-506567': [FAIL_OK], -# RegExps are not callable. -js1_2/regexp/simple_form: FAIL_OK -js1_2/regexp/regress-6359: FAIL_OK -js1_2/regexp/regress-9141: FAIL_OK -js1_5/Regress/regress-224956: FAIL_OK -js1_5/Regress/regress-325925: FAIL_OK -ecma_2/RegExp/regress-001: FAIL_OK + # Use special Mozilla getter/setter syntax + 'js1_5/Regress/regress-354924': [FAIL_OK], + 'js1_5/Regress/regress-355341': [FAIL_OK], + 'js1_5/GC/regress-316885-01': [FAIL_OK], + 'js1_5/GetSet/getset-002': [FAIL_OK], + 'js1_5/GetSet/regress-353264': [FAIL_OK], + 'js1_5/Regress/regress-361617': [FAIL_OK], + 'js1_5/Regress/regress-362583': [FAIL_OK], + 'js1_5/extensions/regress-356378': [FAIL_OK], + 'js1_5/extensions/regress-452178': [FAIL_OK], -# We do not check for bad surrogate pairs when quoting strings. -js1_5/Regress/regress-315974: FAIL_OK + # Requires Mozilla-specific strict mode or options() function. + 'ecma_3/Object/8.6.1-01': [FAIL_OK], + 'js1_5/Exceptions/regress-315147': [FAIL_OK], + 'js1_5/Regress/regress-106244': [FAIL_OK], + 'js1_5/Regress/regress-317533': [FAIL_OK], + 'js1_5/Regress/regress-323314-1': [FAIL_OK], + 'js1_5/Regress/regress-352197': [FAIL_OK], -# Use unsupported "watch". -js1_5/Regress/regress-213482: FAIL_OK -js1_5/Regress/regress-240577: FAIL_OK -js1_5/Regress/regress-355344: FAIL_OK -js1_5/Object/regress-362872-01: FAIL_OK -js1_5/Object/regress-362872-02: FAIL_OK -js1_5/Regress/regress-361467: FAIL_OK -js1_5/Regress/regress-385393-06: FAIL_OK -js1_5/Regress/regress-506567: FAIL_OK + # Equivalent to assert(false). + 'ecma_2/RegExp/exec-001': [FAIL_OK], + 'ecma_2/String/replace-001': [FAIL_OK], -# Use special Mozilla getter/setter syntax -js1_5/Regress/regress-354924: FAIL_OK -js1_5/Regress/regress-355341: FAIL_OK -js1_5/GC/regress-316885-01: FAIL_OK -js1_5/GetSet/getset-002: FAIL_OK -js1_5/GetSet/regress-353264: FAIL_OK -js1_5/Regress/regress-361617: FAIL_OK -js1_5/Regress/regress-362583: FAIL_OK -js1_5/extensions/regress-356378: FAIL_OK -js1_5/extensions/regress-452178: FAIL_OK + # We do not strip unicode format control characters. This is really + # required for working with non-latin character sets. We match JSC + # and IE here. Firefox matches the spec (section 7.1). + 'ecma_3/Unicode/uc-001': [FAIL_OK], -# Requires Mozilla-specific strict mode or options() function. -ecma_3/Object/8.6.1-01: FAIL_OK -js1_5/Exceptions/regress-315147: FAIL_OK -js1_5/Regress/regress-106244: FAIL_OK -js1_5/Regress/regress-317533: FAIL_OK -js1_5/Regress/regress-323314-1: FAIL_OK -js1_5/Regress/regress-352197: FAIL_OK + # A non-breaking space doesn't match \s in a regular expression. This + # behaviour matches JSC. All the VMs have different behaviours in which + # characters match \s so we do the same as JSC until they change. + 'ecma_3/Unicode/uc-002': [PASS, FAIL_OK], -# Equivalent to assert(false). -ecma_2/RegExp/exec-001: FAIL_OK -ecma_2/String/replace-001: FAIL_OK + # String.prototype.split on empty strings always returns an array + # with one element (as specified in ECMA-262). + 'js1_2/Array/array_split_1': [FAIL_OK], -# We do not strip unicode format control characters. This is really -# required for working with non-latin character sets. We match JSC -# and IE here. Firefox matches the spec (section 7.1). -ecma_3/Unicode/uc-001: FAIL_OK + # The concat() method is defined in Array.prototype; not Array. + 'js1_5/Array/regress-313153': [FAIL_OK], -# A non-breaking space doesn't match \s in a regular expression. This behaviour -# matches JSC. All the VMs have different behaviours in which characters match -# \s so we do the same as JSC until they change. -ecma_3/Unicode/uc-002: PASS || FAIL_OK + # The join() method is defined on Array.prototype; not Array. + 'js1_5/Array/regress-474529': [FAIL_OK], + # The lastIndexOf() method is defined on Array.prototype, not Array. + 'ecma_3/Array/15.5.4.8-01': [FAIL_OK], -# String.prototype.split on empty strings always returns an array -# with one element (as specified in ECMA-262). -js1_2/Array/array_split_1: FAIL_OK + # Properties fileName, and lineNumber of Error instances are + # not supported. Mozilla specific extension. + 'js1_5/Exceptions/errstack-001': [FAIL_OK], + 'js1_5/Exceptions/regress-257751': [FAIL_OK], + 'js1_5/Regress/regress-119719': [FAIL_OK], + 'js1_5/Regress/regress-167328': [FAIL_OK], + 'js1_5/Regress/regress-243869': [FAIL_OK], -# The concat() method is defined in Array.prototype; not Array. -js1_5/Array/regress-313153: FAIL_OK + # Unsupported import/export and <xml> literals. Mozilla extensions. + 'js1_5/Regress/regress-249211': [FAIL_OK], + 'js1_5/Regress/regress-309242': [FAIL_OK], + 'js1_5/Regress/regress-350692': [FAIL_OK], + 'js1_5/extensions/regress-421621': [FAIL_OK], + 'js1_5/extensions/regress-432075': [FAIL_OK], -# The join() method is defined on Array.prototype; not Array. -js1_5/Array/regress-474529: FAIL_OK -# The lastIndexOf() method is defined on Array.prototype, not Array. -ecma_3/Array/15.5.4.8-01: FAIL_OK + # The length of Error functions is 1 not 3. + 'js1_5/Exceptions/regress-123002': [FAIL_OK], -# Properties fileName, and lineNumber of Error instances are -# not supported. Mozilla specific extension. -js1_5/Exceptions/errstack-001: FAIL_OK -js1_5/Exceptions/regress-257751: FAIL_OK -js1_5/Regress/regress-119719: FAIL_OK -js1_5/Regress/regress-167328: FAIL_OK -js1_5/Regress/regress-243869: FAIL_OK + # Reserved keywords as function names, etc is not supported. + 'js1_5/LexicalConventions/regress-343675': [FAIL_OK], -# Unsupported import/export and <xml> literals. Mozilla extensions. -js1_5/Regress/regress-249211: FAIL_OK -js1_5/Regress/regress-309242: FAIL_OK -js1_5/Regress/regress-350692: FAIL_OK -js1_5/extensions/regress-421621: FAIL_OK -js1_5/extensions/regress-432075: FAIL_OK + # Tests if future reserved keywords of ECMA-262, edition 3 emit warnings. We + # implement the edition 5 behaviour and fail on use of edition 5 future + # reserved keywords as identifiers. + 'js1_5/Regress/regress-240317': [FAIL_OK], -# The length of Error functions is 1 not 3. -js1_5/Exceptions/regress-123002: FAIL_OK + # Unsupported list comprehensions: [ ... for ... ] and for each. + 'js1_5/Regress/regress-352009': [FAIL_OK], + 'js1_5/Regress/regress-349648': [FAIL_OK], -# Reserved keywords as function names, etc is not supported. -js1_5/LexicalConventions/regress-343675: FAIL_OK + # Expects top level arguments (passed on command line?) to be + # the empty string? + 'js1_5/Regress/regress-336100': [FAIL_OK], -# Tests if future reserved keywords of ECMA-262, edition 3 emit warnings. We -# implement the edition 5 behaviour and fail on use of edition 5 future reserved -# keywords as identifiers. -js1_5/Regress/regress-240317: FAIL_OK + # Regular expression test failures due to PCRE. We match JSC (ie, perl) + # behavior and not the ECMA spec. + 'ecma_3/RegExp/perlstress-001': [PASS, FAIL_OK], + 'ecma_3/RegExp/regress-334158': [PASS, FAIL], -# Unsupported list comprehensions: [ ... for ... ] and for each. -js1_5/Regress/regress-352009: FAIL_OK -js1_5/Regress/regress-349648: FAIL_OK + # This test fails due to http://code.google.com/p/v8/issues/detail?id=187 + # Failure to clear captures when a lookahead is unwound. + 'ecma_3/RegExp/15.10.2-1': [PASS, FAIL_OK], + # This test requires a failure if we try to compile a function with more + # than 65536 arguments. This seems to be a Mozilla restriction. + 'js1_5/Regress/regress-290575': [PASS, FAIL_OK], -# Expects top level arguments (passed on command line?) to be -# the empty string? -js1_5/Regress/regress-336100: FAIL_OK + # Fails because of the way function declarations are + # handled in V8/JSC. V8 follows IE behavior and introduce + # all nested function declarations when entering the + # surrounding function, whereas Spidermonkey declares + # them dynamically when the statement is executed. + 'ecma_3/Function/scope-001': [FAIL_OK], + 'ecma_3/FunExpr/fe-001': [FAIL_OK], + 'js1_5/Scope/regress-184107': [FAIL_OK], -# Regular expression test failures due to PCRE. We match JSC (ie, perl) -# behavior and not the ECMA spec. -ecma_3/RegExp/perlstress-001: PASS || FAIL_OK -ecma_3/RegExp/regress-334158: PASS || FAIL -# This test fails due to http://code.google.com/p/v8/issues/detail?id=187 -# Failure to clear captures when a lookahead is unwound. -ecma_3/RegExp/15.10.2-1: PASS || FAIL_OK + # Function is deletable in V8 and JSC. + 'js1_5/Regress/regress-352604': [FAIL_OK], -# This test requires a failure if we try to compile a function with more -# than 65536 arguments. This seems to be a Mozilla restriction. -js1_5/Regress/regress-290575: PASS || FAIL_OK + # Cannot call strings as functions. Expects not to crash. + 'js1_5/Regress/regress-417893': [FAIL_OK], -# Fails because of the way function declarations are -# handled in V8/JSC. V8 follows IE behavior and introduce -# all nested function declarations when entering the -# surrounding function, whereas Spidermonkey declares -# them dynamically when the statement is executed. -ecma_3/Function/scope-001: FAIL_OK -ecma_3/FunExpr/fe-001: FAIL_OK -js1_5/Scope/regress-184107: FAIL_OK + # Unsupported use of "[]" as function parameter. We match JSC. + 'js1_5/Regress/regress-416737-01': [FAIL_OK], + 'js1_5/Regress/regress-416737-02': [FAIL_OK], -# Function is deletable in V8 and JSC. -js1_5/Regress/regress-352604: FAIL_OK + # Illegal escape-sequences in string literals. Has already been fixed + # by most engines (i.e. V8, JSC, Opera and FF). + 'ecma/Array/15.4.5.1-1': [FAIL_OK], + 'ecma/LexicalConventions/7.7.4': [FAIL_OK], + 'ecma_2/RegExp/hex-001': [FAIL_OK], + 'js1_2/regexp/hexadecimal': [FAIL_OK], -# Cannot call strings as functions. Expects not to crash. -js1_5/Regress/regress-417893: FAIL_OK - -# Unsupported use of "[]" as function parameter. We match JSC. -js1_5/Regress/regress-416737-01: FAIL_OK -js1_5/Regress/regress-416737-02: FAIL_OK - - -# Illegal escape-sequences in string literals. Has already been fixed -# by most engines (i.e. V8, JSC, Opera and FF). -ecma/Array/15.4.5.1-1: FAIL_OK -ecma/LexicalConventions/7.7.4: FAIL_OK -ecma_2/RegExp/hex-001: FAIL_OK -js1_2/regexp/hexadecimal: FAIL_OK - - -# The source field of RegExp objects is properly escaped. We match JSC. -ecma_2/RegExp/constructor-001: FAIL_OK -ecma_2/RegExp/function-001: FAIL_OK -ecma_2/RegExp/properties-001: FAIL_OK - - -# Negative hexadecimal literals are parsed as NaN. This test is outdated. -ecma/TypeConversion/9.3.1-3: FAIL_OK - - -##################### FAILING TESTS ##################### - -# This section is for tests that fail in V8 and pass in JSC. -# Tests that fail in both V8 and JSC belong in the FAIL_OK -# category. - -# This fails because we don't handle Function.prototype.apply with very large -# numbers of arguments (depending on max stack size). 350256-02 needs more than -# 4Mbytes of stack space. -js1_5/Array/regress-350256-02: FAIL - - -# This test seems designed to fail (it produces a 700Mbyte string). -# We fail on out of memory. The important thing is not to crash. -js1_5/Regress/regress-303213: FAIL || TIMEOUT if $mode == debug - -# This test fails since we now throw in String.prototype.match when apply -# is given null or undefined as this argument (and so does firefox nightly). -js1_5/Regress/regress-295052: FAIL - -# Bug 1202592: New ecma_3/String/15.5.4.11 is failing. -ecma_3/String/15.5.4.11: FAIL - -# Bug 1202597: New js1_5/Expressions/regress-394673 is failing. -# Marked as: Will not fix. V8 throws an acceptable RangeError. -js1_5/Expressions/regress-394673: FAIL - - -# Bug 762: http://code.google.com/p/v8/issues/detail?id=762 -# We do not correctly handle assignments within "with" -ecma_3/Statements/12.10-01: FAIL - -# We do not throw an exception when a const is redeclared. -# (We only fail section 1 of the test.) -js1_5/Regress/regress-103602: FAIL - -##################### MOZILLA EXTENSION TESTS ##################### - -ecma/extensions/15.1.2.1-1: FAIL_OK -ecma_3/extensions/regress-385393-03: FAIL_OK -ecma_3/extensions/7.9.1: FAIL_OK -js1_5/extensions/catchguard-001: FAIL_OK -js1_5/extensions/catchguard-002: FAIL_OK -js1_5/extensions/catchguard-003: FAIL_OK -js1_5/extensions/getset-001: FAIL_OK -js1_5/extensions/getset-003: FAIL_OK -js1_5/extensions/no-such-method: FAIL_OK -js1_5/extensions/regress-104077: FAIL_OK -js1_5/extensions/regress-226078: FAIL_OK -js1_5/extensions/regress-303277: FAIL_OK -js1_5/extensions/regress-304897: FAIL_OK -js1_5/extensions/regress-306738: FAIL_OK -js1_5/extensions/regress-311161: FAIL_OK -js1_5/extensions/regress-311583: FAIL_OK -js1_5/extensions/regress-311792-01: FAIL_OK -js1_5/extensions/regress-312278: FAIL_OK -js1_5/extensions/regress-313630: FAIL_OK -js1_5/extensions/regress-313763: FAIL_OK -js1_5/extensions/regress-313803: FAIL_OK -js1_5/extensions/regress-314874: FAIL_OK -js1_5/extensions/regress-322957: FAIL_OK -js1_5/extensions/regress-328556: FAIL_OK -js1_5/extensions/regress-333541: FAIL_OK -js1_5/extensions/regress-335700: FAIL_OK -js1_5/extensions/regress-336409-1: FAIL_OK -js1_5/extensions/regress-336409-2: FAIL_OK -js1_5/extensions/regress-336410-2: FAIL_OK -js1_5/extensions/regress-341956-01: FAIL_OK -js1_5/extensions/regress-345967: FAIL_OK -js1_5/extensions/regress-346494-01: FAIL_OK -js1_5/extensions/regress-346494: FAIL_OK -js1_5/extensions/regress-347306-02: FAIL_OK -js1_5/extensions/regress-348986: FAIL_OK -js1_5/extensions/regress-349616: FAIL_OK -js1_5/extensions/regress-350312-02: FAIL_OK -js1_5/extensions/regress-350312-03: FAIL_OK -js1_5/extensions/regress-350531: FAIL_OK -js1_5/extensions/regress-351102-01: FAIL_OK -js1_5/extensions/regress-351102-02: FAIL_OK -js1_5/extensions/regress-351102-06: FAIL_OK -js1_5/extensions/regress-351973: FAIL_OK -js1_5/extensions/regress-352060: FAIL_OK -js1_5/extensions/regress-352094: FAIL_OK -js1_5/extensions/regress-352261: FAIL_OK -js1_5/extensions/regress-352281: FAIL_OK -js1_5/extensions/regress-352455: FAIL_OK -js1_5/extensions/regress-352604: FAIL_OK -js1_5/extensions/regress-353214: FAIL_OK -js1_5/extensions/regress-355339: FAIL_OK -js1_5/extensions/regress-355497: FAIL_OK -js1_5/extensions/regress-355622: FAIL_OK -js1_5/extensions/regress-355736: FAIL_OK -js1_5/extensions/regress-356085: FAIL_OK -js1_5/extensions/regress-356106: FAIL_OK -js1_5/extensions/regress-358594-01: FAIL_OK -js1_5/extensions/regress-358594-02: FAIL_OK -js1_5/extensions/regress-358594-03: FAIL_OK -js1_5/extensions/regress-358594-04: FAIL_OK -js1_5/extensions/regress-358594-05: FAIL_OK -js1_5/extensions/regress-358594-06: FAIL_OK -js1_5/extensions/regress-361346: FAIL_OK -js1_5/extensions/regress-361360: FAIL_OK -js1_5/extensions/regress-361558: FAIL_OK -js1_5/extensions/regress-361571: FAIL_OK -js1_5/extensions/regress-361856: FAIL_OK -js1_5/extensions/regress-361964: FAIL_OK -js1_5/extensions/regress-363988: FAIL_OK -js1_5/extensions/regress-365869: FAIL_OK -js1_5/extensions/regress-367630: FAIL_OK -js1_5/extensions/regress-367923: FAIL_OK -js1_5/extensions/regress-368859: FAIL_OK -js1_5/extensions/regress-369696-01: FAIL_OK -js1_5/extensions/regress-369696-02: FAIL_OK -js1_5/extensions/regress-369696-03: FAIL_OK -js1_5/extensions/regress-374589: FAIL_OK -js1_5/extensions/regress-375801: FAIL_OK -js1_5/extensions/regress-376052: FAIL_OK -js1_5/extensions/regress-379523: FAIL_OK -js1_5/extensions/regress-380581: FAIL_OK -js1_5/extensions/regress-380831: FAIL_OK -js1_5/extensions/regress-381205: FAIL_OK -js1_5/extensions/regress-381211: FAIL_OK -js1_5/extensions/regress-381304: FAIL_OK -js1_5/extensions/regress-382509: FAIL_OK -js1_5/extensions/regress-383965: FAIL_OK -js1_5/extensions/regress-384680: FAIL_OK -js1_5/extensions/regress-385393-09: FAIL_OK -js1_5/extensions/regress-407501: FAIL_OK -js1_5/extensions/regress-418730: FAIL_OK -js1_5/extensions/regress-420612: FAIL_OK -js1_5/extensions/regress-420869-01: FAIL_OK -js1_5/extensions/regress-424257: FAIL_OK -js1_5/extensions/regress-424683-01: FAIL_OK -js1_5/extensions/regress-429739: FAIL_OK -js1_5/extensions/regress-454142: FAIL_OK -js1_5/extensions/regress-465145: FAIL_OK -js1_5/extensions/regress-469625: FAIL_OK -js1_5/extensions/regress-472787: FAIL_OK -js1_5/extensions/regress-44009: FAIL_OK -js1_5/extensions/regress-50447-1: FAIL_OK -js1_5/extensions/regress-50447: FAIL_OK -js1_5/extensions/regress-90596-001: FAIL_OK -js1_5/extensions/regress-90596-002: FAIL_OK -js1_5/extensions/regress-96284-001: FAIL_OK -js1_5/extensions/regress-96284-002: FAIL_OK -js1_5/extensions/toLocaleFormat-01: FAIL_OK -js1_5/extensions/toLocaleFormat-02: FAIL_OK - -js1_5/extensions/regress-330569: TIMEOUT -js1_5/extensions/regress-351448: TIMEOUT -# In the 64-bit version, this test takes longer to run out of memory -# than it does in the 32-bit version when attempting to generate a huge -# error message in debug mode. -js1_5/extensions/regress-336410-1: FAIL_OK || TIMEOUT if ($mode == debug && $arch == x64) - -##################### DECOMPILATION TESTS ##################### - -# We don't really about the outcome of running the -# decompilation tests as long as they don't crash or -# timeout. - -js1_5/decompilation/regress-344120: PASS || FAIL -js1_5/decompilation/regress-346892: PASS || FAIL -js1_5/decompilation/regress-346902: PASS || FAIL -js1_5/decompilation/regress-346904: PASS || FAIL -js1_5/decompilation/regress-346915: PASS || FAIL -js1_5/decompilation/regress-349484: PASS || FAIL -js1_5/decompilation/regress-349489: PASS || FAIL -js1_5/decompilation/regress-349491: PASS || FAIL -js1_5/decompilation/regress-349596: PASS || FAIL -js1_5/decompilation/regress-349650: PASS || FAIL -js1_5/decompilation/regress-349663: PASS || FAIL -js1_5/decompilation/regress-350242: PASS || FAIL -js1_5/decompilation/regress-350263: PASS || FAIL -js1_5/decompilation/regress-350271: PASS || FAIL -js1_5/decompilation/regress-350666: PASS || FAIL -js1_5/decompilation/regress-350670: PASS || FAIL -js1_5/decompilation/regress-351104: PASS || FAIL -js1_5/decompilation/regress-351219: PASS || FAIL -js1_5/decompilation/regress-351336: PASS || FAIL -js1_5/decompilation/regress-351597: PASS || FAIL -js1_5/decompilation/regress-351625: PASS || FAIL -js1_5/decompilation/regress-351626: PASS || FAIL -js1_5/decompilation/regress-351693: PASS || FAIL -js1_5/decompilation/regress-351705: PASS || FAIL -js1_5/decompilation/regress-351793: PASS || FAIL -js1_5/decompilation/regress-352013: PASS || FAIL -js1_5/decompilation/regress-352022: PASS || FAIL -js1_5/decompilation/regress-352073: PASS || FAIL -js1_5/decompilation/regress-352202: PASS || FAIL -js1_5/decompilation/regress-352312: PASS || FAIL -js1_5/decompilation/regress-352360: PASS || FAIL -js1_5/decompilation/regress-352375: PASS || FAIL -js1_5/decompilation/regress-352453: PASS || FAIL -js1_5/decompilation/regress-352649: PASS || FAIL -js1_5/decompilation/regress-352873-01: PASS || FAIL -js1_5/decompilation/regress-352873-02: PASS || FAIL -js1_5/decompilation/regress-353000: PASS || FAIL -js1_5/decompilation/regress-353120: PASS || FAIL -js1_5/decompilation/regress-353146: PASS || FAIL -js1_5/decompilation/regress-354878: PASS || FAIL -js1_5/decompilation/regress-354910: PASS || FAIL -js1_5/decompilation/regress-355992: PASS || FAIL -js1_5/decompilation/regress-356083: PASS || FAIL -js1_5/decompilation/regress-356248: PASS || FAIL -js1_5/decompilation/regress-371692: PASS || FAIL -js1_5/decompilation/regress-373678: PASS || FAIL -js1_5/decompilation/regress-375639: PASS || FAIL -js1_5/decompilation/regress-375882: PASS || FAIL -js1_5/decompilation/regress-376564: PASS || FAIL -js1_5/decompilation/regress-383721: PASS || FAIL -js1_5/decompilation/regress-406555: PASS || FAIL -js1_5/decompilation/regress-460870: PASS || FAIL - - -[ $arch == arm ] - -# BUG(3251229): Times out when running new crankshaft test script. -ecma_3/RegExp/regress-311414: SKIP -ecma/Date/15.9.5.8: SKIP -ecma/Date/15.9.5.10-2: SKIP -ecma/Date/15.9.5.11-2: SKIP -ecma/Date/15.9.5.12-2: SKIP -js1_5/Array/regress-99120-02: SKIP -js1_5/extensions/regress-371636: SKIP -js1_5/Regress/regress-203278-1: SKIP -js1_5/Regress/regress-404755: SKIP -js1_5/Regress/regress-451322: SKIP - - -# BUG(1040): Allow this test to timeout. -js1_5/GC/regress-203278-2: PASS || TIMEOUT - - -[ $arch == mipsel ] - -# BUG(3251229): Times out when running new crankshaft test script. -ecma_3/RegExp/regress-311414: SKIP -ecma/Date/15.9.5.8: SKIP -ecma/Date/15.9.5.10-2: SKIP -ecma/Date/15.9.5.11-2: SKIP -ecma/Date/15.9.5.12-2: SKIP -js1_5/Array/regress-99120-02: SKIP -js1_5/extensions/regress-371636: SKIP -js1_5/Regress/regress-203278-1: SKIP -js1_5/Regress/regress-404755: SKIP -js1_5/Regress/regress-451322: SKIP - - -# BUG(1040): Allow this test to timeout. -js1_5/GC/regress-203278-2: PASS || TIMEOUT + # The source field of RegExp objects is properly escaped. We match JSC. + 'ecma_2/RegExp/constructor-001': [FAIL_OK], + 'ecma_2/RegExp/function-001': [FAIL_OK], + 'ecma_2/RegExp/properties-001': [FAIL_OK], + + + # Negative hexadecimal literals are parsed as NaN. This test is outdated. + 'ecma/TypeConversion/9.3.1-3': [FAIL_OK], + + + ##################### FAILING TESTS ##################### + + # This section is for tests that fail in V8 and pass in JSC. + # Tests that fail in both V8 and JSC belong in the FAIL_OK + # category. + + # This fails because we don't handle Function.prototype.apply with very large + # numbers of arguments (depending on max stack size). 350256-02 needs more + # than 4Mbytes of stack space. + 'js1_5/Array/regress-350256-02': [FAIL], + + + # This test seems designed to fail (it produces a 700Mbyte string). + # We fail on out of memory. The important thing is not to crash. + 'js1_5/Regress/regress-303213': [FAIL, ['mode == debug', TIMEOUT]], + + # This test fails since we now throw in String.prototype.match when apply + # is given null or undefined as this argument (and so does firefox nightly). + 'js1_5/Regress/regress-295052': [FAIL], + + # Bug 1202592: New ecma_3/String/15.5.4.11 is failing. + 'ecma_3/String/15.5.4.11': [FAIL], + + # Bug 1202597: New js1_5/Expressions/regress-394673 is failing. + # Marked as: Will not fix. V8 throws an acceptable RangeError. + 'js1_5/Expressions/regress-394673': [FAIL], + + + # Bug 762: http://code.google.com/p/v8/issues/detail?id=762 + # We do not correctly handle assignments within "with" + 'ecma_3/Statements/12.10-01': [FAIL], + + # We do not throw an exception when a const is redeclared. + # (We only fail section 1 of the test.) + 'js1_5/Regress/regress-103602': [FAIL], + + ##################### MOZILLA EXTENSION TESTS ##################### + + 'ecma/extensions/15.1.2.1-1': [FAIL_OK], + 'ecma_3/extensions/regress-385393-03': [FAIL_OK], + 'ecma_3/extensions/7.9.1': [FAIL_OK], + 'js1_5/extensions/catchguard-001': [FAIL_OK], + 'js1_5/extensions/catchguard-002': [FAIL_OK], + 'js1_5/extensions/catchguard-003': [FAIL_OK], + 'js1_5/extensions/getset-001': [FAIL_OK], + 'js1_5/extensions/getset-003': [FAIL_OK], + 'js1_5/extensions/no-such-method': [FAIL_OK], + 'js1_5/extensions/regress-104077': [FAIL_OK], + 'js1_5/extensions/regress-226078': [FAIL_OK], + 'js1_5/extensions/regress-303277': [FAIL_OK], + 'js1_5/extensions/regress-304897': [FAIL_OK], + 'js1_5/extensions/regress-306738': [FAIL_OK], + 'js1_5/extensions/regress-311161': [FAIL_OK], + 'js1_5/extensions/regress-311583': [FAIL_OK], + 'js1_5/extensions/regress-311792-01': [FAIL_OK], + 'js1_5/extensions/regress-312278': [FAIL_OK], + 'js1_5/extensions/regress-313630': [FAIL_OK], + 'js1_5/extensions/regress-313763': [FAIL_OK], + 'js1_5/extensions/regress-313803': [FAIL_OK], + 'js1_5/extensions/regress-314874': [FAIL_OK], + 'js1_5/extensions/regress-322957': [FAIL_OK], + 'js1_5/extensions/regress-328556': [FAIL_OK], + 'js1_5/extensions/regress-333541': [FAIL_OK], + 'js1_5/extensions/regress-335700': [FAIL_OK], + 'js1_5/extensions/regress-336409-1': [FAIL_OK], + 'js1_5/extensions/regress-336409-2': [FAIL_OK], + 'js1_5/extensions/regress-336410-2': [FAIL_OK], + 'js1_5/extensions/regress-341956-01': [FAIL_OK], + 'js1_5/extensions/regress-345967': [FAIL_OK], + 'js1_5/extensions/regress-346494-01': [FAIL_OK], + 'js1_5/extensions/regress-346494': [FAIL_OK], + 'js1_5/extensions/regress-347306-02': [FAIL_OK], + 'js1_5/extensions/regress-348986': [FAIL_OK], + 'js1_5/extensions/regress-349616': [FAIL_OK], + 'js1_5/extensions/regress-350312-02': [FAIL_OK], + 'js1_5/extensions/regress-350312-03': [FAIL_OK], + 'js1_5/extensions/regress-350531': [FAIL_OK], + 'js1_5/extensions/regress-351102-01': [FAIL_OK], + 'js1_5/extensions/regress-351102-02': [FAIL_OK], + 'js1_5/extensions/regress-351102-06': [FAIL_OK], + 'js1_5/extensions/regress-351973': [FAIL_OK], + 'js1_5/extensions/regress-352060': [FAIL_OK], + 'js1_5/extensions/regress-352094': [FAIL_OK], + 'js1_5/extensions/regress-352261': [FAIL_OK], + 'js1_5/extensions/regress-352281': [FAIL_OK], + 'js1_5/extensions/regress-352455': [FAIL_OK], + 'js1_5/extensions/regress-352604': [FAIL_OK], + 'js1_5/extensions/regress-353214': [FAIL_OK], + 'js1_5/extensions/regress-355339': [FAIL_OK], + 'js1_5/extensions/regress-355497': [FAIL_OK], + 'js1_5/extensions/regress-355622': [FAIL_OK], + 'js1_5/extensions/regress-355736': [FAIL_OK], + 'js1_5/extensions/regress-356085': [FAIL_OK], + 'js1_5/extensions/regress-356106': [FAIL_OK], + 'js1_5/extensions/regress-358594-01': [FAIL_OK], + 'js1_5/extensions/regress-358594-02': [FAIL_OK], + 'js1_5/extensions/regress-358594-03': [FAIL_OK], + 'js1_5/extensions/regress-358594-04': [FAIL_OK], + 'js1_5/extensions/regress-358594-05': [FAIL_OK], + 'js1_5/extensions/regress-358594-06': [FAIL_OK], + 'js1_5/extensions/regress-361346': [FAIL_OK], + 'js1_5/extensions/regress-361360': [FAIL_OK], + 'js1_5/extensions/regress-361558': [FAIL_OK], + 'js1_5/extensions/regress-361571': [FAIL_OK], + 'js1_5/extensions/regress-361856': [FAIL_OK], + 'js1_5/extensions/regress-361964': [FAIL_OK], + 'js1_5/extensions/regress-363988': [FAIL_OK], + 'js1_5/extensions/regress-365869': [FAIL_OK], + 'js1_5/extensions/regress-367630': [FAIL_OK], + 'js1_5/extensions/regress-367923': [FAIL_OK], + 'js1_5/extensions/regress-368859': [FAIL_OK], + 'js1_5/extensions/regress-369696-01': [FAIL_OK], + 'js1_5/extensions/regress-369696-02': [FAIL_OK], + 'js1_5/extensions/regress-369696-03': [FAIL_OK], + 'js1_5/extensions/regress-374589': [FAIL_OK], + 'js1_5/extensions/regress-375801': [FAIL_OK], + 'js1_5/extensions/regress-376052': [FAIL_OK], + 'js1_5/extensions/regress-379523': [FAIL_OK], + 'js1_5/extensions/regress-380581': [FAIL_OK], + 'js1_5/extensions/regress-380831': [FAIL_OK], + 'js1_5/extensions/regress-381205': [FAIL_OK], + 'js1_5/extensions/regress-381211': [FAIL_OK], + 'js1_5/extensions/regress-381304': [FAIL_OK], + 'js1_5/extensions/regress-382509': [FAIL_OK], + 'js1_5/extensions/regress-383965': [FAIL_OK], + 'js1_5/extensions/regress-384680': [FAIL_OK], + 'js1_5/extensions/regress-385393-09': [FAIL_OK], + 'js1_5/extensions/regress-407501': [FAIL_OK], + 'js1_5/extensions/regress-418730': [FAIL_OK], + 'js1_5/extensions/regress-420612': [FAIL_OK], + 'js1_5/extensions/regress-420869-01': [FAIL_OK], + 'js1_5/extensions/regress-424257': [FAIL_OK], + 'js1_5/extensions/regress-424683-01': [FAIL_OK], + 'js1_5/extensions/regress-429739': [FAIL_OK], + 'js1_5/extensions/regress-454142': [FAIL_OK], + 'js1_5/extensions/regress-465145': [FAIL_OK], + 'js1_5/extensions/regress-469625': [FAIL_OK], + 'js1_5/extensions/regress-472787': [FAIL_OK], + 'js1_5/extensions/regress-44009': [FAIL_OK], + 'js1_5/extensions/regress-50447-1': [FAIL_OK], + 'js1_5/extensions/regress-50447': [FAIL_OK], + 'js1_5/extensions/regress-90596-001': [FAIL_OK], + 'js1_5/extensions/regress-90596-002': [FAIL_OK], + 'js1_5/extensions/regress-96284-001': [FAIL_OK], + 'js1_5/extensions/regress-96284-002': [FAIL_OK], + 'js1_5/extensions/toLocaleFormat-01': [FAIL_OK], + 'js1_5/extensions/toLocaleFormat-02': [FAIL_OK], + + 'js1_5/extensions/regress-330569': [TIMEOUT], + 'js1_5/extensions/regress-351448': [TIMEOUT], + # In the 64-bit version, this test takes longer to run out of memory + # than it does in the 32-bit version when attempting to generate a huge + # error message in debug mode. + 'js1_5/extensions/regress-336410-1': [FAIL_OK, ['mode == debug and arch == x64', TIMEOUT]], + + ##################### DECOMPILATION TESTS ##################### + + # We don't really about the outcome of running the + # decompilation tests as long as they don't crash or + # timeout. + + 'js1_5/decompilation/regress-344120': [PASS, FAIL], + 'js1_5/decompilation/regress-346892': [PASS, FAIL], + 'js1_5/decompilation/regress-346902': [PASS, FAIL], + 'js1_5/decompilation/regress-346904': [PASS, FAIL], + 'js1_5/decompilation/regress-346915': [PASS, FAIL], + 'js1_5/decompilation/regress-349484': [PASS, FAIL], + 'js1_5/decompilation/regress-349489': [PASS, FAIL], + 'js1_5/decompilation/regress-349491': [PASS, FAIL], + 'js1_5/decompilation/regress-349596': [PASS, FAIL], + 'js1_5/decompilation/regress-349650': [PASS, FAIL], + 'js1_5/decompilation/regress-349663': [PASS, FAIL], + 'js1_5/decompilation/regress-350242': [PASS, FAIL], + 'js1_5/decompilation/regress-350263': [PASS, FAIL], + 'js1_5/decompilation/regress-350271': [PASS, FAIL], + 'js1_5/decompilation/regress-350666': [PASS, FAIL], + 'js1_5/decompilation/regress-350670': [PASS, FAIL], + 'js1_5/decompilation/regress-351104': [PASS, FAIL], + 'js1_5/decompilation/regress-351219': [PASS, FAIL], + 'js1_5/decompilation/regress-351336': [PASS, FAIL], + 'js1_5/decompilation/regress-351597': [PASS, FAIL], + 'js1_5/decompilation/regress-351625': [PASS, FAIL], + 'js1_5/decompilation/regress-351626': [PASS, FAIL], + 'js1_5/decompilation/regress-351693': [PASS, FAIL], + 'js1_5/decompilation/regress-351705': [PASS, FAIL], + 'js1_5/decompilation/regress-351793': [PASS, FAIL], + 'js1_5/decompilation/regress-352013': [PASS, FAIL], + 'js1_5/decompilation/regress-352022': [PASS, FAIL], + 'js1_5/decompilation/regress-352073': [PASS, FAIL], + 'js1_5/decompilation/regress-352202': [PASS, FAIL], + 'js1_5/decompilation/regress-352312': [PASS, FAIL], + 'js1_5/decompilation/regress-352360': [PASS, FAIL], + 'js1_5/decompilation/regress-352375': [PASS, FAIL], + 'js1_5/decompilation/regress-352453': [PASS, FAIL], + 'js1_5/decompilation/regress-352649': [PASS, FAIL], + 'js1_5/decompilation/regress-352873-01': [PASS, FAIL], + 'js1_5/decompilation/regress-352873-02': [PASS, FAIL], + 'js1_5/decompilation/regress-353000': [PASS, FAIL], + 'js1_5/decompilation/regress-353120': [PASS, FAIL], + 'js1_5/decompilation/regress-353146': [PASS, FAIL], + 'js1_5/decompilation/regress-354878': [PASS, FAIL], + 'js1_5/decompilation/regress-354910': [PASS, FAIL], + 'js1_5/decompilation/regress-355992': [PASS, FAIL], + 'js1_5/decompilation/regress-356083': [PASS, FAIL], + 'js1_5/decompilation/regress-356248': [PASS, FAIL], + 'js1_5/decompilation/regress-371692': [PASS, FAIL], + 'js1_5/decompilation/regress-373678': [PASS, FAIL], + 'js1_5/decompilation/regress-375639': [PASS, FAIL], + 'js1_5/decompilation/regress-375882': [PASS, FAIL], + 'js1_5/decompilation/regress-376564': [PASS, FAIL], + 'js1_5/decompilation/regress-383721': [PASS, FAIL], + 'js1_5/decompilation/regress-406555': [PASS, FAIL], + 'js1_5/decompilation/regress-460870': [PASS, FAIL], +}], # ALWAYS + + +['arch == arm', { + + # BUG(3251229): Times out when running new crankshaft test script. + 'ecma_3/RegExp/regress-311414': [SKIP], + 'ecma/Date/15.9.5.8': [SKIP], + 'ecma/Date/15.9.5.10-2': [SKIP], + 'ecma/Date/15.9.5.11-2': [SKIP], + 'ecma/Date/15.9.5.12-2': [SKIP], + 'js1_5/Array/regress-99120-02': [SKIP], + 'js1_5/extensions/regress-371636': [SKIP], + 'js1_5/Regress/regress-203278-1': [SKIP], + 'js1_5/Regress/regress-404755': [SKIP], + 'js1_5/Regress/regress-451322': [SKIP], + + + # BUG(1040): Allow this test to timeout. + 'js1_5/GC/regress-203278-2': [PASS, TIMEOUT], +}], # 'arch == arm' + + +['arch == mipsel', { + + # BUG(3251229): Times out when running new crankshaft test script. + 'ecma_3/RegExp/regress-311414': [SKIP], + 'ecma/Date/15.9.5.8': [SKIP], + 'ecma/Date/15.9.5.10-2': [SKIP], + 'ecma/Date/15.9.5.11-2': [SKIP], + 'ecma/Date/15.9.5.12-2': [SKIP], + 'js1_5/Array/regress-99120-02': [SKIP], + 'js1_5/extensions/regress-371636': [SKIP], + 'js1_5/Regress/regress-203278-1': [SKIP], + 'js1_5/Regress/regress-404755': [SKIP], + 'js1_5/Regress/regress-451322': [SKIP], + + + # BUG(1040): Allow this test to timeout. + 'js1_5/GC/regress-203278-2': [PASS, TIMEOUT], +}], # 'arch == mipsel' +] diff --git a/deps/v8/test/preparser/preparser.status b/deps/v8/test/preparser/preparser.status index 40c5caf742..9d69988f71 100644 --- a/deps/v8/test/preparser/preparser.status +++ b/deps/v8/test/preparser/preparser.status @@ -25,14 +25,20 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -prefix preparser +[ +[ALWAYS, { + # TODO(mstarzinger): This script parses but throws a TypeError when run. + 'non-alphanum': [FAIL], -# We don't parse RegExps at scanning time, so we can't fail on octal -# escapes (we need to parse to distinguish octal escapes from valid -# back-references). -strict-octal-regexp: FAIL + # We don't parse RegExps at scanning time, so we can't fail on octal + # escapes (we need to parse to distinguish octal escapes from valid + # back-references). + 'strict-octal-regexp': [FAIL], +}], # ALWAYS -[ $arch == android_arm || $arch == android_ia32 ] -# Remove this once the issue above is fixed. Android test runner does not -# handle "FAIL" test expectation correctly. -strict-octal-regexp: SKIP +['arch == android_arm or arch == android_ia32', { + # Remove this once the issue above is fixed. Android test runner does not + # handle "FAIL" test expectation correctly. + 'strict-octal-regexp': [SKIP], +}], # 'arch == android_arm or arch == android_ia32' +] diff --git a/deps/v8/test/preparser/strict-identifiers.pyt b/deps/v8/test/preparser/strict-identifiers.pyt index f979088689..446980f701 100644 --- a/deps/v8/test/preparser/strict-identifiers.pyt +++ b/deps/v8/test/preparser/strict-identifiers.pyt @@ -147,25 +147,25 @@ label_strict = StrictTemplate("label-strict-$id", """ """) break_normal = Template("break-normal-$id", """ - for (;;) { + $id: for (;false;) { break $id; } """) break_strict = StrictTemplate("break-strict-$id", """ - for (;;) { + $id: for (;false;) { break $id; } """) continue_normal = Template("continue-normal-$id", """ - for (;;) { + $id: for (;false;) { continue $id; } """) continue_strict = StrictTemplate("continue-strict-$id", """ - for (;;) { + $id: for (;false;) { continue $id; } """) diff --git a/deps/v8/test/preparser/testcfg.py b/deps/v8/test/preparser/testcfg.py index 566fd5ca44..850c0a4589 100644 --- a/deps/v8/test/preparser/testcfg.py +++ b/deps/v8/test/preparser/testcfg.py @@ -39,7 +39,7 @@ class PreparserTestSuite(testsuite.TestSuite): super(PreparserTestSuite, self).__init__(name, root) def shell(self): - return "preparser" + return "d8" def _GetExpectations(self): expects_file = os.path.join(self.root, "preparser.expectation") @@ -64,7 +64,7 @@ class PreparserTestSuite(testsuite.TestSuite): testname = os.path.join(filename, name) flags = ["-e", source] if expectation: - flags += ["throws", expectation] + flags += ["--throws"] test = testcase.TestCase(self, testname, flags=flags) result.append(test) def Template(name, source): @@ -89,7 +89,7 @@ class PreparserTestSuite(testsuite.TestSuite): throws = expectations.get(f, None) flags = [f + ".js"] if throws: - flags += ["throws", throws] + flags += ["--throws"] test = testcase.TestCase(self, f, flags=flags) result.append(test) @@ -112,7 +112,7 @@ class PreparserTestSuite(testsuite.TestSuite): with open(testcase.flags[0]) as f: return f.read() - def VariantFlags(self): + def VariantFlags(self, testcase, default_flags): return [[]]; diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status index 4910939f15..e546266f3a 100644 --- a/deps/v8/test/test262/test262.status +++ b/deps/v8/test/test262/test262.status @@ -25,68 +25,97 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -prefix test262 -def FAIL_OK = FAIL, OKAY +[ +[ALWAYS, { + ############################### BUGS ################################### -############################### BUGS ################################### + # Sequencing of getter side effects on receiver and argument properties + # is wrong. The receiver callback should be called before any arguments + # are evaluated. + # V8 Bug: http://code.google.com/p/v8/issues/detail?id=691 + '11.2.3-3_3': [FAIL], -# Sequencing of getter side effects on receiver and argument properties -# is wrong. The receiver callback should be called before any arguments -# are evaluated. -# V8 Bug: http://code.google.com/p/v8/issues/detail?id=691 -11.2.3-3_3: FAIL + '15.5.4.9_CE': [['no_i18n', SKIP]], -# Strings that are considered canonically equivalent by the Unicode standard -# return a non-zero value on String.prototype.localeCompare calls. -# V8 Bug: http://code.google.com/p/v8/issues/detail?id=2413 -15.5.4.9_CE: FAIL + ######################## NEEDS INVESTIGATION ########################### -##################### DELIBERATE INCOMPATIBILITIES ##################### + # These test failures are specific to the intl402 suite and need investigation + # to be either marked as bugs with issues filed for them or as deliberate + # incompatibilities if the test cases turn out to be broken or ambiguous. + '6.2.3': [FAIL], + '9.2.1_2': [FAIL], + '9.2.5_11_g_ii_2': [FAIL], + '9.2.6_2': [FAIL], + '10.1.1_a': [FAIL], + '10.1.1_19_c': [PASS, FAIL], + '10.1.2.1_4': [FAIL], + '10.2.3_b': [PASS, FAIL], + '10.3_a': [FAIL], + '11.1.1_17': [PASS, FAIL], + '11.1.1_19': [PASS, FAIL], + '11.1.1_20_c': [FAIL], + '11.1.1_a': [FAIL], + '11.1.2.1_4': [FAIL], + '11.3.2_FN_2': [PASS, FAIL], + '11.3.2_TRF': [PASS, FAIL], + '11.3.2_TRP': [FAIL], + '11.3_a': [FAIL], + '12.1.1_a': [FAIL], + '12.1.2.1_4': [FAIL], + '12.3.2_FDT_7_a_iv': [FAIL], + '12.3.3': [FAIL], + '12.3_a': [FAIL], + '15.5.4.9_3': [PASS, FAIL], -# This tests precision of Math functions. The implementation for those -# trigonometric functions are platform/compiler dependent. Furthermore, the -# expectation values by far deviates from the actual result given by an -# arbitrary-precision calculator, making those tests partly bogus. -S15.8.2.8_A6: PASS || FAIL_OK # Math.exp (less precise with --fast-math) -S15.8.2.16_A7: PASS || FAIL_OK # Math.sin -S15.8.2.18_A7: PASS || FAIL_OK # Math.tan + ##################### DELIBERATE INCOMPATIBILITIES ##################### -# Linux for ia32 (and therefore simulators) default to extended 80 bit floating -# point formats, so these tests checking 64-bit FP precision fail. The other -# platforms/arch's pass these tests. -# We follow the other major JS engines by keeping this default. -S8.5_A2.1: PASS || FAIL_OK -S8.5_A2.2: PASS || FAIL_OK + # This tests precision of Math functions. The implementation for those + # trigonometric functions are platform/compiler dependent. Furthermore, the + # expectation values by far deviates from the actual result given by an + # arbitrary-precision calculator, making those tests partly bogus. + 'S15.8.2.8_A6': [PASS, FAIL_OK], # Math.exp (less precise with --fast-math) + 'S15.8.2.16_A7': [PASS, FAIL_OK], # Math.sin + 'S15.8.2.18_A7': [PASS, FAIL_OK], # Math.tan -############################ INVALID TESTS ############################# + # Linux for ia32 (and therefore simulators) default to extended 80 bit + # floating point formats, so these tests checking 64-bit FP precision fail. + # The other platforms/arch's pass these tests. + # We follow the other major JS engines by keeping this default. + 'S8.5_A2.1': [PASS, FAIL_OK], + 'S8.5_A2.2': [PASS, FAIL_OK], -# The reference value calculated by Test262 is incorrect if you run these tests -# in PST/PDT between first Sunday in March and first Sunday in April. The DST -# switch was moved in 2007 whereas Test262 bases the reference value on 2000. -# Test262 Bug: https://bugs.ecmascript.org/show_bug.cgi?id=293 -S15.9.3.1_A5_T1: PASS || FAIL_OK -S15.9.3.1_A5_T2: PASS || FAIL_OK -S15.9.3.1_A5_T3: PASS || FAIL_OK -S15.9.3.1_A5_T4: PASS || FAIL_OK -S15.9.3.1_A5_T5: PASS || FAIL_OK -S15.9.3.1_A5_T6: PASS || FAIL_OK + ############################ INVALID TESTS ############################# -############################ SKIPPED TESTS ############################# + # The reference value calculated by Test262 is incorrect if you run these + # tests in PST/PDT between first Sunday in March and first Sunday in April. + # The DST switch was moved in 2007 whereas Test262 bases the reference value + # on 2000. Test262 Bug: https://bugs.ecmascript.org/show_bug.cgi?id=293 + 'S15.9.3.1_A5_T1': [PASS, FAIL_OK], + 'S15.9.3.1_A5_T2': [PASS, FAIL_OK], + 'S15.9.3.1_A5_T3': [PASS, FAIL_OK], + 'S15.9.3.1_A5_T4': [PASS, FAIL_OK], + 'S15.9.3.1_A5_T5': [PASS, FAIL_OK], + 'S15.9.3.1_A5_T6': [PASS, FAIL_OK], -# These tests take a looong time to run in debug mode. -S15.1.3.1_A2.5_T1: PASS, SKIP if $mode == debug -S15.1.3.2_A2.5_T1: PASS, SKIP if $mode == debug + ############################ SKIPPED TESTS ############################# -[ $arch == arm || $arch == mipsel ] + # These tests take a looong time to run in debug mode. + 'S15.1.3.1_A2.5_T1': [PASS, ['mode == debug', SKIP]], + 'S15.1.3.2_A2.5_T1': [PASS, ['mode == debug', SKIP]], +}], # ALWAYS -# TODO(mstarzinger): Causes stack overflow on simulators due to eager -# compilation of parenthesized function literals. Needs investigation. -S13.2.1_A1_T1: SKIP +['arch == arm or arch == mipsel', { -# BUG(3251225): Tests that timeout with --nocrankshaft. -S15.1.3.1_A2.4_T1: SKIP -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.4_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP -S15.1.3.3_A2.3_T1: SKIP -S15.1.3.4_A2.3_T1: SKIP + # TODO(mstarzinger): Causes stack overflow on simulators due to eager + # compilation of parenthesized function literals. Needs investigation. + 'S13.2.1_A1_T1': [SKIP], + + # BUG(3251225): Tests that timeout with --nocrankshaft. + 'S15.1.3.1_A2.4_T1': [SKIP], + 'S15.1.3.1_A2.5_T1': [SKIP], + 'S15.1.3.2_A2.4_T1': [SKIP], + 'S15.1.3.2_A2.5_T1': [SKIP], + 'S15.1.3.3_A2.3_T1': [SKIP], + 'S15.1.3.4_A2.3_T1': [SKIP], +}], # 'arch == arm or arch == mipsel' +] diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py index fc03504dca..89f729d9a3 100644 --- a/deps/v8/test/test262/testcfg.py +++ b/deps/v8/test/test262/testcfg.py @@ -39,8 +39,7 @@ from testrunner.objects import testcase TEST_262_ARCHIVE_REVISION = "99aac3bc1cad" # This is the r365 revision. TEST_262_ARCHIVE_MD5 = "aadbd720ce9bdb4f8f3de066f4d7eea1" TEST_262_URL = "http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2" -TEST_262_HARNESS = ["sta.js", "testBuiltInObject.js"] -TEST_262_SKIP = ["intl402"] +TEST_262_HARNESS = ["sta.js", "testBuiltInObject.js", "testIntl.js"] class Test262TestSuite(testsuite.TestSuite): @@ -60,8 +59,8 @@ class Test262TestSuite(testsuite.TestSuite): for dirname, dirs, files in os.walk(self.testroot): for dotted in [x for x in dirs if x.startswith(".")]: dirs.remove(dotted) - for skipped in [x for x in dirs if x in TEST_262_SKIP]: - dirs.remove(skipped) + if context.noi18n and "intl402" in dirs: + dirs.remove("intl402") dirs.sort() files.sort() for filename in files: diff --git a/deps/v8/test/webkit/webkit.status b/deps/v8/test/webkit/webkit.status index 4aaf8a97fb..eba1be3f0f 100644 --- a/deps/v8/test/webkit/webkit.status +++ b/deps/v8/test/webkit/webkit.status @@ -25,11 +25,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Too slow in debug mode. -dfg-int-overflow-in-loop: PASS, SKIP if $mode == debug -dfg-double-vote-fuzz: PASS, SKIP if $mode == debug -reentrant-caching: PASS, SKIP if $mode == debug -sort-large-array: PASS, SKIP if $mode == debug - -############################################################################## -[ $deopt_fuzzer == True ] +[ +['mode == debug', { + # Too slow in debug mode. + 'dfg-int-overflow-in-loop': [SKIP], + 'dfg-double-vote-fuzz': [SKIP], + 'reentrant-caching': [SKIP], + 'sort-large-array': [SKIP], +}], # 'mode == debug' +] |