diff options
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' +] |