summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest')
-rw-r--r--deps/v8/test/cctest/SConscript12
-rw-r--r--deps/v8/test/cctest/cctest.gyp32
-rw-r--r--deps/v8/test/cctest/cctest.h9
-rw-r--r--deps/v8/test/cctest/cctest.status30
-rw-r--r--deps/v8/test/cctest/test-accessors.cc6
-rw-r--r--deps/v8/test/cctest/test-alloc.cc74
-rw-r--r--deps/v8/test/cctest/test-api.cc2444
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc470
-rw-r--r--deps/v8/test/cctest/test-assembler-ia32.cc85
-rw-r--r--deps/v8/test/cctest/test-assembler-mips.cc1097
-rw-r--r--deps/v8/test/cctest/test-assembler-x64.cc57
-rw-r--r--deps/v8/test/cctest/test-ast.cc3
-rw-r--r--deps/v8/test/cctest/test-circular-queue.cc3
-rw-r--r--deps/v8/test/cctest/test-compiler.cc96
-rw-r--r--deps/v8/test/cctest/test-conversions.cc207
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc188
-rw-r--r--deps/v8/test/cctest/test-dataflow.cc3
-rw-r--r--deps/v8/test/cctest/test-debug.cc232
-rw-r--r--deps/v8/test/cctest/test-decls.cc2
-rw-r--r--deps/v8/test/cctest/test-deoptimization.cc53
-rw-r--r--deps/v8/test/cctest/test-disasm-arm.cc239
-rw-r--r--deps/v8/test/cctest/test-disasm-ia32.cc21
-rw-r--r--deps/v8/test/cctest/test-disasm-mips.cc432
-rw-r--r--deps/v8/test/cctest/test-func-name-inference.cc96
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc908
-rw-r--r--deps/v8/test/cctest/test-heap.cc400
-rw-r--r--deps/v8/test/cctest/test-liveedit.cc9
-rw-r--r--deps/v8/test/cctest/test-lockers.cc629
-rw-r--r--deps/v8/test/cctest/test-log-stack-tracer.cc44
-rw-r--r--deps/v8/test/cctest/test-log.cc220
-rwxr-xr-xdeps/v8/test/cctest/test-macro-assembler-x64.cc424
-rw-r--r--deps/v8/test/cctest/test-mark-compact.cc258
-rw-r--r--deps/v8/test/cctest/test-mips.cc52
-rwxr-xr-xdeps/v8/test/cctest/test-parsing.cc55
-rw-r--r--deps/v8/test/cctest/test-platform-linux.cc1
-rw-r--r--deps/v8/test/cctest/test-platform-tls.cc66
-rw-r--r--deps/v8/test/cctest/test-platform-win32.cc1
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc2
-rw-r--r--deps/v8/test/cctest/test-regexp.cc147
-rw-r--r--deps/v8/test/cctest/test-reloc-info.cc29
-rw-r--r--deps/v8/test/cctest/test-serialize.cc87
-rw-r--r--deps/v8/test/cctest/test-sockets.cc8
-rw-r--r--deps/v8/test/cctest/test-spaces.cc76
-rw-r--r--deps/v8/test/cctest/test-strings.cc46
-rw-r--r--deps/v8/test/cctest/test-thread-termination.cc50
-rw-r--r--deps/v8/test/cctest/test-threads.cc57
-rw-r--r--deps/v8/test/cctest/test-type-info.cc56
-rw-r--r--deps/v8/test/cctest/test-utils.cc14
-rw-r--r--deps/v8/test/cctest/testcfg.py10
49 files changed, 7134 insertions, 2406 deletions
diff --git a/deps/v8/test/cctest/SConscript b/deps/v8/test/cctest/SConscript
index 703813776..0197178cf 100644
--- a/deps/v8/test/cctest/SConscript
+++ b/deps/v8/test/cctest/SConscript
@@ -41,8 +41,8 @@ SOURCES = {
'test-alloc.cc',
'test-api.cc',
'test-ast.cc',
- 'test-bignum.cc',
'test-bignum-dtoa.cc',
+ 'test-bignum.cc',
'test-circular-queue.cc',
'test-compiler.cc',
'test-conversions.cc',
@@ -59,15 +59,17 @@ SOURCES = {
'test-flags.cc',
'test-func-name-inference.cc',
'test-hashmap.cc',
- 'test-heap.cc',
'test-heap-profiler.cc',
+ 'test-heap.cc',
'test-list.cc',
'test-liveedit.cc',
'test-lock.cc',
- 'test-log.cc',
+ 'test-lockers.cc',
'test-log-utils.cc',
+ 'test-log.cc',
'test-mark-compact.cc',
'test-parsing.cc',
+ 'test-platform-tls.cc',
'test-profile-generator.cc',
'test-regexp.cc',
'test-reloc-info.cc',
@@ -78,7 +80,6 @@ SOURCES = {
'test-strtod.cc',
'test-thread-termination.cc',
'test-threads.cc',
- 'test-type-info.cc',
'test-unbound-queue.cc',
'test-utils.cc',
'test-version.cc'
@@ -95,7 +96,8 @@ SOURCES = {
'arch:x64': ['test-assembler-x64.cc',
'test-macro-assembler-x64.cc',
'test-log-stack-tracer.cc'],
- 'arch:mips': ['test-assembler-mips.cc', 'test-mips.cc'],
+ 'arch:mips': ['test-assembler-mips.cc',
+ 'test-disasm-mips.cc'],
'os:linux': ['test-platform-linux.cc'],
'os:macos': ['test-platform-macos.cc'],
'os:nullos': ['test-platform-nullos.cc'],
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index aa2b35583..1d54e8cf5 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -1,4 +1,4 @@
-# Copyright 2010 the V8 project authors. All rights reserved.
+# 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:
@@ -26,31 +26,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
- 'target_defaults': {
- 'conditions': [
- ['OS!="mac"', {
- # TODO(sgjesse): This is currently copied from v8.gyp, should probably
- # be refactored.
- 'conditions': [
- ['v8_target_arch=="arm"', {
- 'defines': [
- 'V8_TARGET_ARCH_ARM',
- ],
- }],
- ['v8_target_arch=="ia32"', {
- 'defines': [
- 'V8_TARGET_ARCH_IA32',
- ],
- }],
- ['v8_target_arch=="x64"', {
- 'defines': [
- 'V8_TARGET_ARCH_X64',
- ],
- }],
- ],
- }],
- ],
- },
+ 'includes': [ '../../build/v8-features.gypi' ],
'targets': [
{
'target_name': 'cctest',
@@ -93,6 +69,7 @@
'test-list.cc',
'test-liveedit.cc',
'test-lock.cc',
+ 'test-lockers.cc',
'test-log.cc',
'test-log-utils.cc',
'test-mark-compact.cc',
@@ -107,7 +84,6 @@
'test-strtod.cc',
'test-thread-termination.cc',
'test-threads.cc',
- 'test-type-info.cc',
'test-unbound-queue.cc',
'test-utils.cc',
'test-version.cc'
@@ -136,7 +112,7 @@
['v8_target_arch=="mips"', {
'sources': [
'test-assembler-mips.cc',
- 'test-mips.cc',
+ 'test-disasm-mips.cc',
],
}],
[ 'OS=="linux"', {
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index 404b692b2..b0b8eb720 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -88,7 +88,8 @@ class ApiTestFuzzer: public v8::internal::Thread {
public:
void CallTest();
explicit ApiTestFuzzer(int num)
- : test_number_(num),
+ : Thread("ApiTestFuzzer"),
+ test_number_(num),
gate_(v8::internal::OS::CreateSemaphore(0)),
active_(true) {
}
@@ -97,7 +98,11 @@ class ApiTestFuzzer: public v8::internal::Thread {
// The ApiTestFuzzer is also a Thread, so it has a Run method.
virtual void Run();
- enum PartOfTest { FIRST_PART, SECOND_PART };
+ enum PartOfTest { FIRST_PART,
+ SECOND_PART,
+ THIRD_PART,
+ FOURTH_PART,
+ LAST_PART = FOURTH_PART };
static void Setup(PartOfTest part);
static void RunAllTests();
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index e573eb29b..6e7824f2f 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -30,17 +30,9 @@ prefix cctest
test-api/Bug*: FAIL
##############################################################################
-# BUG(281): This test fails on some Linuxes.
-test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux
-
# BUG(382): Weird test. Can't guarantee that it never times out.
test-api/ApplyInterruption: PASS || TIMEOUT
-# BUG(484): This test which we thought was originally corrected in r5236
-# is re-appearing. Disabled until bug in test is fixed. This only fails
-# when snapshot is on, so I am marking it PASS || FAIL
-test-heap-profiler/HeapSnapshotsDiff: PASS || 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
@@ -59,10 +51,11 @@ test-api/OutOfMemoryNested: SKIP
test-log/ProfLazyMode: SKIP
# BUG(945): Socket connect fails on ARM
+test-debug/DebuggerAgent: SKIP
test-debug/DebuggerAgentProtocolOverflowHeader: SKIP
test-sockets/Socket: SKIP
-# BUG(1075): Some deserialization tests fail om ARM
+# BUG(1075): Unresolved crashes.
test-serialize/Deserialize: SKIP
test-serialize/DeserializeFromSecondSerializationAndRunScript2: SKIP
test-serialize/DeserializeAndRunScript2: SKIP
@@ -78,22 +71,5 @@ test-debug/DebugBreakLoop: SKIP
##############################################################################
[ $arch == mips ]
-test-accessors: SKIP
-test-alloc: SKIP
-test-api: SKIP
-test-compiler: SKIP
-test-cpu-profiler: SKIP
-test-debug: SKIP
-test-decls: SKIP
-test-func-name-inference: SKIP
-test-heap: SKIP
-test-heap-profiler: SKIP
-test-log: SKIP
-test-log-utils: SKIP
-test-mark-compact: SKIP
-test-regexp: SKIP
+test-deoptimization: SKIP
test-serialize: SKIP
-test-sockets: SKIP
-test-strings: SKIP
-test-threads: SKIP
-test-thread-termination: SKIP
diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc
index 25f5c3951..028f82f3d 100644
--- a/deps/v8/test/cctest/test-accessors.cc
+++ b/deps/v8/test/cctest/test-accessors.cc
@@ -243,7 +243,7 @@ static v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name,
ApiTestFuzzer::Fuzz();
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
- i::Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
return v8::Integer::New(17);
@@ -397,9 +397,9 @@ static v8::Handle<Value> StackCheck(Local<String> name,
for (int i = 0; !iter.done(); i++) {
i::StackFrame* frame = iter.frame();
CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT));
- CHECK(frame->code()->IsCode());
+ i::Code* code = frame->LookupCode();
+ CHECK(code->IsCode());
i::Address pc = frame->pc();
- i::Code* code = frame->code();
CHECK(code->contains(pc));
iter.Advance();
}
diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc
index d2a28d7f4..4d9c218a4 100644
--- a/deps/v8/test/cctest/test-alloc.cc
+++ b/deps/v8/test/cctest/test-alloc.cc
@@ -27,7 +27,6 @@
#include "v8.h"
#include "accessors.h"
-#include "top.h"
#include "cctest.h"
@@ -38,13 +37,14 @@ using namespace v8::internal;
static MaybeObject* AllocateAfterFailures() {
static int attempts = 0;
if (++attempts < 3) return Failure::RetryAfterGC();
+ Heap* heap = Isolate::Current()->heap();
// New space.
- NewSpace* new_space = Heap::new_space();
+ NewSpace* new_space = heap->new_space();
static const int kNewSpaceFillerSize = ByteArray::SizeFor(0);
while (new_space->Available() > kNewSpaceFillerSize) {
int available_before = static_cast<int>(new_space->Available());
- CHECK(!Heap::AllocateByteArray(0)->IsFailure());
+ CHECK(!heap->AllocateByteArray(0)->IsFailure());
if (available_before == new_space->Available()) {
// It seems that we are avoiding new space allocations when
// allocation is forced, so no need to fill up new space
@@ -52,45 +52,46 @@ static MaybeObject* AllocateAfterFailures() {
break;
}
}
- CHECK(!Heap::AllocateByteArray(100)->IsFailure());
- CHECK(!Heap::AllocateFixedArray(100, NOT_TENURED)->IsFailure());
+ CHECK(!heap->AllocateByteArray(100)->IsFailure());
+ CHECK(!heap->AllocateFixedArray(100, NOT_TENURED)->IsFailure());
// Make sure we can allocate through optimized allocation functions
// for specific kinds.
- CHECK(!Heap::AllocateFixedArray(100)->IsFailure());
- CHECK(!Heap::AllocateHeapNumber(0.42)->IsFailure());
- CHECK(!Heap::AllocateArgumentsObject(Smi::FromInt(87), 10)->IsFailure());
- Object* object =
- Heap::AllocateJSObject(*Top::object_function())->ToObjectChecked();
- CHECK(!Heap::CopyJSObject(JSObject::cast(object))->IsFailure());
+ CHECK(!heap->AllocateFixedArray(100)->IsFailure());
+ CHECK(!heap->AllocateHeapNumber(0.42)->IsFailure());
+ CHECK(!heap->AllocateArgumentsObject(Smi::FromInt(87), 10)->IsFailure());
+ Object* object = heap->AllocateJSObject(
+ *Isolate::Current()->object_function())->ToObjectChecked();
+ CHECK(!heap->CopyJSObject(JSObject::cast(object))->IsFailure());
// Old data space.
- OldSpace* old_data_space = Heap::old_data_space();
+ OldSpace* old_data_space = heap->old_data_space();
static const int kOldDataSpaceFillerSize = ByteArray::SizeFor(0);
while (old_data_space->Available() > kOldDataSpaceFillerSize) {
- CHECK(!Heap::AllocateByteArray(0, TENURED)->IsFailure());
+ CHECK(!heap->AllocateByteArray(0, TENURED)->IsFailure());
}
- CHECK(!Heap::AllocateRawAsciiString(100, TENURED)->IsFailure());
+ CHECK(!heap->AllocateRawAsciiString(100, TENURED)->IsFailure());
// Large object space.
- while (!Heap::OldGenerationAllocationLimitReached()) {
- CHECK(!Heap::AllocateFixedArray(10000, TENURED)->IsFailure());
+ while (!heap->OldGenerationAllocationLimitReached()) {
+ CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure());
}
- CHECK(!Heap::AllocateFixedArray(10000, TENURED)->IsFailure());
+ CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure());
// Map space.
- MapSpace* map_space = Heap::map_space();
+ MapSpace* map_space = heap->map_space();
static const int kMapSpaceFillerSize = Map::kSize;
InstanceType instance_type = JS_OBJECT_TYPE;
int instance_size = JSObject::kHeaderSize;
while (map_space->Available() > kMapSpaceFillerSize) {
- CHECK(!Heap::AllocateMap(instance_type, instance_size)->IsFailure());
+ CHECK(!heap->AllocateMap(instance_type, instance_size)->IsFailure());
}
- CHECK(!Heap::AllocateMap(instance_type, instance_size)->IsFailure());
+ CHECK(!heap->AllocateMap(instance_type, instance_size)->IsFailure());
// Test that we can allocate in old pointer space and code space.
- CHECK(!Heap::AllocateFixedArray(100, TENURED)->IsFailure());
- CHECK(!Heap::CopyCode(Builtins::builtin(Builtins::Illegal))->IsFailure());
+ CHECK(!heap->AllocateFixedArray(100, TENURED)->IsFailure());
+ CHECK(!heap->CopyCode(Isolate::Current()->builtins()->builtin(
+ Builtins::kIllegal))->IsFailure());
// Return success.
return Smi::FromInt(42);
@@ -98,7 +99,7 @@ static MaybeObject* AllocateAfterFailures() {
static Handle<Object> Test() {
- CALL_HEAP_FUNCTION(AllocateAfterFailures(), Object);
+ CALL_HEAP_FUNCTION(ISOLATE, AllocateAfterFailures(), Object);
}
@@ -129,19 +130,20 @@ TEST(StressJS) {
v8::HandleScope scope;
env->Enter();
Handle<JSFunction> function =
- Factory::NewFunction(Factory::function_symbol(), Factory::null_value());
+ FACTORY->NewFunction(FACTORY->function_symbol(), FACTORY->null_value());
// Force the creation of an initial map and set the code to
// something empty.
- Factory::NewJSObject(function);
- function->ReplaceCode(Builtins::builtin(Builtins::EmptyFunction));
+ FACTORY->NewJSObject(function);
+ function->ReplaceCode(Isolate::Current()->builtins()->builtin(
+ Builtins::kEmptyFunction));
// Patch the map to have an accessor for "get".
Handle<Map> map(function->initial_map());
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
- Handle<Proxy> proxy = Factory::NewProxy(&kDescriptor);
- instance_descriptors = Factory::CopyAppendProxyDescriptor(
+ Handle<Foreign> foreign = FACTORY->NewForeign(&kDescriptor);
+ instance_descriptors = FACTORY->CopyAppendForeignDescriptor(
instance_descriptors,
- Factory::NewStringFromAscii(Vector<const char>("get", 3)),
- proxy,
+ FACTORY->NewStringFromAscii(Vector<const char>("get", 3)),
+ foreign,
static_cast<PropertyAttributes>(0));
map->set_instance_descriptors(*instance_descriptors);
// Add the Foo constructor the global object.
@@ -183,7 +185,8 @@ class Block {
TEST(CodeRange) {
const int code_range_size = 16*MB;
- CodeRange::Setup(code_range_size);
+ OS::Setup();
+ Isolate::Current()->code_range()->Setup(code_range_size);
int current_allocated = 0;
int total_allocated = 0;
List<Block> blocks(1000);
@@ -195,14 +198,17 @@ TEST(CodeRange) {
size_t requested = (Page::kPageSize << (Pseudorandom() % 6)) +
Pseudorandom() % 5000 + 1;
size_t allocated = 0;
- void* base = CodeRange::AllocateRawMemory(requested, &allocated);
+ void* base = Isolate::Current()->code_range()->
+ AllocateRawMemory(requested, &allocated);
+ CHECK(base != NULL);
blocks.Add(Block(base, static_cast<int>(allocated)));
current_allocated += static_cast<int>(allocated);
total_allocated += static_cast<int>(allocated);
} else {
// Free a block.
int index = Pseudorandom() % blocks.length();
- CodeRange::FreeRawMemory(blocks[index].base, blocks[index].size);
+ Isolate::Current()->code_range()->FreeRawMemory(
+ blocks[index].base, blocks[index].size);
current_allocated -= blocks[index].size;
if (index < blocks.length() - 1) {
blocks[index] = blocks.RemoveLast();
@@ -212,5 +218,5 @@ TEST(CodeRange) {
}
}
- CodeRange::TearDown();
+ Isolate::Current()->code_range()->TearDown();
}
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index f450a3459..097743dd1 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2009 the V8 project authors. All rights reserved.
+// 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:
@@ -30,17 +30,17 @@
#include "v8.h"
#include "api.h"
+#include "isolate.h"
#include "compilation-cache.h"
#include "execution.h"
#include "snapshot.h"
#include "platform.h"
-#include "top.h"
#include "utils.h"
#include "cctest.h"
#include "parser.h"
#include "unicode-inl.h"
-static const bool kLogThreading = true;
+static const bool kLogThreading = false;
static bool IsNaN(double x) {
#ifdef WIN32
@@ -50,15 +50,27 @@ static bool IsNaN(double x) {
#endif
}
-using ::v8::ObjectTemplate;
-using ::v8::Value;
+using ::v8::AccessorInfo;
+using ::v8::Arguments;
using ::v8::Context;
+using ::v8::Extension;
+using ::v8::Function;
+using ::v8::FunctionTemplate;
+using ::v8::Handle;
+using ::v8::HandleScope;
using ::v8::Local;
-using ::v8::String;
+using ::v8::Message;
+using ::v8::MessageCallback;
+using ::v8::Object;
+using ::v8::ObjectTemplate;
+using ::v8::Persistent;
using ::v8::Script;
-using ::v8::Function;
-using ::v8::AccessorInfo;
-using ::v8::Extension;
+using ::v8::StackTrace;
+using ::v8::String;
+using ::v8::TryCatch;
+using ::v8::Undefined;
+using ::v8::V8;
+using ::v8::Value;
namespace i = ::i;
@@ -191,8 +203,6 @@ THREADED_TEST(ReceiverSignature) {
}
-
-
THREADED_TEST(ArgumentSignature) {
v8::HandleScope scope;
LocalContext env;
@@ -394,11 +404,11 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK(source->IsExternal());
CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource()));
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(0, TestResource::dispose_count);
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
+ v8::internal::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, TestResource::dispose_count);
}
@@ -415,11 +425,11 @@ THREADED_TEST(ScriptUsingAsciiStringResource) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count);
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
+ i::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResource::dispose_count);
}
@@ -432,19 +442,19 @@ THREADED_TEST(ScriptMakingExternalString) {
LocalContext env;
Local<String> source = String::New(two_byte_source);
// Trigger GCs so that the newly allocated string moves to old gen.
- i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now
- i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
bool success = source->MakeExternal(new TestResource(two_byte_source));
CHECK(success);
Local<Script> script = Script::Compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(0, TestResource::dispose_count);
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
+ i::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, TestResource::dispose_count);
}
@@ -457,8 +467,8 @@ THREADED_TEST(ScriptMakingExternalAsciiString) {
LocalContext env;
Local<String> source = v8_str(c_source);
// Trigger GCs so that the newly allocated string moves to old gen.
- i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now
- i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
bool success = source->MakeExternal(
new TestAsciiResource(i::StrDup(c_source)));
CHECK(success);
@@ -466,11 +476,11 @@ THREADED_TEST(ScriptMakingExternalAsciiString) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count);
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
+ i::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResource::dispose_count);
}
@@ -480,8 +490,8 @@ TEST(MakingExternalStringConditions) {
LocalContext env;
// Free some space in the new space so that we can check freshness.
- i::Heap::CollectGarbage(i::NEW_SPACE);
- i::Heap::CollectGarbage(i::NEW_SPACE);
+ HEAP->CollectGarbage(i::NEW_SPACE);
+ HEAP->CollectGarbage(i::NEW_SPACE);
uint16_t* two_byte_string = AsciiToTwoByteString("small");
Local<String> small_string = String::New(two_byte_string);
@@ -490,8 +500,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.
- i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now
- i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
// Old space strings should be accepted.
CHECK(small_string->CanMakeExternal());
@@ -526,15 +536,15 @@ TEST(MakingExternalAsciiStringConditions) {
LocalContext env;
// Free some space in the new space so that we can check freshness.
- i::Heap::CollectGarbage(i::NEW_SPACE);
- i::Heap::CollectGarbage(i::NEW_SPACE);
+ HEAP->CollectGarbage(i::NEW_SPACE);
+ HEAP->CollectGarbage(i::NEW_SPACE);
Local<String> small_string = String::New("small");
// 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.
- i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now
- i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
// Old space strings should be accepted.
CHECK(small_string->CanMakeExternal());
@@ -566,13 +576,13 @@ THREADED_TEST(UsingExternalString) {
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.
- i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now
- i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now
- i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring);
+ HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
+ i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring);
CHECK(isymbol->IsSymbol());
}
- i::Heap::CollectAllGarbage(false);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
}
@@ -584,13 +594,13 @@ THREADED_TEST(UsingExternalAsciiString) {
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.
- i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now
- i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now
- i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring);
+ HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
+ HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
+ i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring);
CHECK(isymbol->IsSymbol());
}
- i::Heap::CollectAllGarbage(false);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
}
@@ -603,12 +613,12 @@ THREADED_TEST(ScavengeExternalString) {
Local<String> string =
String::NewExternal(new TestResource(two_byte_string));
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
- i::Heap::CollectGarbage(i::NEW_SPACE);
- in_new_space = i::Heap::InNewSpace(*istring);
- CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring));
+ HEAP->CollectGarbage(i::NEW_SPACE);
+ in_new_space = HEAP->InNewSpace(*istring);
+ CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring));
CHECK_EQ(0, TestResource::dispose_count);
}
- i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
+ HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
CHECK_EQ(1, TestResource::dispose_count);
}
@@ -622,12 +632,12 @@ THREADED_TEST(ScavengeExternalAsciiString) {
Local<String> string = String::NewExternal(
new TestAsciiResource(i::StrDup(one_byte_string)));
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
- i::Heap::CollectGarbage(i::NEW_SPACE);
- in_new_space = i::Heap::InNewSpace(*istring);
- CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring));
+ HEAP->CollectGarbage(i::NEW_SPACE);
+ in_new_space = HEAP->InNewSpace(*istring);
+ CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring));
CHECK_EQ(0, TestAsciiResource::dispose_count);
}
- i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
+ HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
CHECK_EQ(1, TestAsciiResource::dispose_count);
}
@@ -667,11 +677,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count);
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
+ i::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
CHECK_EQ(0, TestAsciiResource::dispose_count);
@@ -688,11 +698,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count);
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
+ i::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
CHECK_EQ(1, TestAsciiResource::dispose_count);
}
@@ -738,9 +748,9 @@ THREADED_TEST(StringConcat) {
CHECK(value->IsNumber());
CHECK_EQ(68, value->Int32Value());
}
- i::CompilationCache::Clear();
- i::Heap::CollectAllGarbage(false);
- i::Heap::CollectAllGarbage(false);
+ i::Isolate::Current()->compilation_cache()->Clear();
+ HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
}
@@ -1041,8 +1051,10 @@ THREADED_TEST(Date) {
v8::HandleScope scope;
LocalContext env;
double PI = 3.1415926;
- Local<Value> date_obj = v8::Date::New(PI);
- CHECK_EQ(3.0, date_obj->NumberValue());
+ Local<Value> date = v8::Date::New(PI);
+ CHECK_EQ(3.0, date->NumberValue());
+ date.As<v8::Date>()->Set(v8_str("property"), v8::Integer::New(42));
+ CHECK_EQ(42, date.As<v8::Date>()->Get(v8_str("property"))->Int32Value());
}
@@ -1575,12 +1587,12 @@ THREADED_TEST(InternalFieldsNativePointers) {
// Check reading and writing aligned pointers.
obj->SetPointerInInternalField(0, aligned);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
// Check reading and writing unaligned pointers.
obj->SetPointerInInternalField(0, unaligned);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
delete[] data;
@@ -1606,19 +1618,19 @@ THREADED_TEST(InternalFieldsNativePointersAndExternal) {
CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
obj->SetPointerInInternalField(0, aligned);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0)));
obj->SetPointerInInternalField(0, unaligned);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0)));
obj->SetInternalField(0, v8::External::Wrap(aligned));
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
obj->SetInternalField(0, v8::External::Wrap(unaligned));
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
delete[] data;
@@ -1631,7 +1643,7 @@ THREADED_TEST(IdentityHash) {
// Ensure that the test starts with an fresh heap to test whether the hash
// code is based on the address.
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
Local<v8::Object> obj = v8::Object::New();
int hash = obj->GetIdentityHash();
int hash1 = obj->GetIdentityHash();
@@ -1641,7 +1653,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);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
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
@@ -1678,7 +1690,7 @@ THREADED_TEST(HiddenProperties) {
v8::Local<v8::String> empty = v8_str("");
v8::Local<v8::String> prop_name = v8_str("prop_name");
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
// Make sure delete of a non-existent hidden value works
CHECK(obj->DeleteHiddenValue(key));
@@ -1688,7 +1700,7 @@ THREADED_TEST(HiddenProperties) {
CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
// Make sure we do not find the hidden property.
CHECK(!obj->Has(empty));
@@ -1699,7 +1711,7 @@ THREADED_TEST(HiddenProperties) {
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CHECK_EQ(2003, obj->Get(empty)->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
// Add another property and delete it afterwards to force the object in
// slow case.
@@ -1710,7 +1722,7 @@ THREADED_TEST(HiddenProperties) {
CHECK(obj->Delete(prop_name));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK(obj->DeleteHiddenValue(key));
CHECK(obj->GetHiddenValue(key).IsEmpty());
@@ -1789,6 +1801,180 @@ THREADED_TEST(GlobalHandle) {
}
+static int NumberOfWeakCalls = 0;
+static void WeakPointerCallback(Persistent<Value> handle, void* id) {
+ CHECK_EQ(reinterpret_cast<void*>(1234), id);
+ NumberOfWeakCalls++;
+ handle.Dispose();
+}
+
+THREADED_TEST(ApiObjectGroups) {
+ HandleScope scope;
+ LocalContext env;
+
+ NumberOfWeakCalls = 0;
+
+ Persistent<Object> g1s1;
+ Persistent<Object> g1s2;
+ Persistent<Object> g1c1;
+ Persistent<Object> g2s1;
+ Persistent<Object> g2s2;
+ Persistent<Object> g2c1;
+
+ {
+ HandleScope scope;
+ g1s1 = Persistent<Object>::New(Object::New());
+ g1s2 = Persistent<Object>::New(Object::New());
+ g1c1 = Persistent<Object>::New(Object::New());
+ g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+
+ g2s1 = Persistent<Object>::New(Object::New());
+ g2s2 = Persistent<Object>::New(Object::New());
+ g2c1 = Persistent<Object>::New(Object::New());
+ g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ }
+
+ Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root.
+
+ // Connect group 1 and 2, make a cycle.
+ CHECK(g1s2->Set(0, g2s2));
+ CHECK(g2s1->Set(0, g1s1));
+
+ {
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 };
+ Persistent<Value> g1_children[] = { g1c1 };
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 };
+ Persistent<Value> g2_children[] = { g2c1 };
+ V8::AddObjectGroup(g1_objects, 2);
+ V8::AddImplicitReferences(g1s1, g1_children, 1);
+ V8::AddObjectGroup(g2_objects, 2);
+ V8::AddImplicitReferences(g2s2, g2_children, 1);
+ }
+ // Do a full GC
+ HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+
+ // All object should be alive.
+ CHECK_EQ(0, NumberOfWeakCalls);
+
+ // Weaken the root.
+ root.MakeWeak(reinterpret_cast<void*>(1234), &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.
+ {
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 };
+ Persistent<Value> g1_children[] = { g1c1 };
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 };
+ Persistent<Value> g2_children[] = { g2c1 };
+ V8::AddObjectGroup(g1_objects, 2);
+ V8::AddImplicitReferences(g1s1, g1_children, 1);
+ V8::AddObjectGroup(g2_objects, 2);
+ V8::AddImplicitReferences(g2s2, g2_children, 1);
+ }
+
+ HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+
+ // All objects should be gone. 5 global handles in total.
+ CHECK_EQ(5, NumberOfWeakCalls);
+
+ // And now make children weak again and collect them.
+ g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+
+ HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+ CHECK_EQ(7, NumberOfWeakCalls);
+}
+
+
+THREADED_TEST(ApiObjectGroupsCycle) {
+ HandleScope scope;
+ LocalContext env;
+
+ NumberOfWeakCalls = 0;
+
+ Persistent<Object> g1s1;
+ Persistent<Object> g1s2;
+ Persistent<Object> g2s1;
+ Persistent<Object> g2s2;
+ Persistent<Object> g3s1;
+ Persistent<Object> g3s2;
+
+ {
+ HandleScope scope;
+ g1s1 = Persistent<Object>::New(Object::New());
+ g1s2 = Persistent<Object>::New(Object::New());
+ g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+
+ g2s1 = Persistent<Object>::New(Object::New());
+ g2s2 = Persistent<Object>::New(Object::New());
+ g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+
+ g3s1 = Persistent<Object>::New(Object::New());
+ g3s2 = Persistent<Object>::New(Object::New());
+ g3s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g3s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ }
+
+ Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root.
+
+ // Connect groups. We're building the following cycle:
+ // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
+ // groups.
+ {
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 };
+ Persistent<Value> g1_children[] = { g2s1 };
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 };
+ Persistent<Value> g2_children[] = { g3s1 };
+ Persistent<Value> g3_objects[] = { g3s1, g3s2 };
+ Persistent<Value> g3_children[] = { g1s1 };
+ V8::AddObjectGroup(g1_objects, 2);
+ V8::AddImplicitReferences(g1s1, g1_children, 1);
+ V8::AddObjectGroup(g2_objects, 2);
+ V8::AddImplicitReferences(g2s1, g2_children, 1);
+ V8::AddObjectGroup(g3_objects, 2);
+ V8::AddImplicitReferences(g3s1, g3_children, 1);
+ }
+ // Do a full GC
+ HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+
+ // All object should be alive.
+ CHECK_EQ(0, NumberOfWeakCalls);
+
+ // Weaken the root.
+ root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+
+ // Groups are deleted, rebuild groups.
+ {
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 };
+ Persistent<Value> g1_children[] = { g2s1 };
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 };
+ Persistent<Value> g2_children[] = { g3s1 };
+ Persistent<Value> g3_objects[] = { g3s1, g3s2 };
+ Persistent<Value> g3_children[] = { g1s1 };
+ V8::AddObjectGroup(g1_objects, 2);
+ V8::AddImplicitReferences(g1s1, g1_children, 1);
+ V8::AddObjectGroup(g2_objects, 2);
+ V8::AddImplicitReferences(g2s1, g2_children, 1);
+ V8::AddObjectGroup(g3_objects, 2);
+ V8::AddImplicitReferences(g3s1, g3_children, 1);
+ }
+
+ HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+
+ // All objects should be gone. 7 global handles in total.
+ CHECK_EQ(7, NumberOfWeakCalls);
+}
+
+
THREADED_TEST(ScriptException) {
v8::HandleScope scope;
LocalContext env;
@@ -1900,6 +2086,10 @@ THREADED_TEST(Array) {
CHECK_EQ(1, arr->Get(0)->Int32Value());
CHECK_EQ(2, arr->Get(1)->Int32Value());
CHECK_EQ(3, arr->Get(2)->Int32Value());
+ array = v8::Array::New(27);
+ CHECK_EQ(27, array->Length());
+ array = v8::Array::New(-27);
+ CHECK_EQ(0, array->Length());
}
@@ -2082,8 +2272,6 @@ TEST(OutOfMemoryNested) {
TEST(HugeConsStringOutOfMemory) {
// It's not possible to read a snapshot into a heap with different dimensions.
if (i::Snapshot::IsEnabled()) return;
- v8::HandleScope scope;
- LocalContext context;
// Set heap limits.
static const int K = 1024;
v8::ResourceConstraints constraints;
@@ -2094,6 +2282,9 @@ TEST(HugeConsStringOutOfMemory) {
// Execute a script that causes out of memory.
v8::V8::IgnoreOutOfMemoryException();
+ v8::HandleScope scope;
+ LocalContext context;
+
// Build huge string. This should fail with out of memory exception.
Local<Value> result = CompileRun(
"var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();"
@@ -2473,6 +2664,21 @@ TEST(APIThrowMessageAndVerboseTryCatch) {
}
+TEST(APIStackOverflowAndVerboseTryCatch) {
+ message_received = false;
+ v8::HandleScope scope;
+ v8::V8::AddMessageListener(receive_message);
+ LocalContext context;
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ Local<Value> result = CompileRun("function foo() { foo(); } foo();");
+ CHECK(try_catch.HasCaught());
+ CHECK(result.IsEmpty());
+ CHECK(message_received);
+ v8::V8::RemoveMessageListeners(receive_message);
+}
+
+
THREADED_TEST(ExternalScriptException) {
v8::HandleScope scope;
Local<ObjectTemplate> templ = ObjectTemplate::New();
@@ -2513,7 +2719,7 @@ v8::Handle<Value> CThrowCountDown(const v8::Arguments& args) {
if (try_catch.HasCaught()) {
CHECK_EQ(expected, count);
CHECK(result.IsEmpty());
- CHECK(!i::Top::has_scheduled_exception());
+ CHECK(!i::Isolate::Current()->has_scheduled_exception());
} else {
CHECK_NE(expected, count);
}
@@ -2833,8 +3039,7 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) {
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::AsciiValue exception_value(try_catch.Exception());
- CHECK_EQ(*exception_value,
- "TypeError: Cannot redefine property: defineProperty");
+ CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
}
THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
@@ -2879,8 +3084,7 @@ THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::AsciiValue exception_value(try_catch.Exception());
- CHECK_EQ(*exception_value,
- "TypeError: Cannot redefine property: defineProperty");
+ CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
}
@@ -2998,8 +3202,7 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
"{get: function() { return 'func'; }})");
CHECK(try_catch.HasCaught());
String::AsciiValue exception_value(try_catch.Exception());
- CHECK_EQ(*exception_value,
- "TypeError: Cannot redefine property: defineProperty");
+ CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
}
{
v8::TryCatch try_catch;
@@ -3007,8 +3210,7 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
"{get: function() { return 'func'; }})");
CHECK(try_catch.HasCaught());
String::AsciiValue exception_value(try_catch.Exception());
- CHECK_EQ(*exception_value,
- "TypeError: Cannot redefine property: defineProperty");
+ CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
}
}
@@ -3660,6 +3862,49 @@ THREADED_TEST(UndetectableObject) {
}
+THREADED_TEST(VoidLiteral) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ Local<v8::FunctionTemplate> desc =
+ v8::FunctionTemplate::New(0, v8::Handle<Value>());
+ desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
+
+ Local<v8::Object> obj = desc->GetFunction()->NewInstance();
+ env->Global()->Set(v8_str("undetectable"), obj);
+
+ ExpectBoolean("undefined == void 0", true);
+ ExpectBoolean("undetectable == void 0", true);
+ ExpectBoolean("null == void 0", true);
+ ExpectBoolean("undefined === void 0", true);
+ ExpectBoolean("undetectable === void 0", false);
+ ExpectBoolean("null === void 0", false);
+
+ ExpectBoolean("void 0 == undefined", true);
+ ExpectBoolean("void 0 == undetectable", true);
+ ExpectBoolean("void 0 == null", true);
+ ExpectBoolean("void 0 === undefined", true);
+ ExpectBoolean("void 0 === undetectable", false);
+ ExpectBoolean("void 0 === null", false);
+
+ ExpectString("(function() {"
+ " try {"
+ " return x === void 0;"
+ " } catch(e) {"
+ " return e.toString();"
+ " }"
+ "})()",
+ "ReferenceError: x is not defined");
+ ExpectString("(function() {"
+ " try {"
+ " return void 0 === x;"
+ " } catch(e) {"
+ " return e.toString();"
+ " }"
+ "})()",
+ "ReferenceError: x is not defined");
+}
+
THREADED_TEST(ExtensibleOnUndetectable) {
v8::HandleScope scope;
@@ -3688,10 +3933,8 @@ THREADED_TEST(ExtensibleOnUndetectable) {
source = v8_str("undetectable.y = 2000;");
script = Script::Compile(source);
- v8::TryCatch try_catch;
Local<Value> result = script->Run();
- CHECK(result.IsEmpty());
- CHECK(try_catch.HasCaught());
+ ExpectBoolean("undetectable.y == undefined", true);
}
@@ -3736,6 +3979,38 @@ THREADED_TEST(UndetectableString) {
}
+TEST(UndetectableOptimized) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope;
+ LocalContext env;
+
+ Local<String> obj = String::NewUndetectable("foo");
+ env->Global()->Set(v8_str("undetectable"), obj);
+ env->Global()->Set(v8_str("detectable"), v8_str("bar"));
+
+ ExpectString(
+ "function testBranch() {"
+ " if (!%_IsUndetectableObject(undetectable)) throw 1;"
+ " if (%_IsUndetectableObject(detectable)) throw 2;"
+ "}\n"
+ "function testBool() {"
+ " var b1 = !%_IsUndetectableObject(undetectable);"
+ " var b2 = %_IsUndetectableObject(detectable);"
+ " if (b1) throw 3;"
+ " if (b2) throw 4;"
+ " return b1 == b2;"
+ "}\n"
+ "%OptimizeFunctionOnNextCall(testBranch);"
+ "%OptimizeFunctionOnNextCall(testBool);"
+ "for (var i = 0; i < 10; i++) {"
+ " testBranch();"
+ " testBool();"
+ "}\n"
+ "\"PASS\"",
+ "PASS");
+}
+
+
template <typename T> static void USE(T) { }
@@ -3925,6 +4200,69 @@ THREADED_TEST(NativeCallInExtensions) {
}
+class NativeFunctionExtension : public Extension {
+ public:
+ NativeFunctionExtension(const char* name,
+ const char* source,
+ v8::InvocationCallback fun = &Echo)
+ : Extension(name, source),
+ function_(fun) { }
+
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+ v8::Handle<v8::String> name) {
+ return v8::FunctionTemplate::New(function_);
+ }
+
+ static v8::Handle<v8::Value> Echo(const v8::Arguments& args) {
+ if (args.Length() >= 1) return (args[0]);
+ return v8::Undefined();
+ }
+ private:
+ v8::InvocationCallback function_;
+};
+
+
+THREADED_TEST(NativeFunctionDeclaration) {
+ v8::HandleScope handle_scope;
+ 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(&extensions);
+ Context::Scope lock(context);
+ v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run();
+ CHECK_EQ(result, v8::Integer::New(42));
+}
+
+
+THREADED_TEST(NativeFunctionDeclarationError) {
+ v8::HandleScope handle_scope;
+ const char* name = "nativedeclerr";
+ // Syntax error in extension code.
+ v8::RegisterExtension(new NativeFunctionExtension(name,
+ "native\nfunction foo();"));
+ const char* extension_names[] = { name };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ ASSERT(context.IsEmpty());
+}
+
+THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
+ v8::HandleScope handle_scope;
+ const char* name = "nativedeclerresc";
+ // Syntax error in extension code - escape code in "native" means that
+ // it's not treated as a keyword.
+ v8::RegisterExtension(new NativeFunctionExtension(
+ name,
+ "nativ\\u0065 function foo();"));
+ const char* extension_names[] = { name };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ ASSERT(context.IsEmpty());
+}
+
+
static void CheckDependencies(const char* name, const char* expected) {
v8::HandleScope handle_scope;
v8::ExtensionConfiguration config(1, &name);
@@ -4196,55 +4534,116 @@ THREADED_TEST(WeakReference) {
}
-static bool in_scavenge = false;
-static int last = -1;
-
-static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) {
- CHECK_EQ(-1, last);
- last = 0;
+static void DisposeAndSetFlag(v8::Persistent<v8::Value> obj, void* data) {
obj.Dispose();
obj.Clear();
- in_scavenge = true;
- i::Heap::PerformScavenge();
- in_scavenge = false;
*(reinterpret_cast<bool*>(data)) = true;
}
-static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj,
- void* data) {
- CHECK_EQ(0, last);
- last = 1;
- *(reinterpret_cast<bool*>(data)) = in_scavenge;
- obj.Dispose();
- obj.Clear();
-}
-THREADED_TEST(NoWeakRefCallbacksInScavenge) {
- // Test verifies that scavenge cannot invoke WeakReferenceCallbacks.
- // Calling callbacks from scavenges is unsafe as objects held by those
- // handlers might have become strongly reachable, but scavenge doesn't
- // check that.
+THREADED_TEST(IndependentWeakHandle) {
v8::Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
v8::Persistent<v8::Object> object_a;
- v8::Persistent<v8::Object> object_b;
{
v8::HandleScope handle_scope;
- object_b = v8::Persistent<v8::Object>::New(v8::Object::New());
object_a = v8::Persistent<v8::Object>::New(v8::Object::New());
}
bool object_a_disposed = false;
- object_a.MakeWeak(&object_a_disposed, &ForceScavenge);
- bool released_in_scavenge = false;
- object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge);
+ object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
+ object_a.MarkIndependent();
+ HEAP->PerformScavenge();
+ CHECK(object_a_disposed);
+}
+
+
+static void InvokeScavenge() {
+ HEAP->PerformScavenge();
+}
+
+
+static void InvokeMarkSweep() {
+ HEAP->CollectAllGarbage(false);
+}
+
+
+static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) {
+ obj.Dispose();
+ obj.Clear();
+ *(reinterpret_cast<bool*>(data)) = true;
+ InvokeScavenge();
+}
+
+
+static void ForceMarkSweep(v8::Persistent<v8::Value> obj, void* data) {
+ obj.Dispose();
+ obj.Clear();
+ *(reinterpret_cast<bool*>(data)) = true;
+ InvokeMarkSweep();
+}
+
+
+THREADED_TEST(GCFromWeakCallbacks) {
+ v8::Persistent<Context> context = Context::New();
+ Context::Scope context_scope(context);
+
+ static const int kNumberOfGCTypes = 2;
+ v8::WeakReferenceCallback gc_forcing_callback[kNumberOfGCTypes] =
+ {&ForceScavenge, &ForceMarkSweep};
- while (!object_a_disposed) {
- i::Heap::CollectAllGarbage(false);
+ typedef void (*GCInvoker)();
+ GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep};
+
+ for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) {
+ for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) {
+ v8::Persistent<v8::Object> object;
+ {
+ v8::HandleScope handle_scope;
+ object = v8::Persistent<v8::Object>::New(v8::Object::New());
+ }
+ bool disposed = false;
+ object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]);
+ object.MarkIndependent();
+ invoke_gc[outer_gc]();
+ CHECK(disposed);
+ }
+ }
+}
+
+
+static void RevivingCallback(v8::Persistent<v8::Value> obj, void* data) {
+ obj.ClearWeak();
+ *(reinterpret_cast<bool*>(data)) = true;
+}
+
+
+THREADED_TEST(IndependentHandleRevival) {
+ v8::Persistent<Context> context = Context::New();
+ Context::Scope context_scope(context);
+
+ v8::Persistent<v8::Object> object;
+ {
+ v8::HandleScope handle_scope;
+ object = v8::Persistent<v8::Object>::New(v8::Object::New());
+ object->Set(v8_str("x"), v8::Integer::New(1));
+ v8::Local<String> y_str = v8_str("y");
+ object->Set(y_str, y_str);
+ }
+ bool revived = false;
+ object.MakeWeak(&revived, &RevivingCallback);
+ object.MarkIndependent();
+ HEAP->PerformScavenge();
+ CHECK(revived);
+ HEAP->CollectAllGarbage(true);
+ {
+ v8::HandleScope handle_scope;
+ v8::Local<String> y_str = v8_str("y");
+ CHECK_EQ(v8::Integer::New(1), object->Get(v8_str("x")));
+ CHECK(object->Get(y_str)->Equals(y_str));
}
- CHECK(!released_in_scavenge);
}
@@ -4260,7 +4659,7 @@ static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) {
CHECK_EQ(v8::Integer::New(3), args[2]);
CHECK_EQ(v8::Undefined(), args[3]);
v8::HandleScope scope;
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
return v8::Undefined();
}
@@ -4562,130 +4961,130 @@ THREADED_TEST(StringWrite) {
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
- CHECK_EQ(len, 9);
- CHECK_EQ(charlen, 5);
- CHECK_EQ(strcmp(utf8buf, "abc\303\260\342\230\203"), 0);
+ CHECK_EQ(9, len);
+ CHECK_EQ(5, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203"));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 8, &charlen);
- CHECK_EQ(len, 8);
- CHECK_EQ(charlen, 5);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\342\230\203\1", 9), 0);
+ CHECK_EQ(8, len);
+ CHECK_EQ(5, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203\1", 9));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 7, &charlen);
- CHECK_EQ(len, 5);
- CHECK_EQ(charlen, 4);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(4, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 6, &charlen);
- CHECK_EQ(len, 5);
- CHECK_EQ(charlen, 4);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(4, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 5, &charlen);
- CHECK_EQ(len, 5);
- CHECK_EQ(charlen, 4);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(4, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 4, &charlen);
- CHECK_EQ(len, 3);
- CHECK_EQ(charlen, 3);
- CHECK_EQ(strncmp(utf8buf, "abc\1", 4), 0);
+ CHECK_EQ(3, len);
+ CHECK_EQ(3, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 3, &charlen);
- CHECK_EQ(len, 3);
- CHECK_EQ(charlen, 3);
- CHECK_EQ(strncmp(utf8buf, "abc\1", 4), 0);
+ CHECK_EQ(3, len);
+ CHECK_EQ(3, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 2, &charlen);
- CHECK_EQ(len, 2);
- CHECK_EQ(charlen, 2);
- CHECK_EQ(strncmp(utf8buf, "ab\1", 3), 0);
+ CHECK_EQ(2, len);
+ CHECK_EQ(2, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf);
- CHECK_EQ(len, 5);
+ CHECK_EQ(5, len);
len = str->Write(wbuf);
- CHECK_EQ(len, 5);
- CHECK_EQ(strcmp("abcde", buf), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(0, strcmp("abcde", buf));
uint16_t answer1[] = {'a', 'b', 'c', 'd', 'e', '\0'};
- CHECK_EQ(StrCmp16(answer1, wbuf), 0);
+ CHECK_EQ(0, StrCmp16(answer1, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 4);
- CHECK_EQ(len, 4);
+ CHECK_EQ(4, len);
len = str->Write(wbuf, 0, 4);
- CHECK_EQ(len, 4);
- CHECK_EQ(strncmp("abcd\1", buf, 5), 0);
+ CHECK_EQ(4, len);
+ CHECK_EQ(0, strncmp("abcd\1", buf, 5));
uint16_t answer2[] = {'a', 'b', 'c', 'd', 0x101};
- CHECK_EQ(StrNCmp16(answer2, wbuf, 5), 0);
+ CHECK_EQ(0, StrNCmp16(answer2, wbuf, 5));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 5);
- CHECK_EQ(len, 5);
+ CHECK_EQ(5, len);
len = str->Write(wbuf, 0, 5);
- CHECK_EQ(len, 5);
- CHECK_EQ(strncmp("abcde\1", buf, 6), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(0, strncmp("abcde\1", buf, 6));
uint16_t answer3[] = {'a', 'b', 'c', 'd', 'e', 0x101};
- CHECK_EQ(StrNCmp16(answer3, wbuf, 6), 0);
+ CHECK_EQ(0, StrNCmp16(answer3, wbuf, 6));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 6);
- CHECK_EQ(len, 5);
+ CHECK_EQ(5, len);
len = str->Write(wbuf, 0, 6);
- CHECK_EQ(len, 5);
- CHECK_EQ(strcmp("abcde", buf), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(0, strcmp("abcde", buf));
uint16_t answer4[] = {'a', 'b', 'c', 'd', 'e', '\0'};
- CHECK_EQ(StrCmp16(answer4, wbuf), 0);
+ CHECK_EQ(0, StrCmp16(answer4, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, -1);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 4, -1);
- CHECK_EQ(len, 1);
- CHECK_EQ(strcmp("e", buf), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strcmp("e", buf));
uint16_t answer5[] = {'e', '\0'};
- CHECK_EQ(StrCmp16(answer5, wbuf), 0);
+ CHECK_EQ(0, StrCmp16(answer5, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, 6);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 4, 6);
- CHECK_EQ(len, 1);
- CHECK_EQ(strcmp("e", buf), 0);
- CHECK_EQ(StrCmp16(answer5, wbuf), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strcmp("e", buf));
+ CHECK_EQ(0, StrCmp16(answer5, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, 1);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 4, 1);
- CHECK_EQ(len, 1);
- CHECK_EQ(strncmp("e\1", buf, 2), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strncmp("e\1", buf, 2));
uint16_t answer6[] = {'e', 0x101};
- CHECK_EQ(StrNCmp16(answer6, wbuf, 2), 0);
+ CHECK_EQ(0, StrNCmp16(answer6, wbuf, 2));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 3, 1);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 3, 1);
- CHECK_EQ(len, 1);
- CHECK_EQ(strncmp("d\1", buf, 2), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strncmp("d\1", buf, 2));
uint16_t answer7[] = {'d', 0x101};
- CHECK_EQ(StrNCmp16(answer7, wbuf, 2), 0);
+ CHECK_EQ(0, StrNCmp16(answer7, wbuf, 2));
}
@@ -5659,6 +6058,14 @@ TEST(AccessControlES5) {
global_template->SetAccessCheckCallbacks(NamedAccessBlocker,
IndexedAccessBlocker);
+ // Add accessible accessor.
+ global_template->SetAccessor(
+ v8_str("accessible_prop"),
+ EchoGetter, EchoSetter,
+ v8::Handle<Value>(),
+ v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE));
+
+
// Add an accessor that is not accessible by cross-domain JS code.
global_template->SetAccessor(v8_str("blocked_prop"),
UnreachableGetter, UnreachableSetter,
@@ -5699,6 +6106,18 @@ TEST(AccessControlES5) {
CompileRun("Object.seal(other)");
ExpectTrue("Object.isExtensible(other)");
+
+ // Regression test for issue 1250.
+ // Make sure that we can set the accessible accessors value using normal
+ // assignment.
+ CompileRun("other.accessible_prop = 42");
+ CHECK_EQ(42, g_echo_value);
+
+ v8::Handle<Value> value;
+ // We follow Safari in ignoring assignments to host object accessors.
+ CompileRun("Object.defineProperty(other, 'accessible_prop', {value: -1})");
+ value = CompileRun("other.accessible_prop == 42");
+ CHECK(value->IsTrue());
}
@@ -6347,7 +6766,7 @@ THREADED_TEST(ShadowObject) {
context->Global()->Set(v8_str("__proto__"), o);
Local<Value> value =
- Script::Compile(v8_str("propertyIsEnumerable(0)"))->Run();
+ Script::Compile(v8_str("this.propertyIsEnumerable(0)"))->Run();
CHECK(value->IsBoolean());
CHECK(!value->BooleanValue());
@@ -6466,6 +6885,56 @@ THREADED_TEST(SetPrototype) {
}
+THREADED_TEST(SetPrototypeProperties) {
+ v8::HandleScope handle_scope;
+ LocalContext context;
+
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ t1->SetPrototypeAttributes(v8::DontDelete);
+ context->Global()->Set(v8_str("func1"), t1->GetFunction());
+ CHECK(CompileRun(
+ "(function() {"
+ " descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');"
+ " return (descriptor['writable'] == true) &&"
+ " (descriptor['enumerable'] == true) &&"
+ " (descriptor['configurable'] == false);"
+ "})()")->BooleanValue());
+
+ Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+ t2->SetPrototypeAttributes(v8::DontEnum);
+ context->Global()->Set(v8_str("func2"), t2->GetFunction());
+ CHECK(CompileRun(
+ "(function() {"
+ " descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');"
+ " return (descriptor['writable'] == true) &&"
+ " (descriptor['enumerable'] == false) &&"
+ " (descriptor['configurable'] == true);"
+ "})()")->BooleanValue());
+
+ Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+ t3->SetPrototypeAttributes(v8::ReadOnly);
+ context->Global()->Set(v8_str("func3"), t3->GetFunction());
+ CHECK(CompileRun(
+ "(function() {"
+ " descriptor = Object.getOwnPropertyDescriptor(func3, 'prototype');"
+ " return (descriptor['writable'] == false) &&"
+ " (descriptor['enumerable'] == true) &&"
+ " (descriptor['configurable'] == true);"
+ "})()")->BooleanValue());
+
+ Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
+ t4->SetPrototypeAttributes(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
+ context->Global()->Set(v8_str("func4"), t4->GetFunction());
+ CHECK(CompileRun(
+ "(function() {"
+ " descriptor = Object.getOwnPropertyDescriptor(func4, 'prototype');"
+ " return (descriptor['writable'] == false) &&"
+ " (descriptor['enumerable'] == false) &&"
+ " (descriptor['configurable'] == false);"
+ "})()")->BooleanValue());
+}
+
+
THREADED_TEST(SetPrototypeThrows) {
v8::HandleScope handle_scope;
LocalContext context;
@@ -6481,7 +6950,7 @@ THREADED_TEST(SetPrototypeThrows) {
v8::TryCatch try_catch;
CHECK(!o1->SetPrototype(o0));
CHECK(!try_catch.HasCaught());
- ASSERT(!i::Top::has_pending_exception());
+ ASSERT(!i::Isolate::Current()->has_pending_exception());
CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
}
@@ -6523,6 +6992,200 @@ THREADED_TEST(Constructor) {
CHECK(value->BooleanValue());
}
+
+static Handle<Value> ConstructorCallback(const Arguments& args) {
+ ApiTestFuzzer::Fuzz();
+ Local<Object> This;
+
+ if (args.IsConstructCall()) {
+ Local<Object> Holder = args.Holder();
+ This = Object::New();
+ Local<Value> proto = Holder->GetPrototype();
+ if (proto->IsObject()) {
+ This->SetPrototype(proto);
+ }
+ } else {
+ This = args.This();
+ }
+
+ This->Set(v8_str("a"), args[0]);
+ return This;
+}
+
+
+static Handle<Value> FakeConstructorCallback(const Arguments& args) {
+ ApiTestFuzzer::Fuzz();
+ return args[0];
+}
+
+
+THREADED_TEST(ConstructorForObject) {
+ v8::HandleScope handle_scope;
+ LocalContext context;
+
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ instance_template->SetCallAsFunctionHandler(ConstructorCallback);
+ Local<Object> instance = instance_template->NewInstance();
+ context->Global()->Set(v8_str("obj"), instance);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
+
+ // Call the Object's constructor with a 32-bit signed integer.
+ value = CompileRun("(function() { var o = new obj(28); return o.a; })()");
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsInt32());
+ CHECK_EQ(28, value->Int32Value());
+
+ Local<Value> args1[] = { v8_num(28) };
+ Local<Value> value_obj1 = instance->CallAsConstructor(1, args1);
+ CHECK(value_obj1->IsObject());
+ Local<Object> object1 = Local<Object>::Cast(value_obj1);
+ value = object1->Get(v8_str("a"));
+ CHECK(value->IsInt32());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(28, value->Int32Value());
+
+ // Call the Object's constructor with a String.
+ value = CompileRun(
+ "(function() { var o = new obj('tipli'); return o.a; })()");
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsString());
+ String::AsciiValue string_value1(value->ToString());
+ CHECK_EQ("tipli", *string_value1);
+
+ Local<Value> args2[] = { v8_str("tipli") };
+ Local<Value> value_obj2 = instance->CallAsConstructor(1, args2);
+ CHECK(value_obj2->IsObject());
+ Local<Object> object2 = Local<Object>::Cast(value_obj2);
+ value = object2->Get(v8_str("a"));
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsString());
+ String::AsciiValue string_value2(value->ToString());
+ CHECK_EQ("tipli", *string_value2);
+
+ // Call the Object's constructor with a Boolean.
+ value = CompileRun("(function() { var o = new obj(true); return o.a; })()");
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsBoolean());
+ CHECK_EQ(true, value->BooleanValue());
+
+ Handle<Value> args3[] = { v8::Boolean::New(true) };
+ Local<Value> value_obj3 = instance->CallAsConstructor(1, args3);
+ CHECK(value_obj3->IsObject());
+ Local<Object> object3 = Local<Object>::Cast(value_obj3);
+ value = object3->Get(v8_str("a"));
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsBoolean());
+ CHECK_EQ(true, value->BooleanValue());
+
+ // Call the Object's constructor with undefined.
+ Handle<Value> args4[] = { v8::Undefined() };
+ Local<Value> value_obj4 = instance->CallAsConstructor(1, args4);
+ CHECK(value_obj4->IsObject());
+ Local<Object> object4 = Local<Object>::Cast(value_obj4);
+ value = object4->Get(v8_str("a"));
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsUndefined());
+
+ // Call the Object's constructor with null.
+ Handle<Value> args5[] = { v8::Null() };
+ Local<Value> value_obj5 = instance->CallAsConstructor(1, args5);
+ CHECK(value_obj5->IsObject());
+ Local<Object> object5 = Local<Object>::Cast(value_obj5);
+ value = object5->Get(v8_str("a"));
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsNull());
+ }
+
+ // Check exception handling when there is no constructor set for the Object.
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ Local<Object> instance = instance_template->NewInstance();
+ context->Global()->Set(v8_str("obj2"), instance);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
+
+ value = CompileRun("new obj2(28)");
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value1(try_catch.Exception());
+ CHECK_EQ("TypeError: object is not a function", *exception_value1);
+ try_catch.Reset();
+
+ Local<Value> args[] = { v8_num(29) };
+ value = instance->CallAsConstructor(1, args);
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value2(try_catch.Exception());
+ CHECK_EQ("TypeError: #<Object> is not a function", *exception_value2);
+ try_catch.Reset();
+ }
+
+ // Check the case when constructor throws exception.
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ instance_template->SetCallAsFunctionHandler(ThrowValue);
+ Local<Object> instance = instance_template->NewInstance();
+ context->Global()->Set(v8_str("obj3"), instance);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
+
+ value = CompileRun("new obj3(22)");
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value1(try_catch.Exception());
+ CHECK_EQ("22", *exception_value1);
+ try_catch.Reset();
+
+ Local<Value> args[] = { v8_num(23) };
+ value = instance->CallAsConstructor(1, args);
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value2(try_catch.Exception());
+ CHECK_EQ("23", *exception_value2);
+ try_catch.Reset();
+ }
+
+ // Check whether constructor returns with an object or non-object.
+ { Local<FunctionTemplate> function_template =
+ FunctionTemplate::New(FakeConstructorCallback);
+ Local<Function> function = function_template->GetFunction();
+ Local<Object> instance1 = function;
+ context->Global()->Set(v8_str("obj4"), instance1);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
+
+ CHECK(instance1->IsObject());
+ CHECK(instance1->IsFunction());
+
+ value = CompileRun("new obj4(28)");
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsObject());
+
+ Local<Value> args1[] = { v8_num(28) };
+ value = instance1->CallAsConstructor(1, args1);
+ CHECK(!try_catch.HasCaught());
+ CHECK(value->IsObject());
+
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ instance_template->SetCallAsFunctionHandler(FakeConstructorCallback);
+ Local<Object> instance2 = instance_template->NewInstance();
+ context->Global()->Set(v8_str("obj5"), instance2);
+ CHECK(!try_catch.HasCaught());
+
+ CHECK(instance2->IsObject());
+ CHECK(!instance2->IsFunction());
+
+ value = CompileRun("new obj5(28)");
+ CHECK(!try_catch.HasCaught());
+ CHECK(!value->IsObject());
+
+ Local<Value> args2[] = { v8_num(28) };
+ value = instance2->CallAsConstructor(1, args2);
+ CHECK(!try_catch.HasCaught());
+ CHECK(!value->IsObject());
+ }
+}
+
+
THREADED_TEST(FunctionDescriptorException) {
v8::HandleScope handle_scope;
LocalContext context;
@@ -6739,50 +7402,153 @@ THREADED_TEST(CallAsFunction) {
v8::HandleScope scope;
LocalContext context;
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
- Local<ObjectTemplate> instance_template = t->InstanceTemplate();
- instance_template->SetCallAsFunctionHandler(call_as_function);
- Local<v8::Object> instance = t->GetFunction()->NewInstance();
- context->Global()->Set(v8_str("obj"), instance);
- v8::TryCatch try_catch;
- Local<Value> value;
- CHECK(!try_catch.HasCaught());
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
+ instance_template->SetCallAsFunctionHandler(call_as_function);
+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
+ context->Global()->Set(v8_str("obj"), instance);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
- value = CompileRun("obj(42)");
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(42, value->Int32Value());
+ value = CompileRun("obj(42)");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(42, value->Int32Value());
- value = CompileRun("(function(o){return o(49)})(obj)");
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(49, value->Int32Value());
+ value = CompileRun("(function(o){return o(49)})(obj)");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(49, value->Int32Value());
- // test special case of call as function
- value = CompileRun("[obj]['0'](45)");
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(45, value->Int32Value());
+ // test special case of call as function
+ value = CompileRun("[obj]['0'](45)");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(45, value->Int32Value());
- value = CompileRun("obj.call = Function.prototype.call;"
- "obj.call(null, 87)");
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(87, value->Int32Value());
+ value = CompileRun("obj.call = Function.prototype.call;"
+ "obj.call(null, 87)");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(87, value->Int32Value());
- // Regression tests for bug #1116356: Calling call through call/apply
- // must work for non-function receivers.
- const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])";
- value = CompileRun(apply_99);
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(99, value->Int32Value());
+ // Regression tests for bug #1116356: Calling call through call/apply
+ // must work for non-function receivers.
+ const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])";
+ value = CompileRun(apply_99);
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(99, value->Int32Value());
- const char* call_17 = "Function.prototype.call.call(obj, this, 17)";
- value = CompileRun(call_17);
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(17, value->Int32Value());
+ const char* call_17 = "Function.prototype.call.call(obj, this, 17)";
+ value = CompileRun(call_17);
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(17, value->Int32Value());
- // Check that the call-as-function handler can be called through
- // new.
- value = CompileRun("new obj(43)");
- CHECK(!try_catch.HasCaught());
- CHECK_EQ(-43, value->Int32Value());
+ // Check that the call-as-function handler can be called through
+ // new.
+ value = CompileRun("new obj(43)");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(-43, value->Int32Value());
+
+ // Check that the call-as-function handler can be called through
+ // the API.
+ v8::Handle<Value> args[] = { v8_num(28) };
+ value = instance->CallAsFunction(instance, 1, args);
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(28, value->Int32Value());
+ }
+
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
+ context->Global()->Set(v8_str("obj2"), instance);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
+
+ // Call an object without call-as-function handler through the JS
+ value = CompileRun("obj2(28)");
+ CHECK(value.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value1(try_catch.Exception());
+ CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function",
+ *exception_value1);
+ try_catch.Reset();
+
+ // Call an object without call-as-function handler through the API
+ value = CompileRun("obj2(28)");
+ v8::Handle<Value> args[] = { v8_num(28) };
+ value = instance->CallAsFunction(instance, 1, args);
+ CHECK(value.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value2(try_catch.Exception());
+ CHECK_EQ("TypeError: [object Object] is not a function", *exception_value2);
+ try_catch.Reset();
+ }
+
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
+ instance_template->SetCallAsFunctionHandler(ThrowValue);
+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
+ context->Global()->Set(v8_str("obj3"), instance);
+ v8::TryCatch try_catch;
+ Local<Value> value;
+ CHECK(!try_catch.HasCaught());
+
+ // Catch the exception which is thrown by call-as-function handler
+ value = CompileRun("obj3(22)");
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value1(try_catch.Exception());
+ CHECK_EQ("22", *exception_value1);
+ try_catch.Reset();
+
+ v8::Handle<Value> args[] = { v8_num(23) };
+ value = instance->CallAsFunction(instance, 1, args);
+ CHECK(try_catch.HasCaught());
+ String::AsciiValue exception_value2(try_catch.Exception());
+ CHECK_EQ("23", *exception_value2);
+ try_catch.Reset();
+ }
+}
+
+
+// Check whether a non-function object is callable.
+THREADED_TEST(CallableObject) {
+ v8::HandleScope scope;
+ LocalContext context;
+
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ instance_template->SetCallAsFunctionHandler(call_as_function);
+ Local<Object> instance = instance_template->NewInstance();
+ v8::TryCatch try_catch;
+
+ CHECK(instance->IsCallable());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ Local<Object> instance = instance_template->NewInstance();
+ v8::TryCatch try_catch;
+
+ CHECK(!instance->IsCallable());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ { Local<FunctionTemplate> function_template =
+ FunctionTemplate::New(call_as_function);
+ Local<Function> function = function_template->GetFunction();
+ Local<Object> instance = function;
+ v8::TryCatch try_catch;
+
+ CHECK(instance->IsCallable());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ { Local<FunctionTemplate> function_template = FunctionTemplate::New();
+ Local<Function> function = function_template->GetFunction();
+ Local<Object> instance = function;
+ v8::TryCatch try_catch;
+
+ CHECK(instance->IsCallable());
+ CHECK(!try_catch.HasCaught());
+ }
}
@@ -6863,7 +7629,7 @@ static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC(
Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
return v8::Handle<Value>();
}
@@ -7593,7 +8359,7 @@ static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
++(*call_count);
if ((*call_count) % 20 == 0) {
- i::Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
}
return v8::Handle<Value>();
}
@@ -7631,7 +8397,7 @@ static void GenerateSomeGarbage() {
v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) {
static int count = 0;
if (count++ % 3 == 0) {
- i::Heap::CollectAllGarbage(true); // This should move the stub
+ HEAP-> CollectAllGarbage(true); // This should move the stub
GenerateSomeGarbage(); // This should ensure the old stub memory is flushed
}
return v8::Handle<v8::Value>();
@@ -7686,7 +8452,7 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) {
v8::Handle<v8::Value> DirectGetterCallback(Local<String> name,
const v8::AccessorInfo& info) {
if (++p_getter_count % 3 == 0) {
- i::Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
GenerateSomeGarbage();
}
return v8::Handle<v8::Value>();
@@ -8374,6 +9140,134 @@ THREADED_TEST(NamedPropertyHandlerGetterAttributes) {
}
+static Handle<Value> ThrowingGetter(Local<String> name,
+ const AccessorInfo& info) {
+ ApiTestFuzzer::Fuzz();
+ ThrowException(Handle<Value>());
+ return Undefined();
+}
+
+
+THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
+ HandleScope scope;
+ LocalContext context;
+
+ Local<FunctionTemplate> templ = FunctionTemplate::New();
+ Local<ObjectTemplate> instance_templ = templ->InstanceTemplate();
+ instance_templ->SetAccessor(v8_str("f"), ThrowingGetter);
+
+ Local<Object> instance = templ->GetFunction()->NewInstance();
+
+ Local<Object> another = Object::New();
+ another->SetPrototype(instance);
+
+ Local<Object> with_js_getter = CompileRun(
+ "o = {};\n"
+ "o.__defineGetter__('f', function() { throw undefined; });\n"
+ "o\n").As<Object>();
+ CHECK(!with_js_getter.IsEmpty());
+
+ TryCatch try_catch;
+
+ Local<Value> result = instance->GetRealNamedProperty(v8_str("f"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(result.IsEmpty());
+
+ result = another->GetRealNamedProperty(v8_str("f"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(result.IsEmpty());
+
+ result = another->GetRealNamedPropertyInPrototypeChain(v8_str("f"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(result.IsEmpty());
+
+ result = another->Get(v8_str("f"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(result.IsEmpty());
+
+ result = with_js_getter->GetRealNamedProperty(v8_str("f"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(result.IsEmpty());
+
+ result = with_js_getter->Get(v8_str("f"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(result.IsEmpty());
+}
+
+
+static Handle<Value> ThrowingCallbackWithTryCatch(const Arguments& args) {
+ TryCatch try_catch;
+ // Verboseness is important: it triggers message delivery which can call into
+ // external code.
+ 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());
+ return Undefined();
+}
+
+
+static int call_depth;
+
+
+static void WithTryCatch(Handle<Message> message, Handle<Value> data) {
+ TryCatch try_catch;
+}
+
+
+static void ThrowFromJS(Handle<Message> message, Handle<Value> data) {
+ if (--call_depth) CompileRun("throw 'ThrowInJS';");
+}
+
+
+static void ThrowViaApi(Handle<Message> message, Handle<Value> data) {
+ if (--call_depth) ThrowException(v8_str("ThrowViaApi"));
+}
+
+
+static void WebKitLike(Handle<Message> message, Handle<Value> data) {
+ Handle<String> errorMessageString = message->Get();
+ CHECK(!errorMessageString.IsEmpty());
+ message->GetStackTrace();
+ message->GetScriptResourceName();
+}
+
+THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) {
+ HandleScope scope;
+ LocalContext context;
+
+ Local<Function> func =
+ FunctionTemplate::New(ThrowingCallbackWithTryCatch)->GetFunction();
+ context->Global()->Set(v8_str("func"), func);
+
+ MessageCallback callbacks[] =
+ { NULL, WebKitLike, ThrowViaApi, ThrowFromJS, WithTryCatch };
+ for (unsigned i = 0; i < sizeof(callbacks)/sizeof(callbacks[0]); i++) {
+ MessageCallback callback = callbacks[i];
+ if (callback != NULL) {
+ V8::AddMessageListener(callback);
+ }
+ // Some small number to control number of times message handler should
+ // throw an exception.
+ call_depth = 5;
+ ExpectFalse(
+ "var thrown = false;\n"
+ "try { func(); } catch(e) { thrown = true; }\n"
+ "thrown\n");
+ if (callback != NULL) {
+ V8::RemoveMessageListeners(callback);
+ }
+ }
+}
+
+
static v8::Handle<Value> ParentGetter(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
@@ -8595,11 +9489,10 @@ static unsigned linear_congruential_generator;
void ApiTestFuzzer::Setup(PartOfTest part) {
linear_congruential_generator = i::FLAG_testing_prng_seed;
fuzzing_ = true;
- int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1);
- int end = (part == FIRST_PART)
- ? (RegisterThreadedTest::count() >> 1)
- : RegisterThreadedTest::count();
- active_tests_ = tests_being_run_ = end - start;
+ int count = RegisterThreadedTest::count();
+ int start = count * part / (LAST_PART + 1);
+ int end = (count * (part + 1) / (LAST_PART + 1)) - 1;
+ active_tests_ = tests_being_run_ = end - start + 1;
for (int i = 0; i < tests_being_run_; i++) {
RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer(i + start);
}
@@ -8668,6 +9561,17 @@ TEST(Threading2) {
ApiTestFuzzer::TearDown();
}
+TEST(Threading3) {
+ ApiTestFuzzer::Setup(ApiTestFuzzer::THIRD_PART);
+ ApiTestFuzzer::RunAllTests();
+ ApiTestFuzzer::TearDown();
+}
+
+TEST(Threading4) {
+ ApiTestFuzzer::Setup(ApiTestFuzzer::FOURTH_PART);
+ ApiTestFuzzer::RunAllTests();
+ ApiTestFuzzer::TearDown();
+}
void ApiTestFuzzer::CallTest() {
if (kLogThreading)
@@ -8823,11 +9727,12 @@ 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.
- i::Heap::CollectAllGarbage(false);
- i::Heap::CollectAllGarbage(false);
+ HEAP->global_context_map();
+ HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
int count = GetGlobalObjectsCount();
#ifdef DEBUG
- if (count != expected) i::Heap::TracePathToGlobal();
+ if (count != expected) HEAP->TracePathToGlobal();
#endif
CHECK_EQ(expected, count);
}
@@ -8893,7 +9798,7 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) {
// weak callback of the first handle would be able to 'reallocate' it.
handle1.MakeWeak(NULL, NewPersistentHandleCallback);
handle2.Dispose();
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
}
@@ -8901,7 +9806,7 @@ v8::Persistent<v8::Object> to_be_disposed;
void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) {
to_be_disposed.Dispose();
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
handle.Dispose();
}
@@ -8917,7 +9822,7 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
}
handle1.MakeWeak(NULL, DisposeAndForceGcCallback);
to_be_disposed = handle2;
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
}
void DisposingCallback(v8::Persistent<v8::Value> handle, void*) {
@@ -8943,7 +9848,7 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
}
handle2.MakeWeak(NULL, DisposingCallback);
handle3.MakeWeak(NULL, HandleCreatingCallback);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
}
@@ -9161,6 +10066,19 @@ void CheckProperties(v8::Handle<v8::Value> val, int elmc, const char* elmv[]) {
}
+void CheckOwnProperties(v8::Handle<v8::Value> val,
+ int elmc,
+ const char* elmv[]) {
+ v8::Handle<v8::Object> obj = val.As<v8::Object>();
+ v8::Handle<v8::Array> props = obj->GetOwnPropertyNames();
+ CHECK_EQ(elmc, props->Length());
+ for (int i = 0; i < elmc; i++) {
+ v8::String::Utf8Value elm(props->Get(v8::Integer::New(i)));
+ CHECK_EQ(elmv[i], *elm);
+ }
+}
+
+
THREADED_TEST(PropertyEnumeration) {
v8::HandleScope scope;
LocalContext context;
@@ -9178,17 +10096,48 @@ THREADED_TEST(PropertyEnumeration) {
int elmc0 = 0;
const char** elmv0 = NULL;
CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
+ CheckOwnProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
int elmc1 = 2;
const char* elmv1[] = {"a", "b"};
CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
+ CheckOwnProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
int elmc2 = 3;
const char* elmv2[] = {"0", "1", "2"};
CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
+ CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
int elmc3 = 4;
const char* elmv3[] = {"w", "z", "x", "y"};
CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3);
+ int elmc4 = 2;
+ const char* elmv4[] = {"w", "z"};
+ CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4);
}
+THREADED_TEST(PropertyEnumeration2) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New(
+ "var result = [];"
+ "result[0] = {};"
+ "result[1] = {a: 1, b: 2};"
+ "result[2] = [1, 2, 3];"
+ "var proto = {x: 1, y: 2, z: 3};"
+ "var x = { __proto__: proto, w: 0, z: 1 };"
+ "result[3] = x;"
+ "result;"))->Run();
+ v8::Handle<v8::Array> elms = obj.As<v8::Array>();
+ CHECK_EQ(4, elms->Length());
+ int elmc0 = 0;
+ const char** elmv0 = NULL;
+ CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
+
+ v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(0));
+ v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames();
+ CHECK_EQ(0, props->Length());
+ for (uint32_t i = 0; i < props->Length(); i++) {
+ printf("p[%d]\n", i);
+ }
+}
static bool NamedSetAccessBlocker(Local<v8::Object> obj,
Local<Value> name,
@@ -9694,6 +10643,7 @@ class RegExpInterruptTest {
CHECK(regexp_success_);
CHECK(gc_success_);
}
+
private:
// Number of garbage collections required.
static const int kRequiredGCs = 5;
@@ -9701,7 +10651,7 @@ class RegExpInterruptTest {
class GCThread : public i::Thread {
public:
explicit GCThread(RegExpInterruptTest* test)
- : test_(test) {}
+ : Thread("GCThread"), test_(test) {}
virtual void Run() {
test_->CollectGarbage();
}
@@ -9715,7 +10665,7 @@ class RegExpInterruptTest {
{
v8::Locker lock;
// TODO(lrn): Perhaps create some garbage before collecting.
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
gc_count_++;
}
i::OS::Sleep(1);
@@ -9816,6 +10766,7 @@ class ApplyInterruptTest {
CHECK(apply_success_);
CHECK(gc_success_);
}
+
private:
// Number of garbage collections required.
static const int kRequiredGCs = 2;
@@ -9823,7 +10774,7 @@ class ApplyInterruptTest {
class GCThread : public i::Thread {
public:
explicit GCThread(ApplyInterruptTest* test)
- : test_(test) {}
+ : Thread("GCThread"), test_(test) {}
virtual void Run() {
test_->CollectGarbage();
}
@@ -9836,7 +10787,7 @@ class ApplyInterruptTest {
while (gc_during_apply_ < kRequiredGCs) {
{
v8::Locker lock;
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
gc_count_++;
}
i::OS::Sleep(1);
@@ -9965,17 +10916,17 @@ static void MorphAString(i::String* string,
CHECK(i::StringShape(string).IsExternal());
if (string->IsAsciiRepresentation()) {
// Check old map is not symbol or long.
- CHECK(string->map() == i::Heap::external_ascii_string_map());
+ CHECK(string->map() == HEAP->external_ascii_string_map());
// Morph external string to be TwoByte string.
- string->set_map(i::Heap::external_string_map());
+ string->set_map(HEAP->external_string_map());
i::ExternalTwoByteString* morphed =
i::ExternalTwoByteString::cast(string);
morphed->set_resource(uc16_resource);
} else {
// Check old map is not symbol or long.
- CHECK(string->map() == i::Heap::external_string_map());
+ CHECK(string->map() == HEAP->external_string_map());
// Morph external string to be ASCII string.
- string->set_map(i::Heap::external_ascii_string_map());
+ string->set_map(HEAP->external_ascii_string_map());
i::ExternalAsciiString* morphed =
i::ExternalAsciiString::cast(string);
morphed->set_resource(ascii_resource);
@@ -9999,9 +10950,9 @@ THREADED_TEST(MorphCompositeStringTest) {
i::StrLength(c_string)));
Local<String> lhs(v8::Utils::ToLocal(
- i::Factory::NewExternalStringFromAscii(&ascii_resource)));
+ FACTORY->NewExternalStringFromAscii(&ascii_resource)));
Local<String> rhs(v8::Utils::ToLocal(
- i::Factory::NewExternalStringFromAscii(&ascii_resource)));
+ FACTORY->NewExternalStringFromAscii(&ascii_resource)));
env->Global()->Set(v8_str("lhs"), lhs);
env->Global()->Set(v8_str("rhs"), rhs);
@@ -10086,12 +11037,12 @@ class RegExpStringModificationTest {
// Create the input string for the regexp - the one we are going to change
// properties of.
- input_ = i::Factory::NewExternalStringFromAscii(&ascii_resource_);
+ input_ = FACTORY->NewExternalStringFromAscii(&ascii_resource_);
// Inject the input as a global variable.
i::Handle<i::String> input_name =
- i::Factory::NewStringFromAscii(i::Vector<const char>("input", 5));
- i::Top::global_context()->global()->SetProperty(
+ FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5));
+ i::Isolate::Current()->global_context()->global()->SetProperty(
*input_name,
*input_,
NONE,
@@ -10109,8 +11060,8 @@ class RegExpStringModificationTest {
CHECK(regexp_success_);
CHECK(morph_success_);
}
- private:
+ private:
// Number of string modifications required.
static const int kRequiredModifications = 5;
static const int kMaxModifications = 100;
@@ -10118,7 +11069,7 @@ class RegExpStringModificationTest {
class MorphThread : public i::Thread {
public:
explicit MorphThread(RegExpStringModificationTest* test)
- : test_(test) {}
+ : Thread("MorphThread"), test_(test) {}
virtual void Run() {
test_->MorphString();
}
@@ -10549,13 +11500,16 @@ THREADED_TEST(PixelArray) {
LocalContext context;
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
- i::Handle<i::PixelArray> pixels = i::Factory::NewPixelArray(kElementCount,
- pixel_data);
- i::Heap::CollectAllGarbage(false); // Force GC to trigger verification.
+ i::Handle<i::ExternalPixelArray> pixels =
+ i::Handle<i::ExternalPixelArray>::cast(
+ FACTORY->NewExternalArray(kElementCount,
+ v8::kExternalPixelArray,
+ pixel_data));
+ HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
for (int i = 0; i < kElementCount; i++) {
pixels->set(i, i % 256);
}
- i::Heap::CollectAllGarbage(false); // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
for (int i = 0; i < kElementCount; i++) {
CHECK_EQ(i % 256, pixels->get(i));
CHECK_EQ(i % 256, pixel_data[i]);
@@ -10617,14 +11571,14 @@ THREADED_TEST(PixelArray) {
CHECK_EQ(28, result->Int32Value());
i::Handle<i::Smi> value(i::Smi::FromInt(2));
- i::SetElement(jsobj, 1, value);
+ i::SetElement(jsobj, 1, value, i::kNonStrictMode);
CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
*value.location() = i::Smi::FromInt(256);
- i::SetElement(jsobj, 1, value);
+ i::SetElement(jsobj, 1, value, i::kNonStrictMode);
CHECK_EQ(255,
i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
*value.location() = i::Smi::FromInt(-1);
- i::SetElement(jsobj, 1, value);
+ i::SetElement(jsobj, 1, value, i::kNonStrictMode);
CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
result = CompileRun("for (var i = 0; i < 8; i++) {"
@@ -10890,7 +11844,7 @@ THREADED_TEST(PixelArray) {
" return sum; "
"}"
"for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
- "for (var i = 0; i < 10000; ++i) {"
+ "for (var i = 0; i < 5000; ++i) {"
" result = pa_load(pixels);"
"}"
"result");
@@ -10907,7 +11861,7 @@ THREADED_TEST(PixelArray) {
" }"
" return sum; "
"}"
- "for (var i = 0; i < 100000; ++i) {"
+ "for (var i = 0; i < 5000; ++i) {"
" pa_init(pixels);"
"}"
"result = pa_load(pixels);"
@@ -10955,8 +11909,11 @@ THREADED_TEST(PixelArrayWithInterceptor) {
LocalContext context;
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
- i::Handle<i::PixelArray> pixels =
- i::Factory::NewPixelArray(kElementCount, pixel_data);
+ i::Handle<i::ExternalPixelArray> pixels =
+ i::Handle<i::ExternalPixelArray>::cast(
+ FACTORY->NewExternalArray(kElementCount,
+ v8::kExternalPixelArray,
+ pixel_data));
for (int i = 0; i < kElementCount; i++) {
pixels->set(i, i % 256);
}
@@ -10984,6 +11941,7 @@ static int ExternalArrayElementSize(v8::ExternalArrayType array_type) {
switch (array_type) {
case v8::kExternalByteArray:
case v8::kExternalUnsignedByteArray:
+ case v8::kExternalPixelArray:
return 1;
break;
case v8::kExternalShortArray:
@@ -10995,6 +11953,9 @@ static int ExternalArrayElementSize(v8::ExternalArrayType array_type) {
case v8::kExternalFloatArray:
return 4;
break;
+ case v8::kExternalDoubleArray:
+ return 8;
+ break;
default:
UNREACHABLE();
return -1;
@@ -11016,12 +11977,12 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
static_cast<ElementType*>(malloc(kElementCount * element_size));
i::Handle<ExternalArrayClass> array =
i::Handle<ExternalArrayClass>::cast(
- i::Factory::NewExternalArray(kElementCount, array_type, array_data));
- i::Heap::CollectAllGarbage(false); // Force GC to trigger verification.
+ FACTORY->NewExternalArray(kElementCount, array_type, array_data));
+ HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
for (int i = 0; i < kElementCount; i++) {
array->set(i, static_cast<ElementType>(i));
}
- i::Heap::CollectAllGarbage(false); // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
for (int i = 0; i < kElementCount; i++) {
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i)));
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i]));
@@ -11138,7 +12099,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
" }"
"}"
"sum;");
- i::Heap::CollectAllGarbage(false); // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
CHECK_EQ(28, result->Int32Value());
// Make sure out-of-range loads do not throw.
@@ -11184,7 +12145,8 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
CHECK_EQ(
2, static_cast<int>(jsobj->GetElement(6)->ToObjectChecked()->Number()));
- if (array_type != v8::kExternalFloatArray) {
+ if (array_type != v8::kExternalFloatArray &&
+ array_type != v8::kExternalDoubleArray) {
// Though the specification doesn't state it, be explicit about
// converting NaNs and +/-Infinity to zero.
result = CompileRun("for (var i = 0; i < 8; i++) {"
@@ -11205,8 +12167,10 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
" ext_array[i] = Infinity;"
"}"
"ext_array[5];");
- CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(0,
+ int expected_value =
+ (array_type == v8::kExternalPixelArray) ? 255 : 0;
+ CHECK_EQ(expected_value, result->Int32Value());
+ CHECK_EQ(expected_value,
i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
result = CompileRun("for (var i = 0; i < 8; i++) {"
@@ -11227,10 +12191,14 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
const char* signed_data =
"var source_data = [0.6, 10.6, -0.6, -10.6];"
"var expected_results = [0, 10, 0, -10];";
+ const char* pixel_data =
+ "var source_data = [0.6, 10.6];"
+ "var expected_results = [1, 11];";
bool is_unsigned =
(array_type == v8::kExternalUnsignedByteArray ||
array_type == v8::kExternalUnsignedShortArray ||
array_type == v8::kExternalUnsignedIntArray);
+ bool is_pixel_data = array_type == v8::kExternalPixelArray;
i::OS::SNPrintF(test_buf,
"%s"
@@ -11243,11 +12211,46 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
" (ext_array[5] == expected_results[i]);"
"}"
"all_passed;",
- (is_unsigned ? unsigned_data : signed_data));
+ (is_unsigned ?
+ unsigned_data :
+ (is_pixel_data ? pixel_data : signed_data)));
result = CompileRun(test_buf.start());
CHECK_EQ(true, result->BooleanValue());
}
+ for (int i = 0; i < kElementCount; i++) {
+ array->set(i, static_cast<ElementType>(i));
+ }
+ // Test complex assignments
+ result = CompileRun("function ee_op_test_complex_func(sum) {"
+ " for (var i = 0; i < 40; ++i) {"
+ " sum += (ext_array[i] += 1);"
+ " sum += (ext_array[i] -= 1);"
+ " } "
+ " return sum;"
+ "}"
+ "sum=0;"
+ "for (var i=0;i<10000;++i) {"
+ " sum=ee_op_test_complex_func(sum);"
+ "}"
+ "sum;");
+ CHECK_EQ(16000000, result->Int32Value());
+
+ // Test count operations
+ result = CompileRun("function ee_op_test_count_func(sum) {"
+ " for (var i = 0; i < 40; ++i) {"
+ " sum += (++ext_array[i]);"
+ " sum += (--ext_array[i]);"
+ " } "
+ " return sum;"
+ "}"
+ "sum=0;"
+ "for (var i=0;i<10000;++i) {"
+ " sum=ee_op_test_count_func(sum);"
+ "}"
+ "sum;");
+ CHECK_EQ(16000000, result->Int32Value());
+
result = CompileRun("ext_array[3] = 33;"
"delete ext_array[3];"
"ext_array[3];");
@@ -11287,7 +12290,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
static_cast<ElementType*>(malloc(kLargeElementCount * element_size));
i::Handle<ExternalArrayClass> large_array =
i::Handle<ExternalArrayClass>::cast(
- i::Factory::NewExternalArray(kLargeElementCount,
+ FACTORY->NewExternalArray(kLargeElementCount,
array_type,
array_data));
v8::Handle<v8::Object> large_obj = v8::Object::New();
@@ -11354,6 +12357,95 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
free(large_array_data);
}
+ // The "" property descriptor is overloaded to store information about
+ // the external array. Ensure that setting and accessing the "" property
+ // works (it should overwrite the information cached about the external
+ // array in the DescriptorArray) in various situations.
+ result = CompileRun("ext_array[''] = 23; ext_array['']");
+ CHECK_EQ(23, result->Int32Value());
+
+ // Property "" set after the external array is associated with the object.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field"), v8::Int32::New(256));
+ obj2->Set(v8_str(""), v8::Int32::New(1503));
+ // Set the elements to be the external array.
+ obj2->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array['']");
+ CHECK_EQ(1503, result->Int32Value());
+ }
+
+ // Property "" set after the external array is associated with the object.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256));
+ // Set the elements to be the external array.
+ obj2->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ obj2->Set(v8_str(""), v8::Int32::New(1503));
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array['']");
+ CHECK_EQ(1503, result->Int32Value());
+ }
+
+ // Should reuse the map from previous test.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256));
+ // Set the elements to be the external array. Should re-use the map
+ // from previous test.
+ obj2->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array['']");
+ }
+
+ // Property "" is a constant function that shouldn't not be interfered with
+ // when an external array is set.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ // Start
+ obj2->Set(v8_str("ee_test_field3"), v8::Int32::New(256));
+
+ // Add a constant function to an object.
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array[''] = function() {return 1503;};"
+ "ext_array['']();");
+
+ // Add an external array transition to the same map that
+ // has the constant transition.
+ v8::Handle<v8::Object> obj3 = v8::Object::New();
+ obj3->Set(v8_str("ee_test_field3"), v8::Int32::New(256));
+ obj3->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ context->Global()->Set(v8_str("ext_array"), obj3);
+ }
+
+ // If a external array transition is in the map, it should get clobbered
+ // by a constant function.
+ {
+ // Add an external array transition.
+ v8::Handle<v8::Object> obj3 = v8::Object::New();
+ obj3->Set(v8_str("ee_test_field4"), v8::Int32::New(256));
+ obj3->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+
+ // Add a constant function to the same map that just got an external array
+ // transition.
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field4"), v8::Int32::New(256));
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array[''] = function() {return 1503;};"
+ "ext_array['']();");
+ }
+
free(array_data);
}
@@ -11374,6 +12466,14 @@ THREADED_TEST(ExternalUnsignedByteArray) {
}
+THREADED_TEST(ExternalPixelArray) {
+ ExternalArrayTestHelper<i::ExternalPixelArray, uint8_t>(
+ v8::kExternalPixelArray,
+ 0,
+ 255);
+}
+
+
THREADED_TEST(ExternalShortArray) {
ExternalArrayTestHelper<i::ExternalShortArray, int16_t>(
v8::kExternalShortArray,
@@ -11414,6 +12514,14 @@ THREADED_TEST(ExternalFloatArray) {
}
+THREADED_TEST(ExternalDoubleArray) {
+ ExternalArrayTestHelper<i::ExternalDoubleArray, double>(
+ v8::kExternalDoubleArray,
+ -500,
+ 500);
+}
+
+
THREADED_TEST(ExternalArrays) {
TestExternalByteArray();
TestExternalUnsignedByteArray();
@@ -11451,6 +12559,8 @@ THREADED_TEST(ExternalArrayInfo) {
ExternalArrayInfoTestHelper(v8::kExternalIntArray);
ExternalArrayInfoTestHelper(v8::kExternalUnsignedIntArray);
ExternalArrayInfoTestHelper(v8::kExternalFloatArray);
+ ExternalArrayInfoTestHelper(v8::kExternalDoubleArray);
+ ExternalArrayInfoTestHelper(v8::kExternalPixelArray);
}
@@ -11714,7 +12824,8 @@ THREADED_TEST(IdleNotification) {
static uint32_t* stack_limit;
static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) {
- stack_limit = reinterpret_cast<uint32_t*>(i::StackGuard::real_climit());
+ stack_limit = reinterpret_cast<uint32_t*>(
+ i::Isolate::Current()->stack_guard()->real_climit());
return v8::Undefined();
}
@@ -11799,28 +12910,14 @@ THREADED_TEST(GetHeapStatistics) {
static double DoubleFromBits(uint64_t value) {
double target;
-#ifdef BIG_ENDIAN_FLOATING_POINT
- const int kIntSize = 4;
- // Somebody swapped the lower and higher half of doubles.
- memcpy(&target, reinterpret_cast<char*>(&value) + kIntSize, kIntSize);
- memcpy(reinterpret_cast<char*>(&target) + kIntSize, &value, kIntSize);
-#else
memcpy(&target, &value, sizeof(target));
-#endif
return target;
}
static uint64_t DoubleToBits(double value) {
uint64_t target;
-#ifdef BIG_ENDIAN_FLOATING_POINT
- const int kIntSize = 4;
- // Somebody swapped the lower and higher half of doubles.
- memcpy(&target, reinterpret_cast<char*>(&value) + kIntSize, kIntSize);
- memcpy(reinterpret_cast<char*>(&target) + kIntSize, &value, kIntSize);
-#else
memcpy(&target, &value, sizeof(target));
-#endif
return target;
}
@@ -11980,7 +13077,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_simple);
other_context->Exit();
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -12002,7 +13099,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_eval);
other_context->Exit();
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -12029,7 +13126,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_exception);
other_context->Exit();
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -12247,26 +13344,26 @@ TEST(GCCallbacks) {
v8::V8::AddGCEpilogueCallback(EpilogueCallback);
CHECK_EQ(0, prologue_call_count);
CHECK_EQ(0, epilogue_call_count);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(1, prologue_call_count);
CHECK_EQ(1, epilogue_call_count);
v8::V8::AddGCPrologueCallback(PrologueCallbackSecond);
v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
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);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
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);
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
@@ -12294,7 +13391,7 @@ THREADED_TEST(AddToJSFunctionResultCache) {
" return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;"
" return 'PASSED';"
"})()";
- i::Heap::ClearJSFunctionResultCaches();
+ HEAP->ClearJSFunctionResultCaches();
ExpectString(code, "PASSED");
}
@@ -12318,7 +13415,7 @@ THREADED_TEST(FillJSFunctionResultCache) {
" return 'FAILED: k0CacheSize is too small';"
" return 'PASSED';"
"})()";
- i::Heap::ClearJSFunctionResultCaches();
+ HEAP->ClearJSFunctionResultCaches();
ExpectString(code, "PASSED");
}
@@ -12343,7 +13440,7 @@ THREADED_TEST(RoundRobinGetFromCache) {
" };"
" return 'PASSED';"
"})()";
- i::Heap::ClearJSFunctionResultCaches();
+ HEAP->ClearJSFunctionResultCaches();
ExpectString(code, "PASSED");
}
@@ -12368,7 +13465,7 @@ THREADED_TEST(ReverseGetFromCache) {
" };"
" return 'PASSED';"
"})()";
- i::Heap::ClearJSFunctionResultCaches();
+ HEAP->ClearJSFunctionResultCaches();
ExpectString(code, "PASSED");
}
@@ -12386,7 +13483,7 @@ THREADED_TEST(TestEviction) {
" };"
" return 'PASSED';"
"})()";
- i::Heap::ClearJSFunctionResultCaches();
+ HEAP->ClearJSFunctionResultCaches();
ExpectString(code, "PASSED");
}
@@ -12476,7 +13573,7 @@ THREADED_TEST(TwoByteStringInAsciiCons) {
void FailedAccessCheckCallbackGC(Local<v8::Object> target,
v8::AccessType type,
Local<v8::Value> data) {
- i::Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
}
@@ -12557,6 +13654,396 @@ TEST(GCInFailedAccessCheckCallback) {
v8::V8::SetFailedAccessCheckCallbackFunction(NULL);
}
+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* 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::HandleScope scope;
+ LocalContext context;
+ v8::Isolate* current_isolate = v8::Isolate::GetCurrent();
+ CHECK(current_isolate != NULL); // Default isolate.
+ 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;
+ 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;
+ 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;
+ 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()");
+
+ 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) {
+ v8::Isolate* isolate = v8::Isolate::New();
+ CHECK(isolate);
+ isolate->Enter();
+ v8::HandleScope scope;
+ LocalContext context;
+ // Run something in this isolate.
+ ExpectTrue("true");
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback);
+ last_location = last_message = NULL;
+ // Still entered, should fail.
+ isolate->Dispose();
+ CHECK_NE(last_location, NULL);
+ CHECK_NE(last_message, NULL);
+}
+
+TEST(RunTwoIsolatesOnSingleThread) {
+ // Run isolate 1.
+ v8::Isolate* isolate1 = v8::Isolate::New();
+ isolate1->Enter();
+ v8::Persistent<v8::Context> context1 = v8::Context::New();
+
+ {
+ v8::Context::Scope cscope(context1);
+ v8::HandleScope scope;
+ // Run something in new isolate.
+ CompileRun("var foo = 'isolate 1';");
+ ExpectString("function f() { return foo; }; f()", "isolate 1");
+ }
+
+ // Run isolate 2.
+ v8::Isolate* isolate2 = v8::Isolate::New();
+ v8::Persistent<v8::Context> context2;
+
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ context2 = v8::Context::New();
+ v8::Context::Scope cscope(context2);
+ v8::HandleScope scope;
+
+ // Run something in new isolate.
+ CompileRun("var foo = 'isolate 2';");
+ ExpectString("function f() { return foo; }; f()", "isolate 2");
+ }
+
+ {
+ v8::Context::Scope cscope(context1);
+ v8::HandleScope scope;
+ // Now again in isolate 1
+ ExpectString("function f() { return foo; }; f()", "isolate 1");
+ }
+
+ isolate1->Exit();
+
+ // Run some stuff in default isolate.
+ v8::Persistent<v8::Context> context_default = v8::Context::New();
+
+ {
+ v8::Context::Scope cscope(context_default);
+ v8::HandleScope scope;
+ // Variables in other isolates should be not available, verify there
+ // is an exception.
+ ExpectTrue("function f() {"
+ " try {"
+ " foo;"
+ " return false;"
+ " } catch(e) {"
+ " return true;"
+ " }"
+ "};"
+ "var isDefaultIsolate = true;"
+ "f()");
+ }
+
+ isolate1->Enter();
+
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ v8::Context::Scope cscope(context2);
+ v8::HandleScope scope;
+ ExpectString("function f() { return foo; }; f()", "isolate 2");
+ }
+
+ {
+ v8::Context::Scope cscope(context1);
+ v8::HandleScope scope;
+ ExpectString("function f() { return foo; }; f()", "isolate 1");
+ }
+
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ context2.Dispose();
+ }
+
+ context1.Dispose();
+ isolate1->Exit();
+
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback);
+ last_location = last_message = NULL;
+
+ isolate1->Dispose();
+ CHECK_EQ(last_location, NULL);
+ CHECK_EQ(last_message, NULL);
+
+ isolate2->Dispose();
+ CHECK_EQ(last_location, NULL);
+ CHECK_EQ(last_message, NULL);
+
+ // Check that default isolate still runs.
+ {
+ v8::Context::Scope cscope(context_default);
+ v8::HandleScope scope;
+ ExpectTrue("function f() { return isDefaultIsolate; }; f()");
+ }
+}
+
+static int CalcFibonacci(v8::Isolate* isolate, int limit) {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope scope;
+ LocalContext context;
+ i::ScopedVector<char> code(1024);
+ i::OS::SNPrintF(code, "function fib(n) {"
+ " if (n <= 2) return 1;"
+ " return fib(n-1) + fib(n-2);"
+ "}"
+ "fib(%d)", limit);
+ Local<Value> value = CompileRun(code.start());
+ CHECK(value->IsNumber());
+ return static_cast<int>(value->NumberValue());
+}
+
+class IsolateThread : public v8::internal::Thread {
+ public:
+ IsolateThread(v8::Isolate* isolate, int fib_limit)
+ : Thread("IsolateThread"),
+ isolate_(isolate),
+ fib_limit_(fib_limit),
+ result_(0) { }
+
+ void Run() {
+ result_ = CalcFibonacci(isolate_, fib_limit_);
+ }
+
+ int result() { return result_; }
+
+ private:
+ v8::Isolate* isolate_;
+ int fib_limit_;
+ int result_;
+};
+
+TEST(MultipleIsolatesOnIndividualThreads) {
+ v8::Isolate* isolate1 = v8::Isolate::New();
+ v8::Isolate* isolate2 = v8::Isolate::New();
+
+ IsolateThread thread1(isolate1, 21);
+ IsolateThread thread2(isolate2, 12);
+
+ // Compute some fibonacci numbers on 3 threads in 3 isolates.
+ thread1.Start();
+ thread2.Start();
+
+ int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21);
+ int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12);
+
+ thread1.Join();
+ thread2.Join();
+
+ // Compare results. The actual fibonacci numbers for 12 and 21 are taken
+ // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number
+ CHECK_EQ(result1, 10946);
+ CHECK_EQ(result2, 144);
+ CHECK_EQ(result1, thread1.result());
+ CHECK_EQ(result2, thread2.result());
+
+ isolate1->Dispose();
+ isolate2->Dispose();
+}
+
+TEST(IsolateDifferentContexts) {
+ v8::Isolate* isolate = v8::Isolate::New();
+ Persistent<v8::Context> context;
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope;
+ context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+ Local<Value> v = CompileRun("2");
+ CHECK(v->IsNumber());
+ CHECK_EQ(2, static_cast<int>(v->NumberValue()));
+ }
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope;
+ context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+ Local<Value> v = CompileRun("22");
+ CHECK(v->IsNumber());
+ CHECK_EQ(22, static_cast<int>(v->NumberValue()));
+ }
+}
+
+class InitDefaultIsolateThread : public v8::internal::Thread {
+ public:
+ enum TestCase {
+ IgnoreOOM,
+ SetResourceConstraints,
+ SetFatalHandler,
+ SetCounterFunction,
+ SetCreateHistogramFunction,
+ SetAddHistogramSampleFunction
+ };
+
+ explicit InitDefaultIsolateThread(TestCase testCase)
+ : Thread("InitDefaultIsolateThread"),
+ testCase_(testCase),
+ result_(false) { }
+
+ void Run() {
+ switch (testCase_) {
+ case IgnoreOOM:
+ v8::V8::IgnoreOutOfMemoryException();
+ break;
+
+ case SetResourceConstraints: {
+ static const int K = 1024;
+ v8::ResourceConstraints constraints;
+ constraints.set_max_young_space_size(256 * K);
+ constraints.set_max_old_space_size(4 * K * K);
+ v8::SetResourceConstraints(&constraints);
+ break;
+ }
+
+ case SetFatalHandler:
+ v8::V8::SetFatalErrorHandler(NULL);
+ break;
+
+ case SetCounterFunction:
+ v8::V8::SetCounterFunction(NULL);
+ break;
+
+ case SetCreateHistogramFunction:
+ v8::V8::SetCreateHistogramFunction(NULL);
+ break;
+
+ case SetAddHistogramSampleFunction:
+ v8::V8::SetAddHistogramSampleFunction(NULL);
+ break;
+ }
+ result_ = true;
+ }
+
+ bool result() { return result_; }
+
+ private:
+ TestCase testCase_;
+ bool result_;
+};
+
+
+static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) {
+ InitDefaultIsolateThread thread(testCase);
+ thread.Start();
+ thread.Join();
+ CHECK_EQ(thread.result(), true);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread1) {
+ InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread2) {
+ InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread3) {
+ InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread4) {
+ InitializeTestHelper(InitDefaultIsolateThread::SetCounterFunction);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread5) {
+ InitializeTestHelper(InitDefaultIsolateThread::SetCreateHistogramFunction);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread6) {
+ InitializeTestHelper(InitDefaultIsolateThread::SetAddHistogramSampleFunction);
+}
+
TEST(StringCheckMultipleContexts) {
const char* code =
@@ -12660,7 +14147,7 @@ TEST(DontDeleteCellLoadIC) {
"})()",
"ReferenceError: cell is not defined");
CompileRun("cell = \"new_second\";");
- i::Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
ExpectString("readCell()", "new_second");
ExpectString("readCell()", "new_second");
}
@@ -12723,48 +14210,6 @@ TEST(DontDeleteCellLoadICAPI) {
}
-TEST(GlobalLoadICGC) {
- const char* function_code =
- "function readCell() { while (true) { return cell; } }";
-
- // Check inline load code for a don't delete cell is cleared during
- // GC.
- {
- v8::HandleScope scope;
- LocalContext context;
- CompileRun("var cell = \"value\";");
- ExpectBoolean("delete cell", false);
- CompileRun(function_code);
- ExpectString("readCell()", "value");
- ExpectString("readCell()", "value");
- }
- {
- v8::HandleScope scope;
- LocalContext context2;
- // Hold the code object in the second context.
- CompileRun(function_code);
- CheckSurvivingGlobalObjectsCount(1);
- }
-
- // Check inline load code for a deletable cell is cleared during GC.
- {
- v8::HandleScope scope;
- LocalContext context;
- CompileRun("cell = \"value\";");
- CompileRun(function_code);
- ExpectString("readCell()", "value");
- ExpectString("readCell()", "value");
- }
- {
- v8::HandleScope scope;
- LocalContext context2;
- // Hold the code object in the second context.
- CompileRun(function_code);
- CheckSurvivingGlobalObjectsCount(1);
- }
-}
-
-
TEST(RegExp) {
v8::HandleScope scope;
LocalContext context;
@@ -12821,6 +14266,11 @@ TEST(RegExp) {
context->Global()->Set(v8_str("re"), re);
ExpectTrue("re.test('FoobarbaZ')");
+ // RegExps are objects on which you can set properties.
+ re->Set(v8_str("property"), v8::Integer::New(32));
+ v8::Handle<v8::Value> value = CompileRun("re.property");
+ ASSERT_EQ(32, value->Int32Value());
+
v8::TryCatch try_catch;
re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
CHECK(re.IsEmpty());
@@ -12891,3 +14341,321 @@ TEST(DefinePropertyPostDetach) {
context->DetachGlobal();
define_property->Call(proxy, 0, NULL);
}
+
+
+static void InstallContextId(v8::Handle<Context> context, int id) {
+ Context::Scope scope(context);
+ CompileRun("Object.prototype").As<Object>()->
+ Set(v8_str("context_id"), v8::Integer::New(id));
+}
+
+
+static void CheckContextId(v8::Handle<Object> object, int expected) {
+ CHECK_EQ(expected, object->Get(v8_str("context_id"))->Int32Value());
+}
+
+
+THREADED_TEST(CreationContext) {
+ HandleScope handle_scope;
+ Persistent<Context> context1 = Context::New();
+ InstallContextId(context1, 1);
+ Persistent<Context> context2 = Context::New();
+ InstallContextId(context2, 2);
+ Persistent<Context> context3 = Context::New();
+ InstallContextId(context3, 3);
+
+ Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New();
+
+ Local<Object> object1;
+ Local<Function> func1;
+ {
+ Context::Scope scope(context1);
+ object1 = Object::New();
+ func1 = tmpl->GetFunction();
+ }
+
+ Local<Object> object2;
+ Local<Function> func2;
+ {
+ Context::Scope scope(context2);
+ object2 = Object::New();
+ func2 = tmpl->GetFunction();
+ }
+
+ Local<Object> instance1;
+ Local<Object> instance2;
+
+ {
+ Context::Scope scope(context3);
+ instance1 = func1->NewInstance();
+ instance2 = func2->NewInstance();
+ }
+
+ CHECK(object1->CreationContext() == context1);
+ CheckContextId(object1, 1);
+ CHECK(func1->CreationContext() == context1);
+ CheckContextId(func1, 1);
+ CHECK(instance1->CreationContext() == context1);
+ CheckContextId(instance1, 1);
+ CHECK(object2->CreationContext() == context2);
+ CheckContextId(object2, 2);
+ CHECK(func2->CreationContext() == context2);
+ CheckContextId(func2, 2);
+ CHECK(instance2->CreationContext() == context2);
+ CheckContextId(instance2, 2);
+
+ {
+ Context::Scope scope(context1);
+ CHECK(object1->CreationContext() == context1);
+ CheckContextId(object1, 1);
+ CHECK(func1->CreationContext() == context1);
+ CheckContextId(func1, 1);
+ CHECK(instance1->CreationContext() == context1);
+ CheckContextId(instance1, 1);
+ CHECK(object2->CreationContext() == context2);
+ CheckContextId(object2, 2);
+ CHECK(func2->CreationContext() == context2);
+ CheckContextId(func2, 2);
+ CHECK(instance2->CreationContext() == context2);
+ CheckContextId(instance2, 2);
+ }
+
+ {
+ Context::Scope scope(context2);
+ CHECK(object1->CreationContext() == context1);
+ CheckContextId(object1, 1);
+ CHECK(func1->CreationContext() == context1);
+ CheckContextId(func1, 1);
+ CHECK(instance1->CreationContext() == context1);
+ CheckContextId(instance1, 1);
+ CHECK(object2->CreationContext() == context2);
+ CheckContextId(object2, 2);
+ CHECK(func2->CreationContext() == context2);
+ CheckContextId(func2, 2);
+ CHECK(instance2->CreationContext() == context2);
+ CheckContextId(instance2, 2);
+ }
+
+ context1.Dispose();
+ context2.Dispose();
+ context3.Dispose();
+}
+
+
+Handle<Value> HasOwnPropertyIndexedPropertyGetter(uint32_t index,
+ const AccessorInfo& info) {
+ if (index == 42) return v8_str("yes");
+ return Handle<v8::Integer>();
+}
+
+
+Handle<Value> HasOwnPropertyNamedPropertyGetter(Local<String> property,
+ const AccessorInfo& info) {
+ if (property->Equals(v8_str("foo"))) return v8_str("yes");
+ return Handle<Value>();
+}
+
+
+Handle<v8::Integer> HasOwnPropertyIndexedPropertyQuery(
+ uint32_t index, const AccessorInfo& info) {
+ if (index == 42) return v8_num(1).As<v8::Integer>();
+ return Handle<v8::Integer>();
+}
+
+
+Handle<v8::Integer> HasOwnPropertyNamedPropertyQuery(
+ Local<String> property, const AccessorInfo& info) {
+ if (property->Equals(v8_str("foo"))) return v8_num(1).As<v8::Integer>();
+ return Handle<v8::Integer>();
+}
+
+
+Handle<v8::Integer> HasOwnPropertyNamedPropertyQuery2(
+ Local<String> property, const AccessorInfo& info) {
+ if (property->Equals(v8_str("bar"))) return v8_num(1).As<v8::Integer>();
+ return Handle<v8::Integer>();
+}
+
+
+Handle<Value> HasOwnPropertyAccessorGetter(Local<String> property,
+ const AccessorInfo& info) {
+ return v8_str("yes");
+}
+
+
+TEST(HasOwnProperty) {
+ v8::HandleScope scope;
+ LocalContext env;
+ { // Check normal properties and defined getters.
+ Handle<Value> value = CompileRun(
+ "function Foo() {"
+ " this.foo = 11;"
+ " this.__defineGetter__('baz', function() { return 1; });"
+ "};"
+ "function Bar() { "
+ " this.bar = 13;"
+ " this.__defineGetter__('bla', function() { return 2; });"
+ "};"
+ "Bar.prototype = new Foo();"
+ "new Bar();");
+ CHECK(value->IsObject());
+ Handle<Object> object = value->ToObject();
+ CHECK(object->Has(v8_str("foo")));
+ CHECK(!object->HasOwnProperty(v8_str("foo")));
+ CHECK(object->HasOwnProperty(v8_str("bar")));
+ CHECK(object->Has(v8_str("baz")));
+ CHECK(!object->HasOwnProperty(v8_str("baz")));
+ CHECK(object->HasOwnProperty(v8_str("bla")));
+ }
+ { // Check named getter interceptors.
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter);
+ Handle<Object> instance = templ->NewInstance();
+ CHECK(!instance->HasOwnProperty(v8_str("42")));
+ CHECK(instance->HasOwnProperty(v8_str("foo")));
+ CHECK(!instance->HasOwnProperty(v8_str("bar")));
+ }
+ { // Check indexed getter interceptors.
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetIndexedPropertyHandler(HasOwnPropertyIndexedPropertyGetter);
+ Handle<Object> instance = templ->NewInstance();
+ CHECK(instance->HasOwnProperty(v8_str("42")));
+ CHECK(!instance->HasOwnProperty(v8_str("43")));
+ CHECK(!instance->HasOwnProperty(v8_str("foo")));
+ }
+ { // Check named query interceptors.
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetNamedPropertyHandler(0, 0, HasOwnPropertyNamedPropertyQuery);
+ Handle<Object> instance = templ->NewInstance();
+ CHECK(instance->HasOwnProperty(v8_str("foo")));
+ CHECK(!instance->HasOwnProperty(v8_str("bar")));
+ }
+ { // Check indexed query interceptors.
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetIndexedPropertyHandler(0, 0, HasOwnPropertyIndexedPropertyQuery);
+ Handle<Object> instance = templ->NewInstance();
+ CHECK(instance->HasOwnProperty(v8_str("42")));
+ CHECK(!instance->HasOwnProperty(v8_str("41")));
+ }
+ { // Check callbacks.
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetAccessor(v8_str("foo"), HasOwnPropertyAccessorGetter);
+ Handle<Object> instance = templ->NewInstance();
+ CHECK(instance->HasOwnProperty(v8_str("foo")));
+ CHECK(!instance->HasOwnProperty(v8_str("bar")));
+ }
+ { // Check that query wins on disagreement.
+ Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter,
+ 0,
+ HasOwnPropertyNamedPropertyQuery2);
+ Handle<Object> instance = templ->NewInstance();
+ CHECK(!instance->HasOwnProperty(v8_str("foo")));
+ CHECK(instance->HasOwnProperty(v8_str("bar")));
+ }
+}
+
+
+void CheckCodeGenerationAllowed() {
+ Handle<Value> result = CompileRun("eval('42')");
+ CHECK_EQ(42, result->Int32Value());
+ result = CompileRun("(function(e) { return e('42'); })(eval)");
+ CHECK_EQ(42, result->Int32Value());
+ result = CompileRun("var f = new Function('return 42'); f()");
+ CHECK_EQ(42, result->Int32Value());
+}
+
+
+void CheckCodeGenerationDisallowed() {
+ TryCatch try_catch;
+
+ Handle<Value> result = CompileRun("eval('42')");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+
+ result = CompileRun("(function(e) { return e('42'); })(eval)");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+
+ result = CompileRun("var f = new Function('return 42'); f()");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+}
+
+
+bool CodeGenerationAllowed(Local<Context> context) {
+ ApiTestFuzzer::Fuzz();
+ return true;
+}
+
+
+bool CodeGenerationDisallowed(Local<Context> context) {
+ ApiTestFuzzer::Fuzz();
+ return false;
+}
+
+
+THREADED_TEST(AllowCodeGenFromStrings) {
+ v8::HandleScope scope;
+ LocalContext context;
+
+ // eval and the Function constructor allowed by default.
+ CheckCodeGenerationAllowed();
+
+ // Disallow eval and the Function constructor.
+ context->AllowCodeGenerationFromStrings(false);
+ CheckCodeGenerationDisallowed();
+
+ // Allow again.
+ context->AllowCodeGenerationFromStrings(true);
+ CheckCodeGenerationAllowed();
+
+ // Disallow but setting a global callback that will allow the calls.
+ context->AllowCodeGenerationFromStrings(false);
+ V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationAllowed);
+ CheckCodeGenerationAllowed();
+
+ // Set a callback that disallows the code generation.
+ V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed);
+ CheckCodeGenerationDisallowed();
+}
+
+
+static v8::Handle<Value> NonObjectThis(const v8::Arguments& args) {
+ return v8::Undefined();
+}
+
+
+THREADED_TEST(CallAPIFunctionOnNonObject) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Handle<FunctionTemplate> templ = v8::FunctionTemplate::New(NonObjectThis);
+ Handle<Function> function = templ->GetFunction();
+ context->Global()->Set(v8_str("f"), function);
+ TryCatch try_catch;
+ CompileRun("f.call(2)");
+}
+
+
+// Regression test for issue 1470.
+THREADED_TEST(ReadOnlyIndexedProperties) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+
+ LocalContext context;
+ Local<v8::Object> obj = templ->NewInstance();
+ context->Global()->Set(v8_str("obj"), obj);
+ obj->Set(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->Set(v8_str("1"), v8_str("foobar"));
+ CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("1")));
+ obj->Set(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->Set(v8_num(2), v8_str("foobar"));
+ CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_num(2)));
+
+ // Test non-smi case.
+ obj->Set(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->Set(v8_str("2000000000"), v8_str("foobar"));
+ CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("2000000000")));
+}
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index 43cf580a5..17032035c 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// 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:
@@ -39,7 +39,8 @@ using namespace v8::internal;
// Define these function prototypes to match JSEntryFunction in execution.cc.
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
-typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
+typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
static v8::Persistent<v8::Context> env;
@@ -58,17 +59,17 @@ TEST(0) {
InitializeVM();
v8::HandleScope scope;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
__ add(r0, r0, Operand(r1));
__ mov(pc, Operand(lr));
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -84,7 +85,7 @@ TEST(1) {
InitializeVM();
v8::HandleScope scope;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
Label L, C;
__ mov(r1, Operand(r0));
@@ -102,10 +103,10 @@ TEST(1) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -121,7 +122,7 @@ TEST(2) {
InitializeVM();
v8::HandleScope scope;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
Label L, C;
__ mov(r1, Operand(r0));
@@ -139,7 +140,7 @@ TEST(2) {
// some relocated stuff here, not executed
__ RecordComment("dead code, just testing relocations");
- __ mov(r0, Operand(Factory::true_value()));
+ __ mov(r0, Operand(FACTORY->true_value()));
__ RecordComment("dead code, just testing immediate operands");
__ mov(r0, Operand(-1));
__ mov(r0, Operand(0xFF000000));
@@ -148,10 +149,10 @@ TEST(2) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -174,7 +175,7 @@ TEST(3) {
} T;
T t;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
Label L, C;
__ mov(ip, Operand(sp));
@@ -196,10 +197,10 @@ TEST(3) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -232,6 +233,8 @@ TEST(4) {
double g;
double h;
int i;
+ double m;
+ double n;
float x;
float y;
} T;
@@ -239,7 +242,7 @@ TEST(4) {
// Create a function that accepts &t, and loads, manipulates, and stores
// the doubles and floats.
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
Label L, C;
@@ -297,14 +300,22 @@ TEST(4) {
__ vabs(d0, d2);
__ vstr(d0, r4, OFFSET_OF(T, h));
+ // Test vneg.
+ __ vldr(d1, r4, OFFSET_OF(T, m));
+ __ vneg(d0, d1);
+ __ vstr(d0, r4, OFFSET_OF(T, m));
+ __ vldr(d1, r4, OFFSET_OF(T, n));
+ __ vneg(d0, d1);
+ __ vstr(d0, r4, OFFSET_OF(T, n));
+
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -319,12 +330,16 @@ TEST(4) {
t.g = -2718.2818;
t.h = 31415926.5;
t.i = 0;
+ t.m = -2718.2818;
+ t.n = 123.456;
t.x = 4.5;
t.y = 9.0;
Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
USE(dummy);
CHECK_EQ(4.5, t.y);
CHECK_EQ(9.0, t.x);
+ CHECK_EQ(-123.456, t.n);
+ CHECK_EQ(2718.2818, t.m);
CHECK_EQ(2, t.i);
CHECK_EQ(2718.2818, t.g);
CHECK_EQ(31415926.5, t.h);
@@ -343,7 +358,7 @@ TEST(5) {
InitializeVM();
v8::HandleScope scope;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
if (CpuFeatures::IsSupported(ARMv7)) {
CpuFeatures::Scope scope(ARMv7);
@@ -357,10 +372,10 @@ TEST(5) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -379,7 +394,7 @@ TEST(6) {
InitializeVM();
v8::HandleScope scope;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
if (CpuFeatures::IsSupported(ARMv7)) {
CpuFeatures::Scope scope(ARMv7);
@@ -392,10 +407,10 @@ TEST(6) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -422,7 +437,7 @@ static void TestRoundingMode(VCVTTypes types,
InitializeVM();
v8::HandleScope scope;
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
@@ -468,10 +483,10 @@ static void TestRoundingMode(VCVTTypes types,
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef DEBUG
Code::cast(code)->Print();
@@ -594,4 +609,405 @@ TEST(7) {
TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true);
}
+TEST(8) {
+ // Test VFP multi load/store with ia_w.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ } D;
+ D d;
+
+ typedef struct {
+ float a;
+ float b;
+ float c;
+ float d;
+ float e;
+ float f;
+ float g;
+ float h;
+ } F;
+ F f;
+
+ // Create a function that uses vldm/vstm to move some double and
+ // single precision values around in memory.
+ Assembler assm(Isolate::Current(), NULL, 0);
+
+ if (CpuFeatures::IsSupported(VFP3)) {
+ CpuFeatures::Scope scope(VFP3);
+
+ __ mov(ip, Operand(sp));
+ __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
+ __ sub(fp, ip, Operand(4));
+
+ __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ vldm(ia_w, r4, d0, d3);
+ __ vldm(ia_w, r4, d4, d7);
+
+ __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ vstm(ia_w, r4, d6, d7);
+ __ vstm(ia_w, r4, d0, d5);
+
+ __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ vldm(ia_w, r4, s0, s3);
+ __ vldm(ia_w, r4, s4, s7);
+
+ __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ vstm(ia_w, r4, s6, s7);
+ __ vstm(ia_w, r4, s0, s5);
+
+ __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+#ifdef DEBUG
+ Code::cast(code)->Print();
+#endif
+ F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
+ d.a = 1.1;
+ d.b = 2.2;
+ d.c = 3.3;
+ d.d = 4.4;
+ d.e = 5.5;
+ d.f = 6.6;
+ d.g = 7.7;
+ d.h = 8.8;
+
+ f.a = 1.0;
+ f.b = 2.0;
+ f.c = 3.0;
+ f.d = 4.0;
+ f.e = 5.0;
+ f.f = 6.0;
+ f.g = 7.0;
+ f.h = 8.0;
+
+ Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(7.7, d.a);
+ CHECK_EQ(8.8, d.b);
+ CHECK_EQ(1.1, d.c);
+ CHECK_EQ(2.2, d.d);
+ CHECK_EQ(3.3, d.e);
+ CHECK_EQ(4.4, d.f);
+ CHECK_EQ(5.5, d.g);
+ CHECK_EQ(6.6, d.h);
+
+ CHECK_EQ(7.0, f.a);
+ CHECK_EQ(8.0, f.b);
+ CHECK_EQ(1.0, f.c);
+ CHECK_EQ(2.0, f.d);
+ CHECK_EQ(3.0, f.e);
+ CHECK_EQ(4.0, f.f);
+ CHECK_EQ(5.0, f.g);
+ CHECK_EQ(6.0, f.h);
+ }
+}
+
+
+TEST(9) {
+ // Test VFP multi load/store with ia.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ } D;
+ D d;
+
+ typedef struct {
+ float a;
+ float b;
+ float c;
+ float d;
+ float e;
+ float f;
+ float g;
+ float h;
+ } F;
+ F f;
+
+ // Create a function that uses vldm/vstm to move some double and
+ // single precision values around in memory.
+ Assembler assm(Isolate::Current(), NULL, 0);
+
+ if (CpuFeatures::IsSupported(VFP3)) {
+ CpuFeatures::Scope scope(VFP3);
+
+ __ mov(ip, Operand(sp));
+ __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
+ __ sub(fp, ip, Operand(4));
+
+ __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ vldm(ia, r4, d0, d3);
+ __ add(r4, r4, Operand(4 * 8));
+ __ vldm(ia, r4, d4, d7);
+
+ __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ vstm(ia, r4, d6, d7);
+ __ add(r4, r4, Operand(2 * 8));
+ __ vstm(ia, r4, d0, d5);
+
+ __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ vldm(ia, r4, s0, s3);
+ __ add(r4, r4, Operand(4 * 4));
+ __ vldm(ia, r4, s4, s7);
+
+ __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ vstm(ia, r4, s6, s7);
+ __ add(r4, r4, Operand(2 * 4));
+ __ vstm(ia, r4, s0, s5);
+
+ __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+#ifdef DEBUG
+ Code::cast(code)->Print();
+#endif
+ F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
+ d.a = 1.1;
+ d.b = 2.2;
+ d.c = 3.3;
+ d.d = 4.4;
+ d.e = 5.5;
+ d.f = 6.6;
+ d.g = 7.7;
+ d.h = 8.8;
+
+ f.a = 1.0;
+ f.b = 2.0;
+ f.c = 3.0;
+ f.d = 4.0;
+ f.e = 5.0;
+ f.f = 6.0;
+ f.g = 7.0;
+ f.h = 8.0;
+
+ Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(7.7, d.a);
+ CHECK_EQ(8.8, d.b);
+ CHECK_EQ(1.1, d.c);
+ CHECK_EQ(2.2, d.d);
+ CHECK_EQ(3.3, d.e);
+ CHECK_EQ(4.4, d.f);
+ CHECK_EQ(5.5, d.g);
+ CHECK_EQ(6.6, d.h);
+
+ CHECK_EQ(7.0, f.a);
+ CHECK_EQ(8.0, f.b);
+ CHECK_EQ(1.0, f.c);
+ CHECK_EQ(2.0, f.d);
+ CHECK_EQ(3.0, f.e);
+ CHECK_EQ(4.0, f.f);
+ CHECK_EQ(5.0, f.g);
+ CHECK_EQ(6.0, f.h);
+ }
+}
+
+
+TEST(10) {
+ // Test VFP multi load/store with db_w.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ } D;
+ D d;
+
+ typedef struct {
+ float a;
+ float b;
+ float c;
+ float d;
+ float e;
+ float f;
+ float g;
+ float h;
+ } F;
+ F f;
+
+ // Create a function that uses vldm/vstm to move some double and
+ // single precision values around in memory.
+ Assembler assm(Isolate::Current(), NULL, 0);
+
+ if (CpuFeatures::IsSupported(VFP3)) {
+ CpuFeatures::Scope scope(VFP3);
+
+ __ mov(ip, Operand(sp));
+ __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
+ __ sub(fp, ip, Operand(4));
+
+ __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ vldm(db_w, r4, d4, d7);
+ __ vldm(db_w, r4, d0, d3);
+
+ __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ vstm(db_w, r4, d0, d5);
+ __ vstm(db_w, r4, d6, d7);
+
+ __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ vldm(db_w, r4, s4, s7);
+ __ vldm(db_w, r4, s0, s3);
+
+ __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ vstm(db_w, r4, s0, s5);
+ __ vstm(db_w, r4, s6, s7);
+
+ __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+#ifdef DEBUG
+ Code::cast(code)->Print();
+#endif
+ F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry());
+ d.a = 1.1;
+ d.b = 2.2;
+ d.c = 3.3;
+ d.d = 4.4;
+ d.e = 5.5;
+ d.f = 6.6;
+ d.g = 7.7;
+ d.h = 8.8;
+
+ f.a = 1.0;
+ f.b = 2.0;
+ f.c = 3.0;
+ f.d = 4.0;
+ f.e = 5.0;
+ f.f = 6.0;
+ f.g = 7.0;
+ f.h = 8.0;
+
+ Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(7.7, d.a);
+ CHECK_EQ(8.8, d.b);
+ CHECK_EQ(1.1, d.c);
+ CHECK_EQ(2.2, d.d);
+ CHECK_EQ(3.3, d.e);
+ CHECK_EQ(4.4, d.f);
+ CHECK_EQ(5.5, d.g);
+ CHECK_EQ(6.6, d.h);
+
+ CHECK_EQ(7.0, f.a);
+ CHECK_EQ(8.0, f.b);
+ CHECK_EQ(1.0, f.c);
+ CHECK_EQ(2.0, f.d);
+ CHECK_EQ(3.0, f.e);
+ CHECK_EQ(4.0, f.f);
+ CHECK_EQ(5.0, f.g);
+ CHECK_EQ(6.0, f.h);
+ }
+}
+
+
+TEST(11) {
+ // Test instructions using the carry flag.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ int32_t a;
+ int32_t b;
+ int32_t c;
+ int32_t d;
+ } I;
+ I i;
+
+ i.a = 0xabcd0001;
+ i.b = 0xabcd0000;
+
+ Assembler assm(Isolate::Current(), NULL, 0);
+
+ // Test HeapObject untagging.
+ __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ mov(r1, Operand(r1, ASR, 1), SetCC);
+ __ adc(r1, r1, Operand(r1), LeaveCC, cs);
+ __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
+
+ __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ mov(r2, Operand(r2, ASR, 1), SetCC);
+ __ adc(r2, r2, Operand(r2), LeaveCC, cs);
+ __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
+
+ // Test corner cases.
+ __ mov(r1, Operand(0xffffffff));
+ __ mov(r2, Operand(0));
+ __ mov(r3, Operand(r1, ASR, 1), SetCC); // Set the carry.
+ __ adc(r3, r1, Operand(r2));
+ __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
+
+ __ mov(r1, Operand(0xffffffff));
+ __ mov(r2, Operand(0));
+ __ mov(r3, Operand(r2, ASR, 1), SetCC); // Unset the carry.
+ __ adc(r3, r1, Operand(r2));
+ __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
+
+ __ mov(pc, Operand(lr));
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+#ifdef DEBUG
+ Code::cast(code)->Print();
+#endif
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0xabcd0001, i.a);
+ CHECK_EQ(static_cast<int32_t>(0xabcd0000) >> 1, i.b);
+ CHECK_EQ(0x00000000, i.c);
+ CHECK_EQ(0xffffffff, i.d);
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc
index 14692ff1e..e9d799b54 100644
--- a/deps/v8/test/cctest/test-assembler-ia32.cc
+++ b/deps/v8/test/cctest/test-assembler-ia32.cc
@@ -61,7 +61,7 @@ TEST(AssemblerIa320) {
v8::HandleScope scope;
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
__ mov(eax, Operand(esp, 4));
__ add(eax, Operand(esp, 8));
@@ -69,10 +69,10 @@ TEST(AssemblerIa320) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->
- ToObjectChecked();
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
@@ -89,7 +89,7 @@ TEST(AssemblerIa321) {
v8::HandleScope scope;
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
Label L, C;
__ mov(edx, Operand(esp, 4));
@@ -102,15 +102,15 @@ TEST(AssemblerIa321) {
__ bind(&C);
__ test(edx, Operand(edx));
- __ j(not_zero, &L, taken);
+ __ j(not_zero, &L);
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->
- ToObjectChecked();
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
@@ -127,7 +127,7 @@ TEST(AssemblerIa322) {
v8::HandleScope scope;
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
Label L, C;
__ mov(edx, Operand(esp, 4));
@@ -140,20 +140,19 @@ TEST(AssemblerIa322) {
__ bind(&C);
__ test(edx, Operand(edx));
- __ j(not_zero, &L, taken);
+ __ j(not_zero, &L);
__ ret(0);
// some relocated stuff here, not executed
- __ mov(eax, Factory::true_value());
+ __ mov(eax, FACTORY->true_value());
__ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
-
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
@@ -168,13 +167,13 @@ TEST(AssemblerIa322) {
typedef int (*F3)(float x);
TEST(AssemblerIa323) {
+ InitializeVM();
if (!CpuFeatures::IsSupported(SSE2)) return;
- InitializeVM();
v8::HandleScope scope;
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
CHECK(CpuFeatures::IsSupported(SSE2));
{ CpuFeatures::Scope fscope(SSE2);
@@ -184,10 +183,10 @@ TEST(AssemblerIa323) {
CodeDesc desc;
assm.GetCode(&desc);
- Code* code = Code::cast(Heap::CreateCode(
+ Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
// don't print the code - our disassembler can't handle cvttss2si
// instead print bytes
Disassembler::Dump(stdout,
@@ -203,13 +202,13 @@ TEST(AssemblerIa323) {
typedef int (*F4)(double x);
TEST(AssemblerIa324) {
+ InitializeVM();
if (!CpuFeatures::IsSupported(SSE2)) return;
- InitializeVM();
v8::HandleScope scope;
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
CHECK(CpuFeatures::IsSupported(SSE2));
CpuFeatures::Scope fscope(SSE2);
@@ -218,10 +217,10 @@ TEST(AssemblerIa324) {
CodeDesc desc;
assm.GetCode(&desc);
- Code* code = Code::cast(Heap::CreateCode(
+ Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
// don't print the code - our disassembler can't handle cvttsd2si
// instead print bytes
Disassembler::Dump(stdout,
@@ -240,17 +239,17 @@ TEST(AssemblerIa325) {
v8::HandleScope scope;
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
__ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE));
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
- Code* code = Code::cast(Heap::CreateCode(
+ Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
F0 f = FUNCTION_CAST<F0>(code->entry());
int res = f();
CHECK_EQ(42, res);
@@ -260,14 +259,14 @@ TEST(AssemblerIa325) {
typedef double (*F5)(double x, double y);
TEST(AssemblerIa326) {
+ InitializeVM();
if (!CpuFeatures::IsSupported(SSE2)) return;
- InitializeVM();
v8::HandleScope scope;
CHECK(CpuFeatures::IsSupported(SSE2));
CpuFeatures::Scope fscope(SSE2);
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
__ movdbl(xmm0, Operand(esp, 1 * kPointerSize));
__ movdbl(xmm1, Operand(esp, 3 * kPointerSize));
@@ -284,10 +283,10 @@ TEST(AssemblerIa326) {
CodeDesc desc;
assm.GetCode(&desc);
- Code* code = Code::cast(Heap::CreateCode(
+ Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
#ifdef DEBUG
::printf("\n---\n");
// don't print the code - our disassembler can't handle SSE instructions
@@ -306,14 +305,14 @@ TEST(AssemblerIa326) {
typedef double (*F6)(int x);
TEST(AssemblerIa328) {
+ InitializeVM();
if (!CpuFeatures::IsSupported(SSE2)) return;
- InitializeVM();
v8::HandleScope scope;
CHECK(CpuFeatures::IsSupported(SSE2));
CpuFeatures::Scope fscope(SSE2);
v8::internal::byte buffer[256];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
__ mov(eax, Operand(esp, 4));
__ cvtsi2sd(xmm0, Operand(eax));
// Copy xmm0 to st(0) using eight bytes of stack.
@@ -324,10 +323,10 @@ TEST(AssemblerIa328) {
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
- Code* code = Code::cast(Heap::CreateCode(
+ Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
@@ -346,16 +345,16 @@ TEST(AssemblerIa329) {
InitializeVM();
v8::HandleScope scope;
v8::internal::byte buffer[256];
- MacroAssembler assm(buffer, sizeof buffer);
+ MacroAssembler assm(Isolate::Current(), buffer, sizeof buffer);
enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 };
Label equal_l, less_l, greater_l, nan_l;
__ fld_d(Operand(esp, 3 * kPointerSize));
__ fld_d(Operand(esp, 1 * kPointerSize));
__ FCmp();
- __ j(parity_even, &nan_l, taken);
- __ j(equal, &equal_l, taken);
- __ j(below, &less_l, taken);
- __ j(above, &greater_l, taken);
+ __ j(parity_even, &nan_l);
+ __ j(equal, &equal_l);
+ __ j(below, &less_l);
+ __ j(above, &greater_l);
__ mov(eax, kUndefined);
__ ret(0);
@@ -379,10 +378,10 @@ TEST(AssemblerIa329) {
CodeDesc desc;
assm.GetCode(&desc);
- Code* code = Code::cast(Heap::CreateCode(
+ Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc
index ecb42e2f7..8ac89f6b3 100644
--- a/deps/v8/test/cctest/test-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-assembler-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// 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:
@@ -59,11 +59,12 @@ static void InitializeVM() {
#define __ assm.
+
TEST(MIPS0) {
InitializeVM();
v8::HandleScope scope;
- MacroAssembler assm(NULL, 0);
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
// Addition.
__ addu(v0, a0, a1);
@@ -72,14 +73,11 @@ TEST(MIPS0) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(desc,
- NULL,
- Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()));
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
-#ifdef DEBUG
- Code::cast(code)->Print();
-#endif
F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
::printf("f() = %d\n", res);
@@ -91,7 +89,7 @@ TEST(MIPS1) {
InitializeVM();
v8::HandleScope scope;
- MacroAssembler assm(NULL, 0);
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
Label L, C;
__ mov(a1, a0);
@@ -100,12 +98,12 @@ TEST(MIPS1) {
__ nop();
__ bind(&L);
- __ add(v0, v0, a1);
+ __ addu(v0, v0, a1);
__ addiu(a1, a1, -1);
__ bind(&C);
__ xori(v1, a1, 0);
- __ Branch(ne, &L, v1, Operand(0, RelocInfo::NONE));
+ __ Branch(&L, ne, v1, Operand(0));
__ nop();
__ jr(ra);
@@ -113,14 +111,11 @@ TEST(MIPS1) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(desc,
- NULL,
- Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()));
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
-#ifdef DEBUG
- Code::cast(code)->Print();
-#endif
F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
::printf("f() = %d\n", res);
@@ -132,7 +127,7 @@ TEST(MIPS2) {
InitializeVM();
v8::HandleScope scope;
- MacroAssembler assm(NULL, 0);
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
Label exit, error;
@@ -166,62 +161,81 @@ TEST(MIPS2) {
__ srav(v0, v0, t0); // 0xff234560
__ sllv(v0, v0, t0); // 0xf2345600
__ srlv(v0, v0, t0); // 0x0f234560
- __ Branch(ne, &error, v0, Operand(0x0f234560));
+ __ Branch(&error, ne, v0, Operand(0x0f234560));
__ nop();
- __ add(v0, t0, t1); // 0x00001238
- __ sub(v0, v0, t0); // 0x00001234
- __ Branch(ne, &error, v0, Operand(0x00001234));
+ __ addu(v0, t0, t1); // 0x00001238
+ __ subu(v0, v0, t0); // 0x00001234
+ __ Branch(&error, ne, v0, Operand(0x00001234));
__ nop();
__ addu(v1, t3, t0);
- __ Branch(ne, &error, v1, Operand(0x80000003));
+ __ Branch(&error, ne, v1, Operand(0x80000003));
__ nop();
__ subu(v1, t7, t0); // 0x7ffffffc
- __ Branch(ne, &error, v1, Operand(0x7ffffffc));
+ __ Branch(&error, ne, v1, Operand(0x7ffffffc));
__ nop();
__ and_(v0, t1, t2); // 0x00001230
__ or_(v0, v0, t1); // 0x00001234
__ xor_(v0, v0, t2); // 0x1234444c
__ nor(v0, v0, t2); // 0xedcba987
- __ Branch(ne, &error, v0, Operand(0xedcba983));
+ __ Branch(&error, ne, v0, Operand(0xedcba983));
__ nop();
__ slt(v0, t7, t3);
- __ Branch(ne, &error, v0, Operand(0x1));
+ __ Branch(&error, ne, v0, Operand(0x1));
__ nop();
__ sltu(v0, t7, t3);
- __ Branch(ne, &error, v0, Operand(0x0));
+ __ Branch(&error, ne, v0, Operand(0x0));
__ nop();
// End of SPECIAL class.
- __ addi(v0, zero_reg, 0x7421); // 0x00007421
- __ addi(v0, v0, -0x1); // 0x00007420
+ __ addiu(v0, zero_reg, 0x7421); // 0x00007421
+ __ addiu(v0, v0, -0x1); // 0x00007420
__ addiu(v0, v0, -0x20); // 0x00007400
- __ Branch(ne, &error, v0, Operand(0x00007400));
+ __ Branch(&error, ne, v0, Operand(0x00007400));
__ nop();
__ addiu(v1, t3, 0x1); // 0x80000000
- __ Branch(ne, &error, v1, Operand(0x80000000));
+ __ Branch(&error, ne, v1, Operand(0x80000000));
__ nop();
__ slti(v0, t1, 0x00002000); // 0x1
__ slti(v0, v0, 0xffff8000); // 0x0
- __ Branch(ne, &error, v0, Operand(0x0));
+ __ Branch(&error, ne, v0, Operand(0x0));
__ nop();
__ sltiu(v0, t1, 0x00002000); // 0x1
__ sltiu(v0, v0, 0x00008000); // 0x1
- __ Branch(ne, &error, v0, Operand(0x1));
+ __ Branch(&error, ne, v0, Operand(0x1));
__ nop();
__ andi(v0, t1, 0xf0f0); // 0x00001030
__ ori(v0, v0, 0x8a00); // 0x00009a30
__ xori(v0, v0, 0x83cc); // 0x000019fc
- __ Branch(ne, &error, v0, Operand(0x000019fc));
+ __ Branch(&error, ne, v0, Operand(0x000019fc));
__ nop();
__ lui(v1, 0x8123); // 0x81230000
- __ Branch(ne, &error, v1, Operand(0x81230000));
+ __ Branch(&error, ne, v1, Operand(0x81230000));
__ nop();
+ // Bit twiddling instructions & conditional moves.
+ // Uses t0-t7 as set above.
+ __ clz(v0, t0); // 29
+ __ clz(v1, t1); // 19
+ __ addu(v0, v0, v1); // 48
+ __ clz(v1, t2); // 3
+ __ addu(v0, v0, v1); // 51
+ __ clz(v1, t7); // 0
+ __ addu(v0, v0, v1); // 51
+ __ Branch(&error, ne, v0, Operand(51));
+ __ movn(a0, t3, t0); // Move a0<-t3 (t0 is NOT 0).
+ __ Ins(a0, t1, 12, 8); // 0x7ff34fff
+ __ Branch(&error, ne, a0, Operand(0x7ff34fff));
+ __ movz(a0, t6, t7); // a0 not updated (t7 is NOT 0).
+ __ Ext(a1, a0, 8, 12); // 0x34f
+ __ Branch(&error, ne, a1, Operand(0x34f));
+ __ movz(a0, t6, v1); // a0<-t6, v0 is 0, from 8 instr back.
+ __ Branch(&error, ne, a0, Operand(t6));
+
// Everything was correctly executed. Load the expected result.
__ li(v0, 0x31415926);
__ b(&exit);
@@ -229,6 +243,7 @@ TEST(MIPS2) {
__ bind(&error);
// Got an error. Return a wrong result.
+ __ li(v0, 666);
__ bind(&exit);
__ jr(ra);
@@ -236,18 +251,1012 @@ TEST(MIPS2) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(desc,
- NULL,
- Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()));
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
-#ifdef DEBUG
- Code::cast(code)->Print();
-#endif
F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
::printf("f() = %d\n", res);
CHECK_EQ(0x31415926, res);
}
+
+TEST(MIPS3) {
+ // Test floating point instructions.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ } T;
+ T t;
+
+ // Create a function that accepts &t, and loads, manipulates, and stores
+ // the doubles t.a ... t.f.
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+ Label L, C;
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ add_d(f8, f4, f6);
+ __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
+
+ __ mov_d(f10, f8); // c
+ __ neg_d(f12, f6); // -b
+ __ sub_d(f10, f10, f12);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
+
+ __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
+
+ __ li(t0, 120);
+ __ mtc1(t0, f14);
+ __ cvt_d_w(f14, f14); // f14 = 120.0.
+ __ mul_d(f10, f10, f14);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
+
+ __ div_d(f12, f10, f4);
+ __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44.
+
+ __ sqrt_d(f14, f12);
+ __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
+ // g = sqrt(f) = 10.97451593465515908537
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.a = 1.5e14;
+ t.b = 2.75e11;
+ t.c = 0.0;
+ t.d = 0.0;
+ t.e = 0.0;
+ t.f = 0.0;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ(1.5e14, t.a);
+ CHECK_EQ(1.5e14, t.b);
+ CHECK_EQ(1.50275e14, t.c);
+ CHECK_EQ(1.50550e14, t.d);
+ CHECK_EQ(1.8066e16, t.e);
+ CHECK_EQ(120.44, t.f);
+ CHECK_EQ(10.97451593465515908537, t.g);
+ }
+}
+
+
+TEST(MIPS4) {
+ // Test moves between floating point and integer registers.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ } T;
+ T t;
+
+ Assembler assm(Isolate::Current(), NULL, 0);
+ Label L, C;
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+
+ // Swap f4 and f6, by using four integer registers, t0-t3.
+ __ mfc1(t0, f4);
+ __ mfc1(t1, f5);
+ __ mfc1(t2, f6);
+ __ mfc1(t3, f7);
+
+ __ mtc1(t0, f6);
+ __ mtc1(t1, f7);
+ __ mtc1(t2, f4);
+ __ mtc1(t3, f5);
+
+ // Store the swapped f4 and f5 back to memory.
+ __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.a = 1.5e22;
+ t.b = 2.75e11;
+ t.c = 17.17;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(2.75e11, t.a);
+ CHECK_EQ(2.75e11, t.b);
+ CHECK_EQ(1.5e22, t.c);
+ }
+}
+
+
+TEST(MIPS5) {
+ // Test conversions between doubles and integers.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ int i;
+ int j;
+ } T;
+ T t;
+
+ Assembler assm(Isolate::Current(), NULL, 0);
+ Label L, C;
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ // Load all structure elements to registers.
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
+
+ // Convert double in f4 to int in element i.
+ __ cvt_w_d(f8, f4);
+ __ mfc1(t2, f8);
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) );
+
+ // Convert double in f6 to int in element j.
+ __ cvt_w_d(f10, f6);
+ __ mfc1(t3, f10);
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) );
+
+ // Convert int in original i (t0) to double in a.
+ __ mtc1(t0, f12);
+ __ cvt_d_w(f0, f12);
+ __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
+
+ // Convert int in original j (t1) to double in b.
+ __ mtc1(t1, f14);
+ __ cvt_d_w(f2, f14);
+ __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.a = 1.5e4;
+ t.b = 2.75e8;
+ t.i = 12345678;
+ t.j = -100000;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(12345678.0, t.a);
+ CHECK_EQ(-100000.0, t.b);
+ CHECK_EQ(15000, t.i);
+ CHECK_EQ(275000000, t.j);
+ }
+}
+
+
+TEST(MIPS6) {
+ // Test simple memory loads and stores.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ uint32_t ui;
+ int32_t si;
+ int32_t r1;
+ int32_t r2;
+ int32_t r3;
+ int32_t r4;
+ int32_t r5;
+ int32_t r6;
+ } T;
+ T t;
+
+ Assembler assm(Isolate::Current(), NULL, 0);
+ Label L, C;
+
+ // Basic word load/store.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, ui)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, r1)) );
+
+ // lh with positive data.
+ __ lh(t1, MemOperand(a0, OFFSET_OF(T, ui)) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, r2)) );
+
+ // lh with negative data.
+ __ lh(t2, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, r3)) );
+
+ // lhu with negative data.
+ __ lhu(t3, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, r4)) );
+
+ // lb with negative data.
+ __ lb(t4, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sw(t4, MemOperand(a0, OFFSET_OF(T, r5)) );
+
+ // sh writes only 1/2 of word.
+ __ lui(t5, 0x3333);
+ __ ori(t5, t5, 0x3333);
+ __ sw(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
+ __ lhu(t5, MemOperand(a0, OFFSET_OF(T, si)) );
+ __ sh(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.ui = 0x11223344;
+ t.si = 0x99aabbcc;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x11223344, t.r1);
+ CHECK_EQ(0x3344, t.r2);
+ CHECK_EQ(0xffffbbcc, t.r3);
+ CHECK_EQ(0x0000bbcc, t.r4);
+ CHECK_EQ(0xffffffcc, t.r5);
+ CHECK_EQ(0x3333bbcc, t.r6);
+}
+
+
+TEST(MIPS7) {
+ // Test floating point compare and branch instructions.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ int32_t result;
+ } T;
+ T t;
+
+ // Create a function that accepts &t, and loads, manipulates, and stores
+ // the doubles t.a ... t.f.
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+ Label neither_is_nan, less_than, outa_here;
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ c(UN, D, f4, f6);
+ __ bc1f(&neither_is_nan);
+ __ nop();
+ __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ Branch(&outa_here);
+
+ __ bind(&neither_is_nan);
+
+ __ c(OLT, D, f6, f4, 2);
+ __ bc1t(&less_than, 2);
+ __ nop();
+ __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ Branch(&outa_here);
+
+ __ bind(&less_than);
+ __ Addu(t0, zero_reg, Operand(1));
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
+
+
+ // This test-case should have additional tests.
+
+ __ bind(&outa_here);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.a = 1.5e14;
+ t.b = 2.75e11;
+ t.c = 2.0;
+ t.d = -4.0;
+ t.e = 0.0;
+ t.f = 0.0;
+ t.result = 0;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ(1.5e14, t.a);
+ CHECK_EQ(2.75e11, t.b);
+ CHECK_EQ(1, t.result);
+ }
+}
+
+
+TEST(MIPS8) {
+ // Test ROTR and ROTRV instructions.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ int32_t input;
+ int32_t result_rotr_4;
+ int32_t result_rotr_8;
+ int32_t result_rotr_12;
+ int32_t result_rotr_16;
+ int32_t result_rotr_20;
+ int32_t result_rotr_24;
+ int32_t result_rotr_28;
+ int32_t result_rotrv_4;
+ int32_t result_rotrv_8;
+ int32_t result_rotrv_12;
+ int32_t result_rotrv_16;
+ int32_t result_rotrv_20;
+ int32_t result_rotrv_24;
+ int32_t result_rotrv_28;
+ } T;
+ T t;
+
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+
+ // Basic word load.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, input)) );
+
+ // ROTR instruction (called through the Ror macro).
+ __ Ror(t1, t0, 0x0004);
+ __ Ror(t2, t0, 0x0008);
+ __ Ror(t3, t0, 0x000c);
+ __ Ror(t4, t0, 0x0010);
+ __ Ror(t5, t0, 0x0014);
+ __ Ror(t6, t0, 0x0018);
+ __ Ror(t7, t0, 0x001c);
+
+ // Basic word store.
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
+ __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
+ __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
+ __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
+ __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
+
+ // ROTRV instruction (called through the Ror macro).
+ __ li(t7, 0x0004);
+ __ Ror(t1, t0, t7);
+ __ li(t7, 0x0008);
+ __ Ror(t2, t0, t7);
+ __ li(t7, 0x000C);
+ __ Ror(t3, t0, t7);
+ __ li(t7, 0x0010);
+ __ Ror(t4, t0, t7);
+ __ li(t7, 0x0014);
+ __ Ror(t5, t0, t7);
+ __ li(t7, 0x0018);
+ __ Ror(t6, t0, t7);
+ __ li(t7, 0x001C);
+ __ Ror(t7, t0, t7);
+
+ // Basic word store.
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
+ __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
+ __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
+ __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
+ __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.input = 0x12345678;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ(0x81234567, t.result_rotr_4);
+ CHECK_EQ(0x78123456, t.result_rotr_8);
+ CHECK_EQ(0x67812345, t.result_rotr_12);
+ CHECK_EQ(0x56781234, t.result_rotr_16);
+ CHECK_EQ(0x45678123, t.result_rotr_20);
+ CHECK_EQ(0x34567812, t.result_rotr_24);
+ CHECK_EQ(0x23456781, t.result_rotr_28);
+
+ CHECK_EQ(0x81234567, t.result_rotrv_4);
+ CHECK_EQ(0x78123456, t.result_rotrv_8);
+ CHECK_EQ(0x67812345, t.result_rotrv_12);
+ CHECK_EQ(0x56781234, t.result_rotrv_16);
+ CHECK_EQ(0x45678123, t.result_rotrv_20);
+ CHECK_EQ(0x34567812, t.result_rotrv_24);
+ CHECK_EQ(0x23456781, t.result_rotrv_28);
+}
+
+
+TEST(MIPS9) {
+ // Test BRANCH improvements.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+ Label exit, exit2, exit3;
+
+ __ Branch(&exit, ge, a0, Operand(0x00000000));
+ __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
+ __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
+
+ __ bind(&exit);
+ __ bind(&exit2);
+ __ bind(&exit3);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+}
+
+
+TEST(MIPS10) {
+ // Test conversions between doubles and long integers.
+ // Test hos the long ints map to FP regs pairs.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double a;
+ double b;
+ int32_t dbl_mant;
+ int32_t dbl_exp;
+ int32_t long_hi;
+ int32_t long_lo;
+ int32_t b_long_hi;
+ int32_t b_long_lo;
+ } T;
+ T t;
+
+ Assembler assm(Isolate::Current(), NULL, 0);
+ Label L, C;
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ // Load all structure elements to registers.
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
+
+ // Save the raw bits of the double.
+ __ mfc1(t0, f0);
+ __ mfc1(t1, f1);
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
+
+ // Convert double in f0 to long, save hi/lo parts.
+ __ cvt_l_d(f0, f0);
+ __ mfc1(t0, f0); // f0 has LS 32 bits of long.
+ __ mfc1(t1, f1); // f1 has MS 32 bits of long.
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, long_lo)));
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, long_hi)));
+
+ // Convert the b long integers to double b.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
+ __ mtc1(t0, f8); // f8 has LS 32-bits.
+ __ mtc1(t1, f9); // f9 has MS 32-bits.
+ __ cvt_d_l(f10, f8);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.a = 2.147483647e9; // 0x7fffffff -> 0x41DFFFFFFFC00000 as double.
+ t.b_long_hi = 0x000000ff; // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double.
+ t.b_long_lo = 0x00ff00ff;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x41DFFFFF, t.dbl_exp);
+ CHECK_EQ(0xFFC00000, t.dbl_mant);
+ CHECK_EQ(0, t.long_hi);
+ CHECK_EQ(0x7fffffff, t.long_lo);
+ // 0xFF00FF00FF -> 1.095233372415e12.
+ CHECK_EQ(1.095233372415e12, t.b);
+ }
+}
+
+
+TEST(MIPS11) {
+ // Test LWL, LWR, SWL and SWR instructions.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ int32_t reg_init;
+ int32_t mem_init;
+ int32_t lwl_0;
+ int32_t lwl_1;
+ int32_t lwl_2;
+ int32_t lwl_3;
+ int32_t lwr_0;
+ int32_t lwr_1;
+ int32_t lwr_2;
+ int32_t lwr_3;
+ int32_t swl_0;
+ int32_t swl_1;
+ int32_t swl_2;
+ int32_t swl_3;
+ int32_t swr_0;
+ int32_t swr_1;
+ int32_t swr_2;
+ int32_t swr_3;
+ } T;
+ T t;
+
+ Assembler assm(Isolate::Current(), NULL, 0);
+
+ // Test all combinations of LWL and vAddr.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwl_0)) );
+
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwl_1)) );
+
+ __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwl_2)) );
+
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwl(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwl_3)) );
+
+ // Test all combinations of LWR and vAddr.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwr_0)) );
+
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwr_1)) );
+
+ __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
+
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ lwr(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
+
+ // Test all combinations of SWL and vAddr.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
+
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, swl_1)) );
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(t1, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) );
+
+ __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, swl_2)) );
+ __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(t2, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) );
+
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, swl_3)) );
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swl(t3, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) );
+
+ // Test all combinations of SWR and vAddr.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
+
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t1, MemOperand(a0, OFFSET_OF(T, swr_1)) );
+ __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(t1, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) );
+
+ __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t2, MemOperand(a0, OFFSET_OF(T, swr_2)) );
+ __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(t2, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) );
+
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
+ __ sw(t3, MemOperand(a0, OFFSET_OF(T, swr_3)) );
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
+ __ swr(t3, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.reg_init = 0xaabbccdd;
+ t.mem_init = 0x11223344;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x44bbccdd, t.lwl_0);
+ CHECK_EQ(0x3344ccdd, t.lwl_1);
+ CHECK_EQ(0x223344dd, t.lwl_2);
+ CHECK_EQ(0x11223344, t.lwl_3);
+
+ CHECK_EQ(0x11223344, t.lwr_0);
+ CHECK_EQ(0xaa112233, t.lwr_1);
+ CHECK_EQ(0xaabb1122, t.lwr_2);
+ CHECK_EQ(0xaabbcc11, t.lwr_3);
+
+ CHECK_EQ(0x112233aa, t.swl_0);
+ CHECK_EQ(0x1122aabb, t.swl_1);
+ CHECK_EQ(0x11aabbcc, t.swl_2);
+ CHECK_EQ(0xaabbccdd, t.swl_3);
+
+ CHECK_EQ(0xaabbccdd, t.swr_0);
+ CHECK_EQ(0xbbccdd44, t.swr_1);
+ CHECK_EQ(0xccdd3344, t.swr_2);
+ CHECK_EQ(0xdd223344, t.swr_3);
+}
+
+
+TEST(MIPS12) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ int32_t x;
+ int32_t y;
+ int32_t y1;
+ int32_t y2;
+ int32_t y3;
+ int32_t y4;
+ } T;
+ T t;
+
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+
+ __ mov(t6, fp); // Save frame pointer.
+ __ mov(fp, a0); // Access struct T by fp.
+ __ lw(t0, MemOperand(a0, OFFSET_OF(T, y)) );
+ __ lw(t3, MemOperand(a0, OFFSET_OF(T, y4)) );
+
+ __ addu(t1, t0, t3);
+ __ subu(t4, t0, t3);
+ __ nop();
+ __ push(t0); // These instructions disappear after opt.
+ __ Pop();
+ __ addu(t0, t0, t0);
+ __ nop();
+ __ Pop(); // These instructions disappear after opt.
+ __ push(t3);
+ __ nop();
+ __ push(t3); // These instructions disappear after opt.
+ __ pop(t3);
+ __ nop();
+ __ push(t3);
+ __ pop(t4);
+ __ nop();
+ __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ nop();
+ __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ nop();
+ __ push(t1);
+ __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(t1);
+ __ nop();
+ __ push(t1);
+ __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(t1);
+ __ nop();
+ __ push(t1);
+ __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(t2);
+ __ nop();
+ __ push(t2);
+ __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(t1);
+ __ nop();
+ __ push(t1);
+ __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ pop(t3);
+ __ nop();
+
+ __ mov(fp, t6);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.x = 1;
+ t.y = 2;
+ t.y1 = 3;
+ t.y2 = 4;
+ t.y3 = 0XBABA;
+ t.y4 = 0xDEDA;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(3, t.y1);
+}
+
+
+TEST(MIPS13) {
+ // Test Cvt_d_uw and Trunc_uw_d macros.
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ double cvt_big_out;
+ double cvt_small_out;
+ uint32_t trunc_big_out;
+ uint32_t trunc_small_out;
+ uint32_t cvt_big_in;
+ uint32_t cvt_small_in;
+ } T;
+ T t;
+
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
+ __ Cvt_d_uw(f10, t0);
+ __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
+
+ __ Trunc_uw_d(f10, f10);
+ __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
+
+ __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
+ __ Cvt_d_uw(f8, t0);
+ __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
+
+ __ Trunc_uw_d(f8, f8);
+ __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+
+ t.cvt_big_in = 0xFFFFFFFF;
+ t.cvt_small_in = 333;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
+ CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
+
+ CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
+ CHECK_EQ(static_cast<int>(t.trunc_small_out),
+ static_cast<int>(t.cvt_small_in));
+ }
+}
+
+
+TEST(MIPS14) {
+ // Test round, floor, ceil, trunc, cvt.
+ InitializeVM();
+ v8::HandleScope scope;
+
+#define ROUND_STRUCT_ELEMENT(x) \
+ int32_t x##_up_out; \
+ int32_t x##_down_out; \
+ int32_t neg_##x##_up_out; \
+ int32_t neg_##x##_down_out; \
+ uint32_t x##_err1_out; \
+ uint32_t x##_err2_out; \
+ uint32_t x##_err3_out; \
+ uint32_t x##_err4_out; \
+ int32_t x##_invalid_result;
+
+ typedef struct {
+ double round_up_in;
+ double round_down_in;
+ double neg_round_up_in;
+ double neg_round_down_in;
+ double err1_in;
+ double err2_in;
+ double err3_in;
+ double err4_in;
+
+ ROUND_STRUCT_ELEMENT(round)
+ ROUND_STRUCT_ELEMENT(floor)
+ ROUND_STRUCT_ELEMENT(ceil)
+ ROUND_STRUCT_ELEMENT(trunc)
+ ROUND_STRUCT_ELEMENT(cvt)
+ } T;
+ T t;
+
+#undef ROUND_STRUCT_ELEMENT
+
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+
+ if (CpuFeatures::IsSupported(FPU)) {
+ CpuFeatures::Scope scope(FPU);
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+#define RUN_ROUND_TEST(x) \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
+ __ x##_w_d(f0, f0); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
+ \
+ __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
+ __ ctc1(zero_reg, FCSR); \
+ __ x##_w_d(f0, f0); \
+ __ cfc1(a2, FCSR); \
+ __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
+ __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
+
+ RUN_ROUND_TEST(round)
+ RUN_ROUND_TEST(floor)
+ RUN_ROUND_TEST(ceil)
+ RUN_ROUND_TEST(trunc)
+ RUN_ROUND_TEST(cvt)
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+
+ t.round_up_in = 123.51;
+ t.round_down_in = 123.49;
+ t.neg_round_up_in = -123.5;
+ t.neg_round_down_in = -123.49;
+ t.err1_in = 123.51;
+ t.err2_in = 1;
+ t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
+ t.err4_in = NAN;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+#define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
+#define CHECK_ROUND_RESULT(type) \
+ CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
+ CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
+ CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
+ CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
+ CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result);
+
+ CHECK_ROUND_RESULT(round);
+ CHECK_ROUND_RESULT(floor);
+ CHECK_ROUND_RESULT(ceil);
+ CHECK_ROUND_RESULT(cvt);
+ }
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc
index 5d292df05..ea70f5420 100644
--- a/deps/v8/test/cctest/test-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-assembler-x64.cc
@@ -35,31 +35,31 @@
#include "serialize.h"
#include "cctest.h"
-using v8::internal::byte;
-using v8::internal::OS;
using v8::internal::Assembler;
-using v8::internal::Operand;
+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::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::rsi;
-using v8::internal::rdi;
+using v8::internal::rbp;
using v8::internal::rcx;
+using v8::internal::rdi;
using v8::internal::rdx;
-using v8::internal::rbp;
+using v8::internal::rsi;
using v8::internal::rsp;
-using v8::internal::r8;
-using v8::internal::r9;
-using v8::internal::r12;
-using v8::internal::r13;
using v8::internal::times_1;
-using v8::internal::FUNCTION_CAST;
-using v8::internal::CodeDesc;
-using v8::internal::less_equal;
-using v8::internal::not_equal;
-using v8::internal::greater;
-
// Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
@@ -86,13 +86,14 @@ static const v8::internal::Register arg2 = rsi;
TEST(AssemblerX64ReturnOperation) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
// Assemble a simple function that copies argument 2 and returns it.
__ movq(rax, arg2);
@@ -107,13 +108,14 @@ TEST(AssemblerX64ReturnOperation) {
}
TEST(AssemblerX64StackOperations) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), 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
@@ -138,13 +140,14 @@ TEST(AssemblerX64StackOperations) {
}
TEST(AssemblerX64ArithmeticOperations) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
// Assemble a simple function that adds arguments returning the sum.
__ movq(rax, arg2);
@@ -159,13 +162,14 @@ TEST(AssemblerX64ArithmeticOperations) {
}
TEST(AssemblerX64ImulOperation) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
// Assemble a simple function that multiplies arguments returning the high
// word.
@@ -186,13 +190,14 @@ TEST(AssemblerX64ImulOperation) {
}
TEST(AssemblerX64MemoryOperands) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
// Assemble a simple function that copies argument 2 and returns it.
__ push(rbp);
@@ -219,13 +224,14 @@ TEST(AssemblerX64MemoryOperands) {
}
TEST(AssemblerX64ControlFlow) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
// Assemble a simple function that copies argument 1 and returns it.
__ push(rbp);
@@ -247,13 +253,14 @@ TEST(AssemblerX64ControlFlow) {
}
TEST(AssemblerX64LoopImmediates) {
+ OS::Setup();
// 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(buffer, static_cast<int>(actual_size));
+ Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
// Assemble two loops using rax as counter, and verify the ending counts.
Label Fail;
__ movq(rax, Immediate(-3));
@@ -317,7 +324,7 @@ TEST(OperandRegisterDependency) {
CHECK(Operand(rsp, offset).AddressUsesRegister(rsp));
CHECK(!Operand(rsp, offset).AddressUsesRegister(rax));
- CHECK(!Operand(rsp, offset).AddressUsesRegister(r12));
+ CHECK(!Operand(rsp, offset).AddressUsesRegister(r15));
CHECK(Operand(rbp, offset).AddressUsesRegister(rbp));
CHECK(!Operand(rbp, offset).AddressUsesRegister(rax));
@@ -333,7 +340,7 @@ TEST(OperandRegisterDependency) {
CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rsp));
CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rbp));
CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rax));
- CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r12));
+ CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r15));
CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r13));
}
}
diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc
index 9c292bcfc..d1e537d9d 100644
--- a/deps/v8/test/cctest/test-ast.cc
+++ b/deps/v8/test/cctest/test-ast.cc
@@ -35,10 +35,11 @@
using namespace v8::internal;
TEST(List) {
+ v8::internal::V8::Initialize(NULL);
List<AstNode*>* list = new List<AstNode*>(0);
CHECK_EQ(0, list->length());
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
AstNode* node = new EmptyStatement();
list->Add(node);
CHECK_EQ(1, list->length());
diff --git a/deps/v8/test/cctest/test-circular-queue.cc b/deps/v8/test/cctest/test-circular-queue.cc
index ce9a42e81..c4e5c4c24 100644
--- a/deps/v8/test/cctest/test-circular-queue.cc
+++ b/deps/v8/test/cctest/test-circular-queue.cc
@@ -88,7 +88,8 @@ class ProducerThread: public i::Thread {
int records_per_chunk,
Record value,
i::Semaphore* finished)
- : scq_(scq),
+ : Thread("producer"),
+ scq_(scq),
records_per_chunk_(records_per_chunk),
value_(value),
finished_(finished) { }
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index 9f21b78dd..4c5f197bc 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -31,10 +31,11 @@
#include "v8.h"
#include "compiler.h"
+#include "disasm.h"
+#include "disassembler.h"
#include "execution.h"
#include "factory.h"
#include "platform.h"
-#include "top.h"
#include "cctest.h"
using namespace v8::internal;
@@ -99,21 +100,21 @@ static void InitializeVM() {
static MaybeObject* GetGlobalProperty(const char* name) {
- Handle<String> symbol = Factory::LookupAsciiSymbol(name);
- return Top::context()->global()->GetProperty(*symbol);
+ Handle<String> symbol = FACTORY->LookupAsciiSymbol(name);
+ return Isolate::Current()->context()->global()->GetProperty(*symbol);
}
static void SetGlobalProperty(const char* name, Object* value) {
Handle<Object> object(value);
- Handle<String> symbol = Factory::LookupAsciiSymbol(name);
- Handle<JSObject> global(Top::context()->global());
+ Handle<String> symbol = FACTORY->LookupAsciiSymbol(name);
+ Handle<JSObject> global(Isolate::Current()->context()->global());
SetProperty(global, symbol, object, NONE, kNonStrictMode);
}
static Handle<JSFunction> Compile(const char* source) {
- Handle<String> source_code(Factory::NewStringFromUtf8(CStrVector(source)));
+ Handle<String> source_code(FACTORY->NewStringFromUtf8(CStrVector(source)));
Handle<SharedFunctionInfo> shared_function =
Compiler::Compile(source_code,
Handle<String>(),
@@ -123,8 +124,8 @@ static Handle<JSFunction> Compile(const char* source) {
NULL,
Handle<String>::null(),
NOT_NATIVES_CODE);
- return Factory::NewFunctionFromSharedFunctionInfo(shared_function,
- Top::global_context());
+ return FACTORY->NewFunctionFromSharedFunctionInfo(shared_function,
+ Isolate::Current()->global_context());
}
@@ -137,7 +138,7 @@ static double Inc(int x) {
if (fun.is_null()) return -1;
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -158,7 +159,7 @@ static double Add(int x, int y) {
SetGlobalProperty("x", Smi::FromInt(x));
SetGlobalProperty("y", Smi::FromInt(y));
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -178,7 +179,7 @@ static double Abs(int x) {
SetGlobalProperty("x", Smi::FromInt(x));
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -199,7 +200,7 @@ static double Sum(int n) {
SetGlobalProperty("n", Smi::FromInt(n));
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
@@ -220,7 +221,7 @@ TEST(Print) {
Handle<JSFunction> fun = Compile(source);
if (fun.is_null()) return;
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
}
@@ -253,7 +254,7 @@ TEST(Stuff) {
Handle<JSFunction> fun = Compile(source);
CHECK(!fun.is_null());
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
CHECK_EQ(511.0, GetGlobalProperty("r")->ToObjectChecked()->Number());
@@ -268,11 +269,12 @@ TEST(UncaughtThrow) {
Handle<JSFunction> fun = Compile(source);
CHECK(!fun.is_null());
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Handle<Object> result =
Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(has_pending_exception);
- CHECK_EQ(42.0, Top::pending_exception()->ToObjectChecked()->Number());
+ CHECK_EQ(42.0, Isolate::Current()->pending_exception()->
+ ToObjectChecked()->Number());
}
@@ -293,18 +295,18 @@ TEST(C2JSFrames) {
// Run the generated code to populate the global object with 'foo'.
bool has_pending_exception;
- Handle<JSObject> global(Top::context()->global());
+ Handle<JSObject> global(Isolate::Current()->context()->global());
Execution::Call(fun0, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
- Object* foo_symbol = Factory::LookupAsciiSymbol("foo")->ToObjectChecked();
- MaybeObject* fun1_object =
- Top::context()->global()->GetProperty(String::cast(foo_symbol));
+ Object* foo_symbol = FACTORY->LookupAsciiSymbol("foo")->ToObjectChecked();
+ MaybeObject* fun1_object = Isolate::Current()->context()->global()->
+ GetProperty(String::cast(foo_symbol));
Handle<Object> fun1(fun1_object->ToObjectChecked());
CHECK(fun1->IsJSFunction());
Object** argv[1] = {
- Handle<Object>::cast(Factory::LookupAsciiSymbol("hello")).location()
+ Handle<Object>::cast(FACTORY->LookupAsciiSymbol("hello")).location()
};
Execution::Call(Handle<JSFunction>::cast(fun1), global, 1, argv,
&has_pending_exception);
@@ -318,8 +320,8 @@ TEST(Regression236) {
InitializeVM();
v8::HandleScope scope;
- Handle<Script> script = Factory::NewScript(Factory::empty_string());
- script->set_source(Heap::undefined_value());
+ Handle<Script> script = FACTORY->NewScript(FACTORY->empty_string());
+ script->set_source(HEAP->undefined_value());
CHECK_EQ(-1, GetScriptLineNumber(script, 0));
CHECK_EQ(-1, GetScriptLineNumber(script, 100));
CHECK_EQ(-1, GetScriptLineNumber(script, -1));
@@ -348,3 +350,51 @@ TEST(GetScriptLineNumber) {
CHECK_EQ(i, f->GetScriptLineNumber());
}
}
+
+
+#ifdef ENABLE_DISASSEMBLER
+static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
+ const char* property_name) {
+ v8::Local<v8::Function> fun =
+ v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name)));
+ return v8::Utils::OpenHandle(*fun);
+}
+
+
+static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
+ // Create a disassembler with default name lookup.
+ disasm::NameConverter name_converter;
+ disasm::Disassembler d(name_converter);
+
+ if (f->code()->kind() == Code::FUNCTION) {
+ Address pc = f->code()->instruction_start();
+ int decode_size =
+ Min(f->code()->instruction_size(),
+ static_cast<int>(f->code()->stack_check_table_offset()));
+ Address end = pc + decode_size;
+
+ v8::internal::EmbeddedVector<char, 128> decode_buffer;
+ while (pc < end) {
+ pc += d.InstructionDecode(decode_buffer, pc);
+ CHECK(strstr(decode_buffer.start(), "mov eax,0x178c29c") == NULL);
+ CHECK(strstr(decode_buffer.start(), "push 0x178c29c") == NULL);
+ CHECK(strstr(decode_buffer.start(), "0x178c29c") == NULL);
+ }
+ }
+}
+
+
+TEST(SplitConstantsInFullCompiler) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun("function f() { a = 12345678 }; f();");
+ CheckCodeForUnsafeLiteral(GetJSFunction(env->Global(), "f"));
+ CompileRun("function f(x) { a = 12345678 + x}; f(1);");
+ CheckCodeForUnsafeLiteral(GetJSFunction(env->Global(), "f"));
+ CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);");
+ CheckCodeForUnsafeLiteral(GetJSFunction(env->Global(), "f"));
+ CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);");
+ CheckCodeForUnsafeLiteral(GetJSFunction(env->Global(), "f"));
+}
+#endif
diff --git a/deps/v8/test/cctest/test-conversions.cc b/deps/v8/test/cctest/test-conversions.cc
index 1b5cc2dee..7c29746fc 100644
--- a/deps/v8/test/cctest/test-conversions.cc
+++ b/deps/v8/test/cctest/test-conversions.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
#include <stdlib.h>
@@ -11,139 +11,151 @@ using namespace v8::internal;
TEST(Hex) {
- CHECK_EQ(0.0, StringToDouble("0x0", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("0X0", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(1.0, StringToDouble("0x1", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(16.0, StringToDouble("0x10", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(255.0, StringToDouble("0xff", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(175.0, StringToDouble("0xAF", ALLOW_HEX | ALLOW_OCTALS));
-
- CHECK_EQ(0.0, StringToDouble("0x0", ALLOW_HEX));
- CHECK_EQ(0.0, StringToDouble("0X0", ALLOW_HEX));
- CHECK_EQ(1.0, StringToDouble("0x1", ALLOW_HEX));
- CHECK_EQ(16.0, StringToDouble("0x10", ALLOW_HEX));
- CHECK_EQ(255.0, StringToDouble("0xff", ALLOW_HEX));
- CHECK_EQ(175.0, StringToDouble("0xAF", ALLOW_HEX));
+ UnicodeCache uc;
+ CHECK_EQ(0.0, StringToDouble(&uc, "0x0", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0X0", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(1.0, StringToDouble(&uc, "0x1", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(16.0, StringToDouble(&uc, "0x10", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(255.0, StringToDouble(&uc, "0xff", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(175.0, StringToDouble(&uc, "0xAF", ALLOW_HEX | ALLOW_OCTALS));
+
+ CHECK_EQ(0.0, StringToDouble(&uc, "0x0", ALLOW_HEX));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0X0", ALLOW_HEX));
+ CHECK_EQ(1.0, StringToDouble(&uc, "0x1", ALLOW_HEX));
+ CHECK_EQ(16.0, StringToDouble(&uc, "0x10", ALLOW_HEX));
+ CHECK_EQ(255.0, StringToDouble(&uc, "0xff", ALLOW_HEX));
+ CHECK_EQ(175.0, StringToDouble(&uc, "0xAF", ALLOW_HEX));
}
TEST(Octal) {
- CHECK_EQ(0.0, StringToDouble("0", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("00", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(1.0, StringToDouble("01", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(7.0, StringToDouble("07", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(8.0, StringToDouble("010", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(63.0, StringToDouble("077", ALLOW_HEX | ALLOW_OCTALS));
-
- CHECK_EQ(0.0, StringToDouble("0", ALLOW_HEX));
- CHECK_EQ(0.0, StringToDouble("00", ALLOW_HEX));
- CHECK_EQ(1.0, StringToDouble("01", ALLOW_HEX));
- CHECK_EQ(7.0, StringToDouble("07", ALLOW_HEX));
- CHECK_EQ(10.0, StringToDouble("010", ALLOW_HEX));
- CHECK_EQ(77.0, StringToDouble("077", ALLOW_HEX));
+ UnicodeCache uc;
+ CHECK_EQ(0.0, StringToDouble(&uc, "0", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "00", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(1.0, StringToDouble(&uc, "01", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(7.0, StringToDouble(&uc, "07", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(8.0, StringToDouble(&uc, "010", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(63.0, StringToDouble(&uc, "077", ALLOW_HEX | ALLOW_OCTALS));
+
+ CHECK_EQ(0.0, StringToDouble(&uc, "0", ALLOW_HEX));
+ CHECK_EQ(0.0, StringToDouble(&uc, "00", ALLOW_HEX));
+ CHECK_EQ(1.0, StringToDouble(&uc, "01", ALLOW_HEX));
+ CHECK_EQ(7.0, StringToDouble(&uc, "07", ALLOW_HEX));
+ CHECK_EQ(10.0, StringToDouble(&uc, "010", ALLOW_HEX));
+ CHECK_EQ(77.0, StringToDouble(&uc, "077", ALLOW_HEX));
const double x = 010000000000; // Power of 2, no rounding errors.
- CHECK_EQ(x * x * x * x * x, StringToDouble("01" "0000000000" "0000000000"
+ CHECK_EQ(x * x * x * x * x, StringToDouble(&uc, "01" "0000000000" "0000000000"
"0000000000" "0000000000" "0000000000", ALLOW_OCTALS));
}
TEST(MalformedOctal) {
- CHECK_EQ(8.0, StringToDouble("08", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(81.0, StringToDouble("081", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(78.0, StringToDouble("078", ALLOW_HEX | ALLOW_OCTALS));
+ UnicodeCache uc;
+ CHECK_EQ(8.0, StringToDouble(&uc, "08", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(81.0, StringToDouble(&uc, "081", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(78.0, StringToDouble(&uc, "078", ALLOW_HEX | ALLOW_OCTALS));
- CHECK(isnan(StringToDouble("07.7", ALLOW_HEX | ALLOW_OCTALS)));
- CHECK(isnan(StringToDouble("07.8", ALLOW_HEX | ALLOW_OCTALS)));
- CHECK(isnan(StringToDouble("07e8", ALLOW_HEX | ALLOW_OCTALS)));
- CHECK(isnan(StringToDouble("07e7", ALLOW_HEX | ALLOW_OCTALS)));
+ CHECK(isnan(StringToDouble(&uc, "07.7", ALLOW_HEX | ALLOW_OCTALS)));
+ CHECK(isnan(StringToDouble(&uc, "07.8", ALLOW_HEX | ALLOW_OCTALS)));
+ CHECK(isnan(StringToDouble(&uc, "07e8", ALLOW_HEX | ALLOW_OCTALS)));
+ CHECK(isnan(StringToDouble(&uc, "07e7", ALLOW_HEX | ALLOW_OCTALS)));
- CHECK_EQ(8.7, StringToDouble("08.7", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(8e7, StringToDouble("08e7", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(8.7, StringToDouble(&uc, "08.7", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(8e7, StringToDouble(&uc, "08e7", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.001, StringToDouble("0.001", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.713, StringToDouble("0.713", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.001, StringToDouble(&uc, "0.001", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.713, StringToDouble(&uc, "0.713", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(8.0, StringToDouble("08", ALLOW_HEX));
- CHECK_EQ(81.0, StringToDouble("081", ALLOW_HEX));
- CHECK_EQ(78.0, StringToDouble("078", ALLOW_HEX));
+ CHECK_EQ(8.0, StringToDouble(&uc, "08", ALLOW_HEX));
+ CHECK_EQ(81.0, StringToDouble(&uc, "081", ALLOW_HEX));
+ CHECK_EQ(78.0, StringToDouble(&uc, "078", ALLOW_HEX));
- CHECK_EQ(7.7, StringToDouble("07.7", ALLOW_HEX));
- CHECK_EQ(7.8, StringToDouble("07.8", ALLOW_HEX));
- CHECK_EQ(7e8, StringToDouble("07e8", ALLOW_HEX));
- CHECK_EQ(7e7, StringToDouble("07e7", ALLOW_HEX));
+ CHECK_EQ(7.7, StringToDouble(&uc, "07.7", ALLOW_HEX));
+ CHECK_EQ(7.8, StringToDouble(&uc, "07.8", ALLOW_HEX));
+ CHECK_EQ(7e8, StringToDouble(&uc, "07e8", ALLOW_HEX));
+ CHECK_EQ(7e7, StringToDouble(&uc, "07e7", ALLOW_HEX));
- CHECK_EQ(8.7, StringToDouble("08.7", ALLOW_HEX));
- CHECK_EQ(8e7, StringToDouble("08e7", ALLOW_HEX));
+ CHECK_EQ(8.7, StringToDouble(&uc, "08.7", ALLOW_HEX));
+ CHECK_EQ(8e7, StringToDouble(&uc, "08e7", ALLOW_HEX));
- CHECK_EQ(0.001, StringToDouble("0.001", ALLOW_HEX));
- CHECK_EQ(0.713, StringToDouble("0.713", ALLOW_HEX));
+ CHECK_EQ(0.001, StringToDouble(&uc, "0.001", ALLOW_HEX));
+ CHECK_EQ(0.713, StringToDouble(&uc, "0.713", ALLOW_HEX));
}
TEST(TrailingJunk) {
- CHECK_EQ(8.0, StringToDouble("8q", ALLOW_TRAILING_JUNK));
- CHECK_EQ(63.0, StringToDouble("077qqq", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
- CHECK_EQ(10.0, StringToDouble("10e", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
- CHECK_EQ(10.0, StringToDouble("10e-", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+ UnicodeCache uc;
+ CHECK_EQ(8.0, StringToDouble(&uc, "8q", ALLOW_TRAILING_JUNK));
+ CHECK_EQ(63.0,
+ StringToDouble(&uc, "077qqq", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+ CHECK_EQ(10.0,
+ StringToDouble(&uc, "10e", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+ CHECK_EQ(10.0,
+ StringToDouble(&uc, "10e-", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
}
TEST(NonStrDecimalLiteral) {
- CHECK(isnan(StringToDouble(" ", NO_FLAGS, OS::nan_value())));
- CHECK(isnan(StringToDouble("", NO_FLAGS, OS::nan_value())));
- CHECK(isnan(StringToDouble(" ", NO_FLAGS, OS::nan_value())));
- CHECK_EQ(0.0, StringToDouble("", NO_FLAGS));
- CHECK_EQ(0.0, StringToDouble(" ", NO_FLAGS));
+ UnicodeCache uc;
+ CHECK(isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value())));
+ CHECK(isnan(StringToDouble(&uc, "", NO_FLAGS, OS::nan_value())));
+ CHECK(isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value())));
+ CHECK_EQ(0.0, StringToDouble(&uc, "", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble(&uc, " ", NO_FLAGS));
}
TEST(IntegerStrLiteral) {
- CHECK_EQ(0.0, StringToDouble("0.0", NO_FLAGS));
- CHECK_EQ(0.0, StringToDouble("0", NO_FLAGS));
- CHECK_EQ(0.0, StringToDouble("00", NO_FLAGS));
- CHECK_EQ(0.0, StringToDouble("000", NO_FLAGS));
- CHECK_EQ(1.0, StringToDouble("1", NO_FLAGS));
- CHECK_EQ(-1.0, StringToDouble("-1", NO_FLAGS));
- CHECK_EQ(-1.0, StringToDouble(" -1 ", NO_FLAGS));
- CHECK_EQ(1.0, StringToDouble(" +1 ", NO_FLAGS));
- CHECK(isnan(StringToDouble(" - 1 ", NO_FLAGS)));
- CHECK(isnan(StringToDouble(" + 1 ", NO_FLAGS)));
-
- CHECK_EQ(0.0, StringToDouble("0e0", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("0e1", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("0e-1", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("0e-100000", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("0e+100000", ALLOW_HEX | ALLOW_OCTALS));
- CHECK_EQ(0.0, StringToDouble("0.", ALLOW_HEX | ALLOW_OCTALS));
+ UnicodeCache uc;
+ CHECK_EQ(0.0, StringToDouble(&uc, "0.0", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "00", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "000", NO_FLAGS));
+ CHECK_EQ(1.0, StringToDouble(&uc, "1", NO_FLAGS));
+ CHECK_EQ(-1.0, StringToDouble(&uc, "-1", NO_FLAGS));
+ CHECK_EQ(-1.0, StringToDouble(&uc, " -1 ", NO_FLAGS));
+ CHECK_EQ(1.0, StringToDouble(&uc, " +1 ", NO_FLAGS));
+ CHECK(isnan(StringToDouble(&uc, " - 1 ", NO_FLAGS)));
+ CHECK(isnan(StringToDouble(&uc, " + 1 ", NO_FLAGS)));
+
+ CHECK_EQ(0.0, StringToDouble(&uc, "0e0", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0e1", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0e-1", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0e-100000", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0e+100000", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble(&uc, "0.", ALLOW_HEX | ALLOW_OCTALS));
}
TEST(LongNumberStr) {
- CHECK_EQ(1e10, StringToDouble("1" "0000000000", NO_FLAGS));
- CHECK_EQ(1e20, StringToDouble("1" "0000000000" "0000000000", NO_FLAGS));
+ UnicodeCache uc;
+ CHECK_EQ(1e10, StringToDouble(&uc, "1" "0000000000", NO_FLAGS));
+ CHECK_EQ(1e20, StringToDouble(&uc, "1" "0000000000" "0000000000", NO_FLAGS));
- CHECK_EQ(1e60, StringToDouble("1" "0000000000" "0000000000" "0000000000"
+ CHECK_EQ(1e60, StringToDouble(&uc, "1" "0000000000" "0000000000" "0000000000"
"0000000000" "0000000000" "0000000000", NO_FLAGS));
- CHECK_EQ(1e-2, StringToDouble("." "0" "1", NO_FLAGS));
- CHECK_EQ(1e-11, StringToDouble("." "0000000000" "1", NO_FLAGS));
- CHECK_EQ(1e-21, StringToDouble("." "0000000000" "0000000000" "1", NO_FLAGS));
+ CHECK_EQ(1e-2, StringToDouble(&uc, "." "0" "1", NO_FLAGS));
+ CHECK_EQ(1e-11, StringToDouble(&uc, "." "0000000000" "1", NO_FLAGS));
+ CHECK_EQ(1e-21, StringToDouble(&uc, "." "0000000000" "0000000000" "1",
+ NO_FLAGS));
- CHECK_EQ(1e-61, StringToDouble("." "0000000000" "0000000000" "0000000000"
+ CHECK_EQ(1e-61, StringToDouble(&uc, "." "0000000000" "0000000000" "0000000000"
"0000000000" "0000000000" "0000000000" "1", NO_FLAGS));
// x = 24414062505131248.0 and y = 24414062505131252.0 are representable in
// double. Check chat z = (x + y) / 2 is rounded to x...
CHECK_EQ(24414062505131248.0,
- StringToDouble("24414062505131250.0", NO_FLAGS));
+ StringToDouble(&uc, "24414062505131250.0", NO_FLAGS));
// ... and z = (x + y) / 2 + delta is rounded to y.
CHECK_EQ(24414062505131252.0,
- StringToDouble("24414062505131250.000000001", NO_FLAGS));
+ StringToDouble(&uc, "24414062505131250.000000001", NO_FLAGS));
}
TEST(MaximumSignificantDigits) {
+ UnicodeCache uc;
char num[] =
"4.4501477170144020250819966727949918635852426585926051135169509"
"122872622312493126406953054127118942431783801370080830523154578"
@@ -159,15 +171,16 @@ TEST(MaximumSignificantDigits) {
"847003580761626016356864581135848683152156368691976240370422601"
"6998291015625000000000000000000000000000000000e-308";
- CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(num, NO_FLAGS));
+ CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(&uc, num, NO_FLAGS));
// Changes the result of strtod (at least in glibc implementation).
num[sizeof(num) - 8] = '1';
- CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(num, NO_FLAGS));
+ CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(&uc, num, NO_FLAGS));
}
TEST(MinimumExponent) {
+ UnicodeCache uc;
// Same test but with different point-position.
char num[] =
"445014771701440202508199667279499186358524265859260511351695091"
@@ -184,29 +197,31 @@ TEST(MinimumExponent) {
"470035807616260163568645811358486831521563686919762403704226016"
"998291015625000000000000000000000000000000000e-1108";
- CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(num, NO_FLAGS));
+ CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(&uc, num, NO_FLAGS));
// Changes the result of strtod (at least in glibc implementation).
num[sizeof(num) - 8] = '1';
- CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(num, NO_FLAGS));
+ CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(&uc, num, NO_FLAGS));
}
TEST(MaximumExponent) {
+ UnicodeCache uc;
char num[] = "0.16e309";
- CHECK_EQ(1.59999999999999997765e+308, StringToDouble(num, NO_FLAGS));
+ CHECK_EQ(1.59999999999999997765e+308, StringToDouble(&uc, num, NO_FLAGS));
}
TEST(ExponentNumberStr) {
- CHECK_EQ(1e1, StringToDouble("1e1", NO_FLAGS));
- CHECK_EQ(1e1, StringToDouble("1e+1", NO_FLAGS));
- CHECK_EQ(1e-1, StringToDouble("1e-1", NO_FLAGS));
- CHECK_EQ(1e100, StringToDouble("1e+100", NO_FLAGS));
- CHECK_EQ(1e-100, StringToDouble("1e-100", NO_FLAGS));
- CHECK_EQ(1e-106, StringToDouble(".000001e-100", NO_FLAGS));
+ UnicodeCache uc;
+ CHECK_EQ(1e1, StringToDouble(&uc, "1e1", NO_FLAGS));
+ CHECK_EQ(1e1, StringToDouble(&uc, "1e+1", NO_FLAGS));
+ CHECK_EQ(1e-1, StringToDouble(&uc, "1e-1", NO_FLAGS));
+ CHECK_EQ(1e100, StringToDouble(&uc, "1e+100", NO_FLAGS));
+ CHECK_EQ(1e-100, StringToDouble(&uc, "1e-100", NO_FLAGS));
+ CHECK_EQ(1e-106, StringToDouble(&uc, ".000001e-100", NO_FLAGS));
}
class OneBit1: public BitField<uint32_t, 0, 1> {};
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index 7f06bc34d..7d898cedb 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -7,6 +7,7 @@
#include "v8.h"
#include "cpu-profiler-inl.h"
#include "cctest.h"
+#include "../include/v8-profiler.h"
namespace i = v8::internal;
@@ -25,9 +26,6 @@ TEST(StartStop) {
ProfileGenerator generator(&profiles);
ProfilerEventsProcessor processor(&generator);
processor.Start();
- while (!processor.running()) {
- i::Thread::YieldCPU();
- }
processor.Stop();
processor.Join();
}
@@ -89,18 +87,15 @@ TEST(CodeEvents) {
ProfileGenerator generator(&profiles);
ProfilerEventsProcessor processor(&generator);
processor.Start();
- while (!processor.running()) {
- i::Thread::YieldCPU();
- }
// Enqueue code creation events.
i::HandleScope scope;
const char* aaa_str = "aaa";
- i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
+ i::Handle<i::String> aaa_name = FACTORY->NewStringFromAscii(
i::Vector<const char>(aaa_str, i::StrLength(aaa_str)));
processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
*aaa_name,
- i::Heap::empty_string(),
+ HEAP->empty_string(),
0,
ToAddress(0x1000),
0x100,
@@ -153,9 +148,6 @@ TEST(TickEvents) {
ProfileGenerator generator(&profiles);
ProfilerEventsProcessor processor(&generator);
processor.Start();
- while (!processor.running()) {
- i::Thread::YieldCPU();
- }
processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
"bbb",
@@ -236,4 +228,178 @@ TEST(CrashIfStoppingLastNonExistentProfile) {
CpuProfiler::TearDown();
}
+
+// http://code.google.com/p/v8/issues/detail?id=1398
+// Long stacks (exceeding max frames limit) must not be erased.
+TEST(Issue1398) {
+ TestSetup test_setup;
+ CpuProfilesCollection profiles;
+ profiles.StartProfiling("", 1);
+ ProfileGenerator generator(&profiles);
+ ProfilerEventsProcessor processor(&generator);
+ processor.Start();
+
+ processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
+ "bbb",
+ ToAddress(0x1200),
+ 0x80);
+
+ i::TickSample* sample = processor.TickSampleEvent();
+ sample->pc = ToAddress(0x1200);
+ sample->tos = 0;
+ sample->frames_count = i::TickSample::kMaxFramesCount;
+ for (int i = 0; i < sample->frames_count; ++i) {
+ sample->stack[i] = ToAddress(0x1200);
+ }
+
+ processor.Stop();
+ processor.Join();
+ CpuProfile* profile =
+ profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
+ CHECK_NE(NULL, profile);
+
+ int actual_depth = 0;
+ const ProfileNode* node = profile->top_down()->root();
+ while (node->children()->length() > 0) {
+ node = node->children()->last();
+ ++actual_depth;
+ }
+
+ CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC.
+}
+
+
+TEST(DeleteAllCpuProfiles) {
+ InitializeVM();
+ TestSetup test_setup;
+ CpuProfiler::Setup();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CpuProfiler::DeleteAllProfiles();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+
+ CpuProfiler::StartProfiling("1");
+ CpuProfiler::StopProfiling("1");
+ CHECK_EQ(1, CpuProfiler::GetProfilesCount());
+ CpuProfiler::DeleteAllProfiles();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CpuProfiler::StartProfiling("1");
+ CpuProfiler::StartProfiling("2");
+ CpuProfiler::StopProfiling("2");
+ CpuProfiler::StopProfiling("1");
+ CHECK_EQ(2, CpuProfiler::GetProfilesCount());
+ CpuProfiler::DeleteAllProfiles();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+
+ // Test profiling cancellation by the 'delete' command.
+ CpuProfiler::StartProfiling("1");
+ CpuProfiler::StartProfiling("2");
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CpuProfiler::DeleteAllProfiles();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+
+ CpuProfiler::TearDown();
+}
+
+
+TEST(DeleteCpuProfile) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CHECK_EQ(0, v8::CpuProfiler::GetProfilesCount());
+ v8::Local<v8::String> name1 = v8::String::New("1");
+ v8::CpuProfiler::StartProfiling(name1);
+ const v8::CpuProfile* p1 = v8::CpuProfiler::StopProfiling(name1);
+ CHECK_NE(NULL, p1);
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ unsigned uid1 = p1->GetUid();
+ CHECK_EQ(p1, v8::CpuProfiler::FindProfile(uid1));
+ const_cast<v8::CpuProfile*>(p1)->Delete();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
+
+ v8::Local<v8::String> name2 = v8::String::New("2");
+ v8::CpuProfiler::StartProfiling(name2);
+ const v8::CpuProfile* p2 = v8::CpuProfiler::StopProfiling(name2);
+ CHECK_NE(NULL, p2);
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ unsigned uid2 = p2->GetUid();
+ CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2));
+ CHECK_EQ(p2, v8::CpuProfiler::FindProfile(uid2));
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
+ v8::Local<v8::String> name3 = v8::String::New("3");
+ v8::CpuProfiler::StartProfiling(name3);
+ const v8::CpuProfile* p3 = v8::CpuProfiler::StopProfiling(name3);
+ CHECK_NE(NULL, p3);
+ CHECK_EQ(2, v8::CpuProfiler::GetProfilesCount());
+ unsigned uid3 = p3->GetUid();
+ CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3));
+ CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
+ const_cast<v8::CpuProfile*>(p2)->Delete();
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
+ CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
+ const_cast<v8::CpuProfile*>(p3)->Delete();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3));
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
+}
+
+
+TEST(DeleteCpuProfileDifferentTokens) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CHECK_EQ(0, v8::CpuProfiler::GetProfilesCount());
+ v8::Local<v8::String> name1 = v8::String::New("1");
+ v8::CpuProfiler::StartProfiling(name1);
+ const v8::CpuProfile* p1 = v8::CpuProfiler::StopProfiling(name1);
+ CHECK_NE(NULL, p1);
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ unsigned uid1 = p1->GetUid();
+ CHECK_EQ(p1, v8::CpuProfiler::FindProfile(uid1));
+ v8::Local<v8::String> token1 = v8::String::New("token1");
+ const v8::CpuProfile* p1_t1 = v8::CpuProfiler::FindProfile(uid1, token1);
+ CHECK_NE(NULL, p1_t1);
+ CHECK_NE(p1, p1_t1);
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ const_cast<v8::CpuProfile*>(p1)->Delete();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1, token1));
+ const_cast<v8::CpuProfile*>(p1_t1)->Delete();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+
+ v8::Local<v8::String> name2 = v8::String::New("2");
+ v8::CpuProfiler::StartProfiling(name2);
+ v8::Local<v8::String> token2 = v8::String::New("token2");
+ const v8::CpuProfile* p2_t2 = v8::CpuProfiler::StopProfiling(name2, token2);
+ CHECK_NE(NULL, p2_t2);
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ unsigned uid2 = p2_t2->GetUid();
+ CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2));
+ const v8::CpuProfile* p2 = v8::CpuProfiler::FindProfile(uid2);
+ CHECK_NE(p2_t2, p2);
+ v8::Local<v8::String> name3 = v8::String::New("3");
+ v8::CpuProfiler::StartProfiling(name3);
+ const v8::CpuProfile* p3 = v8::CpuProfiler::StopProfiling(name3);
+ CHECK_NE(NULL, p3);
+ CHECK_EQ(2, v8::CpuProfiler::GetProfilesCount());
+ unsigned uid3 = p3->GetUid();
+ CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3));
+ CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
+ const_cast<v8::CpuProfile*>(p2_t2)->Delete();
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
+ CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
+ const_cast<v8::CpuProfile*>(p2)->Delete();
+ CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
+ CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
+ const_cast<v8::CpuProfile*>(p3)->Delete();
+ CHECK_EQ(0, CpuProfiler::GetProfilesCount());
+ CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3));
+}
+
#endif // ENABLE_LOGGING_AND_PROFILING
diff --git a/deps/v8/test/cctest/test-dataflow.cc b/deps/v8/test/cctest/test-dataflow.cc
index 5894de2a8..ad48f5503 100644
--- a/deps/v8/test/cctest/test-dataflow.cc
+++ b/deps/v8/test/cctest/test-dataflow.cc
@@ -35,7 +35,8 @@
using namespace v8::internal;
TEST(BitVector) {
- ZoneScope zone(DELETE_ON_EXIT);
+ v8::internal::V8::Initialize(NULL);
+ ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
{
BitVector v(15);
v.Add(1);
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 7245e54be..4886a8a07 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// 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:
@@ -143,17 +143,18 @@ class DebugLocalContext {
inline v8::Context* operator*() { return *context_; }
inline bool IsReady() { return !context_.IsEmpty(); }
void ExposeDebug() {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// Expose the debug context global object in the global object for testing.
- Debug::Load();
- Debug::debug_context()->set_security_token(
+ debug->Load();
+ debug->debug_context()->set_security_token(
v8::Utils::OpenHandle(*context_)->security_token());
Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
v8::Utils::OpenHandle(*context_->Global())));
Handle<v8::internal::String> debug_string =
- v8::internal::Factory::LookupAsciiSymbol("debug");
+ FACTORY->LookupAsciiSymbol("debug");
SetProperty(global, debug_string,
- Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM,
+ Handle<Object>(debug->debug_context()->global_proxy()), DONT_ENUM,
::v8::internal::kNonStrictMode);
}
private:
@@ -196,7 +197,8 @@ static bool HasDebugInfo(v8::Handle<v8::Function> fun) {
static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) {
static int break_point = 0;
Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
- Debug::SetBreakPoint(
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
+ debug->SetBreakPoint(
shared,
Handle<Object>(v8::internal::Smi::FromInt(++break_point)),
&position);
@@ -279,7 +281,8 @@ static int SetScriptBreakPointByNameFromJS(const char* script_name,
// Clear a break point.
static void ClearBreakPoint(int break_point) {
- Debug::ClearBreakPoint(
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
+ debug->ClearBreakPoint(
Handle<Object>(v8::internal::Smi::FromInt(break_point)));
}
@@ -339,8 +342,9 @@ static void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number,
// Change break on exception.
static void ChangeBreakOnException(bool caught, bool uncaught) {
- Debug::ChangeBreakOnException(v8::internal::BreakException, caught);
- Debug::ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
+ debug->ChangeBreakOnException(v8::internal::BreakException, caught);
+ debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);
}
@@ -365,7 +369,8 @@ static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) {
// Prepare to step to next break location.
static void PrepareStep(StepAction step_action) {
- Debug::PrepareStep(step_action, 1);
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
+ debug->PrepareStep(step_action, 1);
}
@@ -376,7 +381,9 @@ namespace internal {
// Collect the currently debugged functions.
Handle<FixedArray> GetDebuggedFunctions() {
- v8::internal::DebugInfoListNode* node = Debug::debug_info_list_;
+ Debug* debug = Isolate::Current()->debug();
+
+ v8::internal::DebugInfoListNode* node = debug->debug_info_list_;
// Find the number of debugged functions.
int count = 0;
@@ -387,7 +394,7 @@ Handle<FixedArray> GetDebuggedFunctions() {
// Allocate array for the debugged functions
Handle<FixedArray> debugged_functions =
- v8::internal::Factory::NewFixedArray(count);
+ FACTORY->NewFixedArray(count);
// Run through the debug info objects and collect all functions.
count = 0;
@@ -402,7 +409,9 @@ Handle<FixedArray> GetDebuggedFunctions() {
static Handle<Code> ComputeCallDebugBreak(int argc) {
CALL_HEAP_FUNCTION(
- v8::internal::StubCache::ComputeCallDebugBreak(argc, Code::CALL_IC),
+ v8::internal::Isolate::Current(),
+ v8::internal::Isolate::Current()->stub_cache()->ComputeCallDebugBreak(
+ argc, Code::CALL_IC),
Code);
}
@@ -411,12 +420,12 @@ 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(Debug::debug_context().is_null());
- CHECK_EQ(NULL, Debug::debug_info_list_);
+ CHECK(Isolate::Current()->debug()->debug_context().is_null());
+ CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_);
// Collect garbage to ensure weak handles are cleared.
- Heap::CollectAllGarbage(false);
- Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
// Iterate the head and check that there are no debugger related objects left.
HeapIterator iterator;
@@ -444,8 +453,8 @@ void CheckDebuggerUnloaded(bool check_functions) {
void ForceUnloadDebugger() {
- Debugger::never_unload_debugger_ = false;
- Debugger::UnloadDebugger();
+ Isolate::Current()->debugger()->never_unload_debugger_ = false;
+ Isolate::Current()->debugger()->UnloadDebugger();
}
@@ -480,6 +489,8 @@ 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();
+
// Create function and set the break point.
Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle(
*CompileFunction(env, source, name));
@@ -490,7 +501,11 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
CHECK(Debug::HasDebugInfo(shared));
TestBreakLocationIterator it1(Debug::GetDebugInfo(shared));
it1.FindBreakLocationFromPosition(position);
- CHECK_EQ(mode, it1.it()->rinfo()->rmode());
+ v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode();
+ if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
+ actual_mode = v8::internal::RelocInfo::CODE_TARGET;
+ }
+ CHECK_EQ(mode, actual_mode);
if (mode != v8::internal::RelocInfo::JS_RETURN) {
CHECK_EQ(debug_break,
Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address()));
@@ -501,11 +516,15 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
// Clear the break point and check that the debug break function is no longer
// there
ClearBreakPoint(bp);
- CHECK(!Debug::HasDebugInfo(shared));
- CHECK(Debug::EnsureDebugInfo(shared));
+ CHECK(!debug->HasDebugInfo(shared));
+ CHECK(debug->EnsureDebugInfo(shared));
TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
it2.FindBreakLocationFromPosition(position);
- CHECK_EQ(mode, it2.it()->rinfo()->rmode());
+ actual_mode = it2.it()->rinfo()->rmode();
+ if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
+ actual_mode = v8::internal::RelocInfo::CODE_TARGET;
+ }
+ CHECK_EQ(mode, actual_mode);
if (mode == v8::internal::RelocInfo::JS_RETURN) {
CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo()));
}
@@ -634,8 +653,9 @@ static void DebugEventBreakPointHitCount(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
// Count the number of breaks.
if (event == v8::Break) {
@@ -738,8 +758,10 @@ static void DebugEventCounter(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
+
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
// Count the number of breaks.
if (event == v8::Break) {
@@ -796,8 +818,9 @@ static void DebugEventEvaluate(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
if (event == v8::Break) {
for (int i = 0; checks[i].expr != NULL; i++) {
@@ -822,8 +845,9 @@ static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
if (event == v8::Break) {
break_point_hit_count++;
@@ -840,8 +864,9 @@ static void DebugEventStep(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
if (event == v8::Break) {
break_point_hit_count++;
@@ -866,8 +891,9 @@ static void DebugEventStepSequence(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
if (event == v8::Break || event == v8::Exception) {
// Check that the current function is the expected.
@@ -896,8 +922,9 @@ static void DebugEventBreakPointCollectGarbage(
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
// Perform a garbage collection when break point is hit and continue. Based
// on the number of break points hit either scavenge or mark compact
@@ -906,10 +933,10 @@ static void DebugEventBreakPointCollectGarbage(
break_point_hit_count++;
if (break_point_hit_count % 2 == 0) {
// Scavenge.
- Heap::CollectGarbage(v8::internal::NEW_SPACE);
+ HEAP->CollectGarbage(v8::internal::NEW_SPACE);
} else {
// Mark sweep compact.
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
}
}
}
@@ -921,8 +948,9 @@ static void DebugEventBreak(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
if (event == v8::Break) {
// Count the number of breaks.
@@ -930,7 +958,7 @@ static void DebugEventBreak(v8::DebugEvent event,
// Run the garbage collector to enforce heap verification if option
// --verify-heap is set.
- Heap::CollectGarbage(v8::internal::NEW_SPACE);
+ HEAP->CollectGarbage(v8::internal::NEW_SPACE);
// Set the break flag again to come back here as soon as possible.
v8::Debug::DebugBreak();
@@ -946,8 +974,9 @@ static void DebugEventBreakMax(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
v8::Handle<v8::Object> event_data,
v8::Handle<v8::Value> data) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
- CHECK_NE(v8::internal::Debug::break_id(), 0);
+ CHECK_NE(debug->break_id(), 0);
if (event == v8::Break) {
if (break_point_hit_count < max_break_point_hit_count) {
@@ -987,6 +1016,7 @@ static void MessageCallbackCount(v8::Handle<v8::Message> message,
// of break locations.
TEST(DebugStub) {
using ::v8::internal::Builtins;
+ using ::v8::internal::Isolate;
v8::HandleScope scope;
DebugLocalContext env;
@@ -999,12 +1029,14 @@ TEST(DebugStub) {
"function f2(){x=1;}", "f2",
0,
v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
- Builtins::builtin(Builtins::StoreIC_DebugBreak));
+ Isolate::Current()->builtins()->builtin(
+ Builtins::kStoreIC_DebugBreak));
CheckDebugBreakFunction(&env,
"function f3(){var a=x;}", "f3",
0,
v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
- Builtins::builtin(Builtins::LoadIC_DebugBreak));
+ Isolate::Current()->builtins()->builtin(
+ Builtins::kLoadIC_DebugBreak));
// TODO(1240753): Make the test architecture independent or split
// parts of the debugger into architecture dependent files. This
@@ -1017,14 +1049,16 @@ TEST(DebugStub) {
"f4",
0,
v8::internal::RelocInfo::CODE_TARGET,
- Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
+ Isolate::Current()->builtins()->builtin(
+ Builtins::kKeyedStoreIC_DebugBreak));
CheckDebugBreakFunction(
&env,
"function f5(){var index='propertyName'; var a={}; return a[index];}",
"f5",
0,
v8::internal::RelocInfo::CODE_TARGET,
- Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
+ Isolate::Current()->builtins()->builtin(
+ Builtins::kKeyedLoadIC_DebugBreak));
#endif
// Check the debug break code stubs for call ICs with different number of
@@ -1139,7 +1173,7 @@ TEST(BreakPointICLoad) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- // Run with breakpoint
+ // Run with breakpoint.
int bp = SetBreakPoint(foo, 0);
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -1172,7 +1206,7 @@ TEST(BreakPointICCall) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- // Run with breakpoint.
+ // Run with breakpoint
int bp = SetBreakPoint(foo, 0);
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -1367,12 +1401,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);
+ 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(force_compaction);
+ HEAP->CollectAllGarbage(force_compaction);
f->Call(recv, 0, NULL);
CHECK_EQ(3 + i * 3, break_point_hit_count);
}
@@ -2199,7 +2233,7 @@ TEST(ScriptBreakPointLineTopLevel) {
}
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
- Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
SetScriptBreakPointByNameFromJS("test.html", 3, -1);
@@ -3698,7 +3732,7 @@ TEST(BreakOnException) {
DebugLocalContext env;
env.ExposeDebug();
- v8::internal::Top::TraceException(false);
+ v8::internal::Isolate::Current()->TraceException(false);
// Create functions for testing break on exception.
v8::Local<v8::Function> throws =
@@ -3845,7 +3879,7 @@ TEST(BreakOnCompileException) {
// For this test, we want to break on uncaught exceptions:
ChangeBreakOnException(false, true);
- v8::internal::Top::TraceException(false);
+ v8::internal::Isolate::Current()->TraceException(false);
// Create a function for checking the function when hitting a break point.
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
@@ -4230,9 +4264,9 @@ TEST(InterceptorPropertyMirror) {
"named_values[%d] instanceof debug.PropertyMirror", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
- // 4 is PropertyType.Interceptor
+ // 5 is PropertyType.Interceptor
OS::SNPrintF(buffer, "named_values[%d].propertyType()", i);
- CHECK_EQ(4, CompileRun(buffer.start())->Int32Value());
+ CHECK_EQ(5, CompileRun(buffer.start())->Int32Value());
OS::SNPrintF(buffer, "named_values[%d].isNative()", i);
CHECK(CompileRun(buffer.start())->BooleanValue());
@@ -4694,6 +4728,8 @@ Barriers message_queue_barriers;
// placing JSON debugger commands in the queue.
class MessageQueueDebuggerThread : public v8::internal::Thread {
public:
+ MessageQueueDebuggerThread()
+ : Thread("MessageQueueDebuggerThread") { }
void Run();
};
@@ -4793,10 +4829,11 @@ void MessageQueueDebuggerThread::Run() {
// Main thread continues running source_3 to end, waits for this thread.
}
-MessageQueueDebuggerThread message_queue_debugger_thread;
// This thread runs the v8 engine.
TEST(MessageQueues) {
+ MessageQueueDebuggerThread message_queue_debugger_thread;
+
// Create a V8 environment
v8::HandleScope scope;
DebugLocalContext env;
@@ -4942,11 +4979,13 @@ Barriers threaded_debugging_barriers;
class V8Thread : public v8::internal::Thread {
public:
+ V8Thread() : Thread("V8Thread") { }
void Run();
};
class DebuggerThread : public v8::internal::Thread {
public:
+ DebuggerThread() : Thread("DebuggerThread") { }
void Run();
};
@@ -4990,6 +5029,7 @@ void V8Thread::Run() {
"\n"
"foo();\n";
+ v8::V8::Initialize();
v8::HandleScope scope;
DebugLocalContext env;
v8::Debug::SetMessageHandler2(&ThreadedMessageHandler);
@@ -5021,10 +5061,11 @@ void DebuggerThread::Run() {
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
}
-DebuggerThread debugger_thread;
-V8Thread v8_thread;
TEST(ThreadedDebugging) {
+ DebuggerThread debugger_thread;
+ V8Thread v8_thread;
+
// Create a V8 environment
threaded_debugging_barriers.Initialize();
@@ -5044,13 +5085,15 @@ TEST(ThreadedDebugging) {
class BreakpointsV8Thread : public v8::internal::Thread {
public:
+ BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { }
void Run();
};
class BreakpointsDebuggerThread : public v8::internal::Thread {
public:
explicit BreakpointsDebuggerThread(bool global_evaluate)
- : global_evaluate_(global_evaluate) {}
+ : Thread("BreakpointsDebuggerThread"),
+ global_evaluate_(global_evaluate) {}
void Run();
private:
@@ -5099,6 +5142,7 @@ void BreakpointsV8Thread::Run() {
const char* source_2 = "cat(17);\n"
"cat(19);\n";
+ v8::V8::Initialize();
v8::HandleScope scope;
DebugLocalContext env;
v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler);
@@ -5609,11 +5653,13 @@ TEST(DebuggerClearMessageHandlerWhileActive) {
class HostDispatchV8Thread : public v8::internal::Thread {
public:
+ HostDispatchV8Thread() : Thread("HostDispatchV8Thread") { }
void Run();
};
class HostDispatchDebuggerThread : public v8::internal::Thread {
public:
+ HostDispatchDebuggerThread() : Thread("HostDispatchDebuggerThread") { }
void Run();
};
@@ -5643,6 +5689,7 @@ void HostDispatchV8Thread::Run() {
"\n";
const char* source_2 = "cat(17);\n";
+ v8::V8::Initialize();
v8::HandleScope scope;
DebugLocalContext env;
@@ -5683,11 +5730,10 @@ void HostDispatchDebuggerThread::Run() {
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
}
-HostDispatchDebuggerThread host_dispatch_debugger_thread;
-HostDispatchV8Thread host_dispatch_v8_thread;
-
TEST(DebuggerHostDispatch) {
+ HostDispatchDebuggerThread host_dispatch_debugger_thread;
+ HostDispatchV8Thread host_dispatch_v8_thread;
i::FLAG_debugger_auto_break = true;
// Create a V8 environment
@@ -5711,11 +5757,14 @@ TEST(DebuggerHostDispatch) {
class DebugMessageDispatchV8Thread : public v8::internal::Thread {
public:
+ DebugMessageDispatchV8Thread() : Thread("DebugMessageDispatchV8Thread") { }
void Run();
};
class DebugMessageDispatchDebuggerThread : public v8::internal::Thread {
public:
+ DebugMessageDispatchDebuggerThread()
+ : Thread("DebugMessageDispatchDebuggerThread") { }
void Run();
};
@@ -5728,6 +5777,7 @@ static void DebugMessageHandler() {
void DebugMessageDispatchV8Thread::Run() {
+ v8::V8::Initialize();
v8::HandleScope scope;
DebugLocalContext env;
@@ -5747,11 +5797,11 @@ void DebugMessageDispatchDebuggerThread::Run() {
debug_message_dispatch_barriers->barrier_2.Wait();
}
-DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
-DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
-
TEST(DebuggerDebugMessageDispatch) {
+ DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
+ DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
+
i::FLAG_debugger_auto_break = true;
// Create a V8 environment
@@ -5769,6 +5819,7 @@ TEST(DebuggerDebugMessageDispatch) {
TEST(DebuggerAgent) {
+ i::Debugger* debugger = i::Isolate::Current()->debugger();
// Make sure these ports is not used by other tests to allow tests to run in
// parallel.
const int kPort1 = 5858;
@@ -5786,18 +5837,23 @@ TEST(DebuggerAgent) {
i::Socket::Setup();
// Test starting and stopping the agent without any client connection.
- i::Debugger::StartAgent("test", kPort1);
- i::Debugger::StopAgent();
-
+ debugger->StartAgent("test", kPort1);
+ debugger->StopAgent();
// Test starting the agent, connecting a client and shutting down the agent
// with the client connected.
- ok = i::Debugger::StartAgent("test", kPort2);
+ ok = debugger->StartAgent("test", kPort2);
CHECK(ok);
- i::Debugger::WaitForAgent();
+ debugger->WaitForAgent();
i::Socket* client = i::OS::CreateSocket();
ok = client->Connect("localhost", port2_str);
CHECK(ok);
- i::Debugger::StopAgent();
+ // It is important to wait for a message from the agent. Otherwise,
+ // we can close the server socket during "accept" syscall, making it failing
+ // (at least on Linux), and the test will work incorrectly.
+ char buf;
+ ok = client->Receive(&buf, 1) == 1;
+ CHECK(ok);
+ debugger->StopAgent();
delete client;
// Test starting and stopping the agent with the required port already
@@ -5805,8 +5861,8 @@ TEST(DebuggerAgent) {
i::Socket* server = i::OS::CreateSocket();
server->Bind(kPort3);
- i::Debugger::StartAgent("test", kPort3);
- i::Debugger::StopAgent();
+ debugger->StartAgent("test", kPort3);
+ debugger->StopAgent();
delete server;
}
@@ -5815,7 +5871,10 @@ TEST(DebuggerAgent) {
class DebuggerAgentProtocolServerThread : public i::Thread {
public:
explicit DebuggerAgentProtocolServerThread(int port)
- : port_(port), server_(NULL), client_(NULL),
+ : Thread("DebuggerAgentProtocolServerThread"),
+ port_(port),
+ server_(NULL),
+ client_(NULL),
listening_(OS::CreateSemaphore(0)) {
}
~DebuggerAgentProtocolServerThread() {
@@ -6251,8 +6310,7 @@ static void ExecuteScriptForContextCheck() {
v8::Persistent<v8::Context> context_1;
v8::Handle<v8::ObjectTemplate> global_template =
v8::Handle<v8::ObjectTemplate>();
- v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
- context_1 = v8::Context::New(NULL, global_template, global_object);
+ context_1 = v8::Context::New(NULL, global_template);
// Default data value is undefined.
CHECK(context_1->GetData()->IsUndefined());
@@ -6317,11 +6375,11 @@ static void DebugEvalContextCheckMessageHandler(
const int kBufferSize = 1000;
uint16_t buffer[kBufferSize];
const char* eval_command =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "arguments:{\"expression\":\"debugger;\","
- "\"global\":true,\"disable_break\":false}}";
+ "{\"seq\":0,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"debugger;\","
+ "\"global\":true,\"disable_break\":false}}";
// Send evaluate command.
v8::Debug::SendCommand(buffer, AsciiToUtf16(eval_command, buffer));
@@ -6376,17 +6434,18 @@ static void DebugEventScriptCollectedEvent(v8::DebugEvent event,
// Test that scripts collected are reported through the debug event listener.
TEST(ScriptCollectedEvent) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
break_point_hit_count = 0;
script_collected_count = 0;
v8::HandleScope scope;
DebugLocalContext env;
// Request the loaded scripts to initialize the debugger script cache.
- Debug::GetLoadedScripts();
+ debug->GetLoadedScripts();
// Do garbage collection to ensure that only the script in this test will be
// collected afterwards.
- Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
script_collected_count = 0;
v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
@@ -6398,7 +6457,7 @@ TEST(ScriptCollectedEvent) {
// Do garbage collection to collect the script above which is no longer
// referenced.
- Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(2, script_collected_count);
@@ -6422,6 +6481,7 @@ static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) {
// Test that GetEventContext doesn't fail and return empty handle for
// ScriptCollected events.
TEST(ScriptCollectedEventContext) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
script_collected_message_count = 0;
v8::HandleScope scope;
@@ -6429,11 +6489,11 @@ TEST(ScriptCollectedEventContext) {
DebugLocalContext env;
// Request the loaded scripts to initialize the debugger script cache.
- Debug::GetLoadedScripts();
+ debug->GetLoadedScripts();
// Do garbage collection to ensure that only the script in this test will be
// collected afterwards.
- Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler);
{
@@ -6444,7 +6504,7 @@ TEST(ScriptCollectedEventContext) {
// Do garbage collection to collect the script above which is no longer
// referenced.
- Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK_EQ(2, script_collected_message_count);
@@ -6592,6 +6652,7 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
static void BreakMessageHandler(const v8::Debug::Message& message) {
+ i::Isolate* isolate = i::Isolate::Current();
if (message.IsEvent() && message.GetEvent() == v8::Break) {
// Count the number of breaks.
break_point_hit_count++;
@@ -6603,18 +6664,18 @@ static void BreakMessageHandler(const v8::Debug::Message& message) {
} else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
v8::HandleScope scope;
- bool is_debug_break = i::StackGuard::IsDebugBreak();
+ bool is_debug_break = isolate->stack_guard()->IsDebugBreak();
// Force DebugBreak flag while serializer is working.
- i::StackGuard::DebugBreak();
+ isolate->stack_guard()->DebugBreak();
// Force serialization to trigger some internal JS execution.
v8::Handle<v8::String> json = message.GetJSON();
// Restore previous state.
if (is_debug_break) {
- i::StackGuard::DebugBreak();
+ isolate->stack_guard()->DebugBreak();
} else {
- i::StackGuard::Continue(i::DEBUGBREAK);
+ isolate->stack_guard()->Continue(i::DEBUGBREAK);
}
}
}
@@ -6843,6 +6904,7 @@ static void DebugEventGetAtgumentPropertyValue(
TEST(CallingContextIsNotDebugContext) {
+ v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// Create and enter a debugee context.
v8::HandleScope scope;
DebugLocalContext env;
@@ -6851,7 +6913,7 @@ TEST(CallingContextIsNotDebugContext) {
// Save handles to the debugger and debugee contexts to be used in
// NamedGetterWithCallingContextCheck.
debugee_context = v8::Local<v8::Context>(*env);
- debugger_context = v8::Utils::ToLocal(Debug::debug_context());
+ debugger_context = v8::Utils::ToLocal(debug->debug_context());
// Create object with 'a' property accessor.
v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index 6ea4c849e..619839185 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -130,7 +130,7 @@ void DeclarationContext::Check(const char* source,
InitializeIfNeeded();
// A retry after a GC may pollute the counts, so perform gc now
// to avoid that.
- v8::internal::Heap::CollectGarbage(v8::internal::NEW_SPACE);
+ HEAP->CollectGarbage(v8::internal::NEW_SPACE);
HandleScope scope;
TryCatch catcher;
catcher.SetVerbose(true);
diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc
index 17453552e..056c98184 100644
--- a/deps/v8/test/cctest/test-deoptimization.cc
+++ b/deps/v8/test/cctest/test-deoptimization.cc
@@ -30,20 +30,21 @@
#include "v8.h"
#include "api.h"
+#include "cctest.h"
#include "compilation-cache.h"
#include "debug.h"
#include "deoptimizer.h"
+#include "isolate.h"
#include "platform.h"
#include "stub-cache.h"
-#include "cctest.h"
-
-using ::v8::internal::Handle;
-using ::v8::internal::Object;
-using ::v8::internal::JSFunction;
using ::v8::internal::Deoptimizer;
using ::v8::internal::EmbeddedVector;
+using ::v8::internal::Handle;
+using ::v8::internal::Isolate;
+using ::v8::internal::JSFunction;
using ::v8::internal::OS;
+using ::v8::internal::Object;
// Size of temp buffer for formatting small strings.
#define SMALL_STRING_BUFFER_SIZE 80
@@ -96,8 +97,8 @@ class AllowNativesSyntaxNoInlining {
};
-Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
- const char* property_name) {
+static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
+ const char* property_name) {
v8::Local<v8::Function> fun =
v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name)));
return v8::Utils::OpenHandle(*fun);
@@ -124,7 +125,7 @@ TEST(DeoptimizeSimple) {
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
- CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
// Test lazy deoptimization of a simple function. Call the function after the
// deoptimization while it is still activated further down the stack.
@@ -140,7 +141,7 @@ TEST(DeoptimizeSimple) {
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
- CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -164,7 +165,7 @@ TEST(DeoptimizeSimpleWithArguments) {
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
- CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
// Test lazy deoptimization of a simple function with some arguments. Call the
// function after the deoptimization while it is still activated further down
@@ -181,7 +182,7 @@ TEST(DeoptimizeSimpleWithArguments) {
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
- CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -207,7 +208,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
}
@@ -232,7 +233,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
v8::Local<v8::Function> fun =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
@@ -266,7 +267,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -289,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
{
AlwaysOptimizeAllowNativesSyntaxNoInlining options;
@@ -306,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -337,7 +338,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -385,7 +386,7 @@ TEST(DeoptimizeBinaryOperationADDString) {
CHECK(result->IsString());
v8::String::AsciiValue ascii(result);
CHECK_EQ("a+an X", *ascii);
- CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -444,7 +445,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -458,7 +459,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -472,7 +473,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -486,7 +487,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -500,7 +501,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -545,7 +546,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -627,7 +628,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
@@ -710,5 +711,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());
+ CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
}
diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc
index dea0db92c..032e6bc0f 100644
--- a/deps/v8/test/cctest/test-disasm-arm.cc
+++ b/deps/v8/test/cctest/test-disasm-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -72,11 +72,11 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) {
// Setup V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
-#define SETUP() \
- InitializeVM(); \
- v8::HandleScope scope; \
+#define SETUP() \
+ InitializeVM(); \
+ v8::HandleScope scope; \
byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
- Assembler assm(buffer, 4*1024); \
+ Assembler assm(Isolate::Current(), buffer, 4*1024); \
bool failure = false;
@@ -436,9 +436,14 @@ TEST(Vfp) {
"ee0faa90 vmov s31, r10");
COMPARE(vabs(d0, d1),
- "eeb00bc1 vabs d0, d1");
+ "eeb00bc1 vabs.f64 d0, d1");
COMPARE(vabs(d3, d4, mi),
- "4eb03bc4 vabsmi d3, d4");
+ "4eb03bc4 vabs.f64mi d3, d4");
+
+ COMPARE(vneg(d0, d1),
+ "eeb10b41 vneg.f64 d0, d1");
+ COMPARE(vneg(d3, d4, mi),
+ "4eb13b44 vneg.f64mi d3, d4");
COMPARE(vadd(d0, d1, d2),
"ee310b02 vadd.f64 d0, d1, d2");
@@ -517,7 +522,227 @@ TEST(Vfp) {
"aef1aa10 vmrsge r10, FPSCR");
COMPARE(vmrs(pc),
"eef1fa10 vmrs APSR, FPSCR");
+
+ COMPARE(vstm(ia, r0, d1, d3),
+ "ec801b06 vstmia r0, {d1-d3}");
+ COMPARE(vldm(ia, r1, d2, d5),
+ "ec912b08 vldmia r1, {d2-d5}");
+ COMPARE(vstm(ia, r2, d0, d15),
+ "ec820b20 vstmia r2, {d0-d15}");
+ COMPARE(vldm(ia, r3, d0, d15),
+ "ec930b20 vldmia r3, {d0-d15}");
+ COMPARE(vstm(ia, r4, s1, s3),
+ "ecc40a03 vstmia r4, {s1-s3}");
+ COMPARE(vldm(ia, r5, s2, s5),
+ "ec951a04 vldmia r5, {s2-s5}");
+ COMPARE(vstm(ia, r6, s0, s31),
+ "ec860a20 vstmia r6, {s0-s31}");
+ COMPARE(vldm(ia, r7, s0, s31),
+ "ec970a20 vldmia r7, {s0-s31}");
}
VERIFY_RUN();
}
+
+
+TEST(LoadStore) {
+ SETUP();
+
+ COMPARE(ldrb(r0, MemOperand(r1)),
+ "e5d10000 ldrb r0, [r1, #+0]");
+ COMPARE(ldrb(r2, MemOperand(r3, 42)),
+ "e5d3202a ldrb r2, [r3, #+42]");
+ COMPARE(ldrb(r4, MemOperand(r5, -42)),
+ "e555402a ldrb r4, [r5, #-42]");
+ COMPARE(ldrb(r6, MemOperand(r7, 42, PostIndex)),
+ "e4d7602a ldrb r6, [r7], #+42");
+ COMPARE(ldrb(r8, MemOperand(r9, -42, PostIndex)),
+ "e459802a ldrb r8, [r9], #-42");
+ COMPARE(ldrb(r10, MemOperand(fp, 42, PreIndex)),
+ "e5fba02a ldrb r10, [fp, #+42]!");
+ COMPARE(ldrb(ip, MemOperand(sp, -42, PreIndex)),
+ "e57dc02a ldrb ip, [sp, #-42]!");
+ COMPARE(ldrb(r0, MemOperand(r1, r2)),
+ "e7d10002 ldrb r0, [r1, +r2]");
+ COMPARE(ldrb(r0, MemOperand(r1, r2, NegOffset)),
+ "e7510002 ldrb r0, [r1, -r2]");
+ COMPARE(ldrb(r0, MemOperand(r1, r2, PostIndex)),
+ "e6d10002 ldrb r0, [r1], +r2");
+ COMPARE(ldrb(r0, MemOperand(r1, r2, NegPostIndex)),
+ "e6510002 ldrb r0, [r1], -r2");
+ COMPARE(ldrb(r0, MemOperand(r1, r2, PreIndex)),
+ "e7f10002 ldrb r0, [r1, +r2]!");
+ COMPARE(ldrb(r0, MemOperand(r1, r2, NegPreIndex)),
+ "e7710002 ldrb r0, [r1, -r2]!");
+
+ COMPARE(strb(r0, MemOperand(r1)),
+ "e5c10000 strb r0, [r1, #+0]");
+ COMPARE(strb(r2, MemOperand(r3, 42)),
+ "e5c3202a strb r2, [r3, #+42]");
+ COMPARE(strb(r4, MemOperand(r5, -42)),
+ "e545402a strb r4, [r5, #-42]");
+ COMPARE(strb(r6, MemOperand(r7, 42, PostIndex)),
+ "e4c7602a strb r6, [r7], #+42");
+ COMPARE(strb(r8, MemOperand(r9, -42, PostIndex)),
+ "e449802a strb r8, [r9], #-42");
+ COMPARE(strb(r10, MemOperand(fp, 42, PreIndex)),
+ "e5eba02a strb r10, [fp, #+42]!");
+ COMPARE(strb(ip, MemOperand(sp, -42, PreIndex)),
+ "e56dc02a strb ip, [sp, #-42]!");
+ COMPARE(strb(r0, MemOperand(r1, r2)),
+ "e7c10002 strb r0, [r1, +r2]");
+ COMPARE(strb(r0, MemOperand(r1, r2, NegOffset)),
+ "e7410002 strb r0, [r1, -r2]");
+ COMPARE(strb(r0, MemOperand(r1, r2, PostIndex)),
+ "e6c10002 strb r0, [r1], +r2");
+ COMPARE(strb(r0, MemOperand(r1, r2, NegPostIndex)),
+ "e6410002 strb r0, [r1], -r2");
+ COMPARE(strb(r0, MemOperand(r1, r2, PreIndex)),
+ "e7e10002 strb r0, [r1, +r2]!");
+ COMPARE(strb(r0, MemOperand(r1, r2, NegPreIndex)),
+ "e7610002 strb r0, [r1, -r2]!");
+
+ COMPARE(ldrh(r0, MemOperand(r1)),
+ "e1d100b0 ldrh r0, [r1, #+0]");
+ COMPARE(ldrh(r2, MemOperand(r3, 42)),
+ "e1d322ba ldrh r2, [r3, #+42]");
+ COMPARE(ldrh(r4, MemOperand(r5, -42)),
+ "e15542ba ldrh r4, [r5, #-42]");
+ COMPARE(ldrh(r6, MemOperand(r7, 42, PostIndex)),
+ "e0d762ba ldrh r6, [r7], #+42");
+ COMPARE(ldrh(r8, MemOperand(r9, -42, PostIndex)),
+ "e05982ba ldrh r8, [r9], #-42");
+ COMPARE(ldrh(r10, MemOperand(fp, 42, PreIndex)),
+ "e1fba2ba ldrh r10, [fp, #+42]!");
+ COMPARE(ldrh(ip, MemOperand(sp, -42, PreIndex)),
+ "e17dc2ba ldrh ip, [sp, #-42]!");
+ COMPARE(ldrh(r0, MemOperand(r1, r2)),
+ "e19100b2 ldrh r0, [r1, +r2]");
+ COMPARE(ldrh(r0, MemOperand(r1, r2, NegOffset)),
+ "e11100b2 ldrh r0, [r1, -r2]");
+ COMPARE(ldrh(r0, MemOperand(r1, r2, PostIndex)),
+ "e09100b2 ldrh r0, [r1], +r2");
+ COMPARE(ldrh(r0, MemOperand(r1, r2, NegPostIndex)),
+ "e01100b2 ldrh r0, [r1], -r2");
+ COMPARE(ldrh(r0, MemOperand(r1, r2, PreIndex)),
+ "e1b100b2 ldrh r0, [r1, +r2]!");
+ COMPARE(ldrh(r0, MemOperand(r1, r2, NegPreIndex)),
+ "e13100b2 ldrh r0, [r1, -r2]!");
+
+ COMPARE(strh(r0, MemOperand(r1)),
+ "e1c100b0 strh r0, [r1, #+0]");
+ COMPARE(strh(r2, MemOperand(r3, 42)),
+ "e1c322ba strh r2, [r3, #+42]");
+ COMPARE(strh(r4, MemOperand(r5, -42)),
+ "e14542ba strh r4, [r5, #-42]");
+ COMPARE(strh(r6, MemOperand(r7, 42, PostIndex)),
+ "e0c762ba strh r6, [r7], #+42");
+ COMPARE(strh(r8, MemOperand(r9, -42, PostIndex)),
+ "e04982ba strh r8, [r9], #-42");
+ COMPARE(strh(r10, MemOperand(fp, 42, PreIndex)),
+ "e1eba2ba strh r10, [fp, #+42]!");
+ COMPARE(strh(ip, MemOperand(sp, -42, PreIndex)),
+ "e16dc2ba strh ip, [sp, #-42]!");
+ COMPARE(strh(r0, MemOperand(r1, r2)),
+ "e18100b2 strh r0, [r1, +r2]");
+ COMPARE(strh(r0, MemOperand(r1, r2, NegOffset)),
+ "e10100b2 strh r0, [r1, -r2]");
+ COMPARE(strh(r0, MemOperand(r1, r2, PostIndex)),
+ "e08100b2 strh r0, [r1], +r2");
+ COMPARE(strh(r0, MemOperand(r1, r2, NegPostIndex)),
+ "e00100b2 strh r0, [r1], -r2");
+ COMPARE(strh(r0, MemOperand(r1, r2, PreIndex)),
+ "e1a100b2 strh r0, [r1, +r2]!");
+ COMPARE(strh(r0, MemOperand(r1, r2, NegPreIndex)),
+ "e12100b2 strh r0, [r1, -r2]!");
+
+ COMPARE(ldr(r0, MemOperand(r1)),
+ "e5910000 ldr r0, [r1, #+0]");
+ COMPARE(ldr(r2, MemOperand(r3, 42)),
+ "e593202a ldr r2, [r3, #+42]");
+ COMPARE(ldr(r4, MemOperand(r5, -42)),
+ "e515402a ldr r4, [r5, #-42]");
+ COMPARE(ldr(r6, MemOperand(r7, 42, PostIndex)),
+ "e497602a ldr r6, [r7], #+42");
+ COMPARE(ldr(r8, MemOperand(r9, -42, PostIndex)),
+ "e419802a ldr r8, [r9], #-42");
+ COMPARE(ldr(r10, MemOperand(fp, 42, PreIndex)),
+ "e5bba02a ldr r10, [fp, #+42]!");
+ COMPARE(ldr(ip, MemOperand(sp, -42, PreIndex)),
+ "e53dc02a ldr ip, [sp, #-42]!");
+ COMPARE(ldr(r0, MemOperand(r1, r2)),
+ "e7910002 ldr r0, [r1, +r2]");
+ COMPARE(ldr(r0, MemOperand(r1, r2, NegOffset)),
+ "e7110002 ldr r0, [r1, -r2]");
+ COMPARE(ldr(r0, MemOperand(r1, r2, PostIndex)),
+ "e6910002 ldr r0, [r1], +r2");
+ COMPARE(ldr(r0, MemOperand(r1, r2, NegPostIndex)),
+ "e6110002 ldr r0, [r1], -r2");
+ COMPARE(ldr(r0, MemOperand(r1, r2, PreIndex)),
+ "e7b10002 ldr r0, [r1, +r2]!");
+ COMPARE(ldr(r0, MemOperand(r1, r2, NegPreIndex)),
+ "e7310002 ldr r0, [r1, -r2]!");
+
+ COMPARE(str(r0, MemOperand(r1)),
+ "e5810000 str r0, [r1, #+0]");
+ COMPARE(str(r2, MemOperand(r3, 42)),
+ "e583202a str r2, [r3, #+42]");
+ COMPARE(str(r4, MemOperand(r5, -42)),
+ "e505402a str r4, [r5, #-42]");
+ COMPARE(str(r6, MemOperand(r7, 42, PostIndex)),
+ "e487602a str r6, [r7], #+42");
+ COMPARE(str(r8, MemOperand(r9, -42, PostIndex)),
+ "e409802a str r8, [r9], #-42");
+ COMPARE(str(r10, MemOperand(fp, 42, PreIndex)),
+ "e5aba02a str r10, [fp, #+42]!");
+ COMPARE(str(ip, MemOperand(sp, -42, PreIndex)),
+ "e52dc02a str ip, [sp, #-42]!");
+ COMPARE(str(r0, MemOperand(r1, r2)),
+ "e7810002 str r0, [r1, +r2]");
+ COMPARE(str(r0, MemOperand(r1, r2, NegOffset)),
+ "e7010002 str r0, [r1, -r2]");
+ COMPARE(str(r0, MemOperand(r1, r2, PostIndex)),
+ "e6810002 str r0, [r1], +r2");
+ COMPARE(str(r0, MemOperand(r1, r2, NegPostIndex)),
+ "e6010002 str r0, [r1], -r2");
+ COMPARE(str(r0, MemOperand(r1, r2, PreIndex)),
+ "e7a10002 str r0, [r1, +r2]!");
+ COMPARE(str(r0, MemOperand(r1, r2, NegPreIndex)),
+ "e7210002 str r0, [r1, -r2]!");
+
+ if (CpuFeatures::IsSupported(ARMv7)) {
+ CpuFeatures::Scope scope(ARMv7);
+ COMPARE(ldrd(r0, r1, MemOperand(r1)),
+ "e1c100d0 ldrd r0, [r1, #+0]");
+ COMPARE(ldrd(r2, r3, MemOperand(r3, 127)),
+ "e1c327df ldrd r2, [r3, #+127]");
+ COMPARE(ldrd(r4, r5, MemOperand(r5, -127)),
+ "e14547df ldrd r4, [r5, #-127]");
+ COMPARE(ldrd(r6, r7, MemOperand(r7, 127, PostIndex)),
+ "e0c767df ldrd r6, [r7], #+127");
+ COMPARE(ldrd(r8, r9, MemOperand(r9, -127, PostIndex)),
+ "e04987df ldrd r8, [r9], #-127");
+ COMPARE(ldrd(r10, fp, MemOperand(fp, 127, PreIndex)),
+ "e1eba7df ldrd r10, [fp, #+127]!");
+ COMPARE(ldrd(ip, sp, MemOperand(sp, -127, PreIndex)),
+ "e16dc7df ldrd ip, [sp, #-127]!");
+
+ COMPARE(strd(r0, r1, MemOperand(r1)),
+ "e1c100f0 strd r0, [r1, #+0]");
+ COMPARE(strd(r2, r3, MemOperand(r3, 127)),
+ "e1c327ff strd r2, [r3, #+127]");
+ COMPARE(strd(r4, r5, MemOperand(r5, -127)),
+ "e14547ff strd r4, [r5, #-127]");
+ COMPARE(strd(r6, r7, MemOperand(r7, 127, PostIndex)),
+ "e0c767ff strd r6, [r7], #+127");
+ COMPARE(strd(r8, r9, MemOperand(r9, -127, PostIndex)),
+ "e04987ff strd r8, [r9], #-127");
+ COMPARE(strd(r10, fp, MemOperand(fp, 127, PreIndex)),
+ "e1eba7ff strd r10, [fp, #+127]!");
+ COMPARE(strd(ip, sp, MemOperand(sp, -127, PreIndex)),
+ "e16dc7ff strd ip, [sp, #-127]!");
+ }
+
+ VERIFY_RUN();
+}
+
diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc
index c995aa8ed..9f7d0bb6e 100644
--- a/deps/v8/test/cctest/test-disasm-ia32.cc
+++ b/deps/v8/test/cctest/test-disasm-ia32.cc
@@ -58,7 +58,7 @@ TEST(DisasmIa320) {
InitializeVM();
v8::HandleScope scope;
v8::internal::byte buffer[2048];
- Assembler assm(buffer, sizeof buffer);
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging)
// Short immediate instructions
@@ -68,7 +68,7 @@ TEST(DisasmIa320) {
__ sub(Operand(eax), Immediate(12345678));
__ xor_(eax, 12345678);
__ and_(eax, 12345678);
- Handle<FixedArray> foo = Factory::NewFixedArray(10, TENURED);
+ Handle<FixedArray> foo = FACTORY->NewFixedArray(10, TENURED);
__ cmp(eax, foo);
// ---- This one caused crash
@@ -99,7 +99,7 @@ TEST(DisasmIa320) {
__ cmp(edx, 3);
__ cmp(edx, Operand(esp, 4));
__ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
- Handle<FixedArray> foo2 = Factory::NewFixedArray(10, TENURED);
+ Handle<FixedArray> foo2 = FACTORY->NewFixedArray(10, TENURED);
__ cmp(ebx, foo2);
__ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
__ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
@@ -272,7 +272,8 @@ TEST(DisasmIa320) {
__ bind(&L2);
__ call(Operand(ebx, ecx, times_4, 10000));
__ nop();
- Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
+ Handle<Code> ic(Isolate::Current()->builtins()->builtin(
+ Builtins::kLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
@@ -282,7 +283,8 @@ TEST(DisasmIa320) {
__ jmp(Operand(ebx, ecx, times_4, 10000));
#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference after_break_target =
- ExternalReference(Debug_Address::AfterBreakTarget());
+ ExternalReference(Debug_Address::AfterBreakTarget(),
+ assm.isolate());
__ jmp(Operand::StaticVariable(after_break_target));
#endif // ENABLE_DEBUGGER_SUPPORT
__ jmp(ic, RelocInfo::CODE_TARGET);
@@ -328,11 +330,6 @@ TEST(DisasmIa320) {
__ j(less_equal, &Ljcc);
__ j(greater, &Ljcc);
- // checking hints
- __ j(zero, &Ljcc, taken);
- __ j(zero, &Ljcc, not_taken);
-
- // __ mov(Operand::StaticVariable(Top::handler_address()), eax);
// 0xD9 instructions
__ nop();
@@ -458,10 +455,10 @@ TEST(DisasmIa320) {
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc
new file mode 100644
index 000000000..901dbc1bf
--- /dev/null
+++ b/deps/v8/test/cctest/test-disasm-mips.cc
@@ -0,0 +1,432 @@
+// 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.
+//
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "debug.h"
+#include "disasm.h"
+#include "disassembler.h"
+#include "macro-assembler.h"
+#include "serialize.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+
+static v8::Persistent<v8::Context> env;
+
+static void InitializeVM() {
+ // Disable compilation of natives.
+ FLAG_disable_native_files = true;
+ if (env.IsEmpty()) {
+ env = v8::Context::New();
+ }
+}
+
+
+bool DisassembleAndCompare(byte* pc, const char* compare_string) {
+ disasm::NameConverter converter;
+ disasm::Disassembler disasm(converter);
+ EmbeddedVector<char, 128> disasm_buffer;
+
+ disasm.InstructionDecode(disasm_buffer, pc);
+
+ if (strcmp(compare_string, disasm_buffer.start()) != 0) {
+ fprintf(stderr,
+ "expected: \n"
+ "%s\n"
+ "disassembled: \n"
+ "%s\n\n",
+ compare_string, disasm_buffer.start());
+ return false;
+ }
+ return true;
+}
+
+
+// Setup V8 to a state where we can at least run the assembler and
+// disassembler. Declare the variables and allocate the data structures used
+// in the rest of the macros.
+#define SETUP() \
+ InitializeVM(); \
+ v8::HandleScope scope; \
+ byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
+ Assembler assm(Isolate::Current(), buffer, 4*1024); \
+ bool failure = false;
+
+
+// This macro assembles one instruction using the preallocated assembler and
+// disassembles the generated instruction, comparing the output to the expected
+// value. If the comparison fails an error message is printed, but the test
+// continues to run until the end.
+#define COMPARE(asm_, compare_string) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
+ }
+
+
+// Verify that all invocations of the COMPARE macro passed successfully.
+// Exit with a failure if at least one of the tests failed.
+#define VERIFY_RUN() \
+if (failure) { \
+ V8_Fatal(__FILE__, __LINE__, "MIPS Disassembler tests failed.\n"); \
+ }
+
+
+TEST(Type0) {
+ SETUP();
+
+ COMPARE(addu(a0, a1, a2),
+ "00a62021 addu a0, a1, a2");
+ COMPARE(addu(t2, t3, t4),
+ "016c5021 addu t2, t3, t4");
+ COMPARE(addu(v0, v1, s0),
+ "00701021 addu v0, v1, s0");
+
+ COMPARE(subu(a0, a1, a2),
+ "00a62023 subu a0, a1, a2");
+ COMPARE(subu(t2, t3, t4),
+ "016c5023 subu t2, t3, t4");
+ COMPARE(subu(v0, v1, s0),
+ "00701023 subu v0, v1, s0");
+
+ COMPARE(mult(a0, a1),
+ "00850018 mult a0, a1");
+ COMPARE(mult(t2, t3),
+ "014b0018 mult t2, t3");
+ COMPARE(mult(v0, v1),
+ "00430018 mult v0, v1");
+
+ COMPARE(multu(a0, a1),
+ "00850019 multu a0, a1");
+ COMPARE(multu(t2, t3),
+ "014b0019 multu t2, t3");
+ COMPARE(multu(v0, v1),
+ "00430019 multu v0, v1");
+
+ COMPARE(div(a0, a1),
+ "0085001a div a0, a1");
+ COMPARE(div(t2, t3),
+ "014b001a div t2, t3");
+ COMPARE(div(v0, v1),
+ "0043001a div v0, v1");
+
+ COMPARE(divu(a0, a1),
+ "0085001b divu a0, a1");
+ COMPARE(divu(t2, t3),
+ "014b001b divu t2, t3");
+ COMPARE(divu(v0, v1),
+ "0043001b divu v0, v1");
+
+ COMPARE(mul(a0, a1, a2),
+ "70a62002 mul a0, a1, a2");
+ COMPARE(mul(t2, t3, t4),
+ "716c5002 mul t2, t3, t4");
+ COMPARE(mul(v0, v1, s0),
+ "70701002 mul v0, v1, s0");
+
+ COMPARE(addiu(a0, a1, 0x0),
+ "24a40000 addiu a0, a1, 0");
+ COMPARE(addiu(s0, s1, 32767),
+ "26307fff addiu s0, s1, 32767");
+ COMPARE(addiu(t2, t3, -32768),
+ "256a8000 addiu t2, t3, -32768");
+ COMPARE(addiu(v0, v1, -1),
+ "2462ffff addiu v0, v1, -1");
+
+ COMPARE(and_(a0, a1, a2),
+ "00a62024 and a0, a1, a2");
+ COMPARE(and_(s0, s1, s2),
+ "02328024 and s0, s1, s2");
+ COMPARE(and_(t2, t3, t4),
+ "016c5024 and t2, t3, t4");
+ COMPARE(and_(v0, v1, a2),
+ "00661024 and v0, v1, a2");
+
+ COMPARE(or_(a0, a1, a2),
+ "00a62025 or a0, a1, a2");
+ COMPARE(or_(s0, s1, s2),
+ "02328025 or s0, s1, s2");
+ COMPARE(or_(t2, t3, t4),
+ "016c5025 or t2, t3, t4");
+ COMPARE(or_(v0, v1, a2),
+ "00661025 or v0, v1, a2");
+
+ COMPARE(xor_(a0, a1, a2),
+ "00a62026 xor a0, a1, a2");
+ COMPARE(xor_(s0, s1, s2),
+ "02328026 xor s0, s1, s2");
+ COMPARE(xor_(t2, t3, t4),
+ "016c5026 xor t2, t3, t4");
+ COMPARE(xor_(v0, v1, a2),
+ "00661026 xor v0, v1, a2");
+
+ COMPARE(nor(a0, a1, a2),
+ "00a62027 nor a0, a1, a2");
+ COMPARE(nor(s0, s1, s2),
+ "02328027 nor s0, s1, s2");
+ COMPARE(nor(t2, t3, t4),
+ "016c5027 nor t2, t3, t4");
+ COMPARE(nor(v0, v1, a2),
+ "00661027 nor v0, v1, a2");
+
+ COMPARE(andi(a0, a1, 0x1),
+ "30a40001 andi a0, a1, 0x1");
+ COMPARE(andi(v0, v1, 0xffff),
+ "3062ffff andi v0, v1, 0xffff");
+
+ COMPARE(ori(a0, a1, 0x1),
+ "34a40001 ori a0, a1, 0x1");
+ COMPARE(ori(v0, v1, 0xffff),
+ "3462ffff ori v0, v1, 0xffff");
+
+ COMPARE(xori(a0, a1, 0x1),
+ "38a40001 xori a0, a1, 0x1");
+ COMPARE(xori(v0, v1, 0xffff),
+ "3862ffff xori v0, v1, 0xffff");
+
+ COMPARE(lui(a0, 0x1),
+ "3c040001 lui a0, 0x1");
+ COMPARE(lui(v0, 0xffff),
+ "3c02ffff lui v0, 0xffff");
+
+ COMPARE(sll(a0, a1, 0),
+ "00052000 sll a0, a1, 0");
+ COMPARE(sll(s0, s1, 8),
+ "00118200 sll s0, s1, 8");
+ COMPARE(sll(t2, t3, 24),
+ "000b5600 sll t2, t3, 24");
+ COMPARE(sll(v0, v1, 31),
+ "000317c0 sll v0, v1, 31");
+
+ COMPARE(sllv(a0, a1, a2),
+ "00c52004 sllv a0, a1, a2");
+ COMPARE(sllv(s0, s1, s2),
+ "02518004 sllv s0, s1, s2");
+ COMPARE(sllv(t2, t3, t4),
+ "018b5004 sllv t2, t3, t4");
+ COMPARE(sllv(v0, v1, fp),
+ "03c31004 sllv v0, v1, fp");
+
+ COMPARE(srl(a0, a1, 0),
+ "00052002 srl a0, a1, 0");
+ COMPARE(srl(s0, s1, 8),
+ "00118202 srl s0, s1, 8");
+ COMPARE(srl(t2, t3, 24),
+ "000b5602 srl t2, t3, 24");
+ COMPARE(srl(v0, v1, 31),
+ "000317c2 srl v0, v1, 31");
+
+ COMPARE(srlv(a0, a1, a2),
+ "00c52006 srlv a0, a1, a2");
+ COMPARE(srlv(s0, s1, s2),
+ "02518006 srlv s0, s1, s2");
+ COMPARE(srlv(t2, t3, t4),
+ "018b5006 srlv t2, t3, t4");
+ COMPARE(srlv(v0, v1, fp),
+ "03c31006 srlv v0, v1, fp");
+
+ COMPARE(sra(a0, a1, 0),
+ "00052003 sra a0, a1, 0");
+ COMPARE(sra(s0, s1, 8),
+ "00118203 sra s0, s1, 8");
+ COMPARE(sra(t2, t3, 24),
+ "000b5603 sra t2, t3, 24");
+ COMPARE(sra(v0, v1, 31),
+ "000317c3 sra v0, v1, 31");
+
+ COMPARE(srav(a0, a1, a2),
+ "00c52007 srav a0, a1, a2");
+ COMPARE(srav(s0, s1, s2),
+ "02518007 srav s0, s1, s2");
+ COMPARE(srav(t2, t3, t4),
+ "018b5007 srav t2, t3, t4");
+ COMPARE(srav(v0, v1, fp),
+ "03c31007 srav v0, v1, fp");
+
+ COMPARE(rotr(a0, a1, 0),
+ "00252002 rotr a0, a1, 0");
+ COMPARE(rotr(s0, s1, 8),
+ "00318202 rotr s0, s1, 8");
+ COMPARE(rotr(t2, t3, 24),
+ "002b5602 rotr t2, t3, 24");
+ COMPARE(rotr(v0, v1, 31),
+ "002317c2 rotr v0, v1, 31");
+
+ COMPARE(rotrv(a0, a1, a2),
+ "00c52046 rotrv a0, a1, a2");
+ COMPARE(rotrv(s0, s1, s2),
+ "02518046 rotrv s0, s1, s2");
+ COMPARE(rotrv(t2, t3, t4),
+ "018b5046 rotrv t2, t3, t4");
+ COMPARE(rotrv(v0, v1, fp),
+ "03c31046 rotrv v0, v1, fp");
+
+ COMPARE(break_(0),
+ "0000000d break, code: 0x00000 (0)");
+ COMPARE(break_(261120),
+ "00ff000d break, code: 0x3fc00 (261120)");
+ COMPARE(break_(1047552),
+ "03ff000d break, code: 0xffc00 (1047552)");
+
+ COMPARE(tge(a0, a1, 0),
+ "00850030 tge a0, a1, code: 0x000");
+ COMPARE(tge(s0, s1, 1023),
+ "0211fff0 tge s0, s1, code: 0x3ff");
+ COMPARE(tgeu(a0, a1, 0),
+ "00850031 tgeu a0, a1, code: 0x000");
+ COMPARE(tgeu(s0, s1, 1023),
+ "0211fff1 tgeu s0, s1, code: 0x3ff");
+ COMPARE(tlt(a0, a1, 0),
+ "00850032 tlt a0, a1, code: 0x000");
+ COMPARE(tlt(s0, s1, 1023),
+ "0211fff2 tlt s0, s1, code: 0x3ff");
+ COMPARE(tltu(a0, a1, 0),
+ "00850033 tltu a0, a1, code: 0x000");
+ COMPARE(tltu(s0, s1, 1023),
+ "0211fff3 tltu s0, s1, code: 0x3ff");
+ COMPARE(teq(a0, a1, 0),
+ "00850034 teq a0, a1, code: 0x000");
+ COMPARE(teq(s0, s1, 1023),
+ "0211fff4 teq s0, s1, code: 0x3ff");
+ COMPARE(tne(a0, a1, 0),
+ "00850036 tne a0, a1, code: 0x000");
+ COMPARE(tne(s0, s1, 1023),
+ "0211fff6 tne s0, s1, code: 0x3ff");
+
+ COMPARE(mfhi(a0),
+ "00002010 mfhi a0");
+ COMPARE(mfhi(s2),
+ "00009010 mfhi s2");
+ COMPARE(mfhi(t4),
+ "00006010 mfhi t4");
+ COMPARE(mfhi(v1),
+ "00001810 mfhi v1");
+ COMPARE(mflo(a0),
+ "00002012 mflo a0");
+ COMPARE(mflo(s2),
+ "00009012 mflo s2");
+ COMPARE(mflo(t4),
+ "00006012 mflo t4");
+ COMPARE(mflo(v1),
+ "00001812 mflo v1");
+
+ COMPARE(slt(a0, a1, a2),
+ "00a6202a slt a0, a1, a2");
+ COMPARE(slt(s0, s1, s2),
+ "0232802a slt s0, s1, s2");
+ COMPARE(slt(t2, t3, t4),
+ "016c502a slt t2, t3, t4");
+ COMPARE(slt(v0, v1, a2),
+ "0066102a slt v0, v1, a2");
+ COMPARE(sltu(a0, a1, a2),
+ "00a6202b sltu a0, a1, a2");
+ COMPARE(sltu(s0, s1, s2),
+ "0232802b sltu s0, s1, s2");
+ COMPARE(sltu(t2, t3, t4),
+ "016c502b sltu t2, t3, t4");
+ COMPARE(sltu(v0, v1, a2),
+ "0066102b sltu v0, v1, a2");
+
+ COMPARE(slti(a0, a1, 0),
+ "28a40000 slti a0, a1, 0");
+ COMPARE(slti(s0, s1, 32767),
+ "2a307fff slti s0, s1, 32767");
+ COMPARE(slti(t2, t3, -32768),
+ "296a8000 slti t2, t3, -32768");
+ COMPARE(slti(v0, v1, -1),
+ "2862ffff slti v0, v1, -1");
+ COMPARE(sltiu(a0, a1, 0),
+ "2ca40000 sltiu a0, a1, 0");
+ COMPARE(sltiu(s0, s1, 32767),
+ "2e307fff sltiu s0, s1, 32767");
+ COMPARE(sltiu(t2, t3, -32768),
+ "2d6a8000 sltiu t2, t3, -32768");
+ COMPARE(sltiu(v0, v1, -1),
+ "2c62ffff sltiu v0, v1, -1");
+
+ COMPARE(movz(a0, a1, a2),
+ "00a6200a movz a0, a1, a2");
+ COMPARE(movz(s0, s1, s2),
+ "0232800a movz s0, s1, s2");
+ COMPARE(movz(t2, t3, t4),
+ "016c500a movz t2, t3, t4");
+ COMPARE(movz(v0, v1, a2),
+ "0066100a movz v0, v1, a2");
+ COMPARE(movn(a0, a1, a2),
+ "00a6200b movn a0, a1, a2");
+ COMPARE(movn(s0, s1, s2),
+ "0232800b movn s0, s1, s2");
+ COMPARE(movn(t2, t3, t4),
+ "016c500b movn t2, t3, t4");
+ COMPARE(movn(v0, v1, a2),
+ "0066100b movn v0, v1, a2");
+
+ COMPARE(movt(a0, a1, 1),
+ "00a52001 movt a0, a1, 1");
+ COMPARE(movt(s0, s1, 2),
+ "02298001 movt s0, s1, 2");
+ COMPARE(movt(t2, t3, 3),
+ "016d5001 movt t2, t3, 3");
+ COMPARE(movt(v0, v1, 7),
+ "007d1001 movt v0, v1, 7");
+ COMPARE(movf(a0, a1, 0),
+ "00a02001 movf a0, a1, 0");
+ COMPARE(movf(s0, s1, 4),
+ "02308001 movf s0, s1, 4");
+ COMPARE(movf(t2, t3, 5),
+ "01745001 movf t2, t3, 5");
+ COMPARE(movf(v0, v1, 6),
+ "00781001 movf v0, v1, 6");
+
+ COMPARE(clz(a0, a1),
+ "70a42020 clz a0, a1");
+ COMPARE(clz(s6, s7),
+ "72f6b020 clz s6, s7");
+ COMPARE(clz(v0, v1),
+ "70621020 clz v0, v1");
+ COMPARE(ins_(a0, a1, 31, 1),
+ "7ca4ffc4 ins a0, a1, 31, 1");
+ COMPARE(ins_(s6, s7, 30, 2),
+ "7ef6ff84 ins s6, s7, 30, 2");
+ COMPARE(ins_(v0, v1, 0, 32),
+ "7c62f804 ins v0, v1, 0, 32");
+ COMPARE(ext_(a0, a1, 31, 1),
+ "7ca407c0 ext a0, a1, 31, 1");
+ COMPARE(ext_(s6, s7, 30, 2),
+ "7ef60f80 ext s6, s7, 30, 2");
+ COMPARE(ext_(v0, v1, 0, 32),
+ "7c62f800 ext v0, v1, 0, 32");
+
+ VERIFY_RUN();
+}
diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc
index 563cc4bf4..4d993af4a 100644
--- a/deps/v8/test/cctest/test-func-name-inference.cc
+++ b/deps/v8/test/cctest/test-func-name-inference.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2009 the V8 project authors. All rights reserved.
+// 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:
@@ -36,6 +36,7 @@ using ::v8::internal::CStrVector;
using ::v8::internal::Factory;
using ::v8::internal::Handle;
using ::v8::internal::Heap;
+using ::v8::internal::Isolate;
using ::v8::internal::JSFunction;
using ::v8::internal::Object;
using ::v8::internal::Runtime;
@@ -77,15 +78,20 @@ static void CheckFunctionName(v8::Handle<v8::Script> script,
// Find the position of a given func source substring in the source.
Handle<String> func_pos_str =
- Factory::NewStringFromAscii(CStrVector(func_pos_src));
- int func_pos = Runtime::StringMatch(script_src, func_pos_str, 0);
+ FACTORY->NewStringFromAscii(CStrVector(func_pos_src));
+ int func_pos = Runtime::StringMatch(Isolate::Current(),
+ script_src,
+ func_pos_str,
+ 0);
CHECK_NE(0, func_pos);
#ifdef ENABLE_DEBUGGER_SUPPORT
// Obtain SharedFunctionInfo for the function.
Object* shared_func_info_ptr =
- Runtime::FindSharedFunctionInfoInScript(i_script, func_pos);
- CHECK(shared_func_info_ptr != Heap::undefined_value());
+ Runtime::FindSharedFunctionInfoInScript(Isolate::Current(),
+ i_script,
+ func_pos);
+ CHECK(shared_func_info_ptr != HEAP->undefined_value());
Handle<SharedFunctionInfo> shared_func_info(
SharedFunctionInfo::cast(shared_func_info_ptr));
@@ -275,3 +281,83 @@ TEST(Issue380) {
"}");
CheckFunctionName(script, "return p", "");
}
+
+
+TEST(MultipleAssignments) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "var fun1 = fun2 = function () { return 1; }\n"
+ "var bar1 = bar2 = bar3 = function () { return 2; }\n"
+ "foo1 = foo2 = function () { return 3; }\n"
+ "baz1 = baz2 = baz3 = function () { return 4; }");
+ CheckFunctionName(script, "return 1", "fun2");
+ CheckFunctionName(script, "return 2", "bar3");
+ CheckFunctionName(script, "return 3", "foo2");
+ CheckFunctionName(script, "return 4", "baz3");
+}
+
+
+TEST(AsConstructorParameter) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "function Foo() {}\n"
+ "var foo = new Foo(function() { return 1; })\n"
+ "var bar = new Foo(function() { return 2; }, function() { return 3; })");
+ CheckFunctionName(script, "return 1", "");
+ CheckFunctionName(script, "return 2", "");
+ CheckFunctionName(script, "return 3", "");
+}
+
+
+TEST(FactoryHashmap) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "function createMyObj() {\n"
+ " var obj = {};\n"
+ " obj[\"method1\"] = function() { return 1; }\n"
+ " obj[\"method2\"] = function() { return 2; }\n"
+ " return obj;\n"
+ "}");
+ CheckFunctionName(script, "return 1", "obj.method1");
+ CheckFunctionName(script, "return 2", "obj.method2");
+}
+
+
+TEST(FactoryHashmapVariable) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "function createMyObj() {\n"
+ " var obj = {};\n"
+ " var methodName = \"method1\";\n"
+ " obj[methodName] = function() { return 1; }\n"
+ " methodName = \"method2\";\n"
+ " obj[methodName] = function() { return 2; }\n"
+ " return obj;\n"
+ "}");
+ // Can't infer function names statically.
+ CheckFunctionName(script, "return 1", "obj.(anonymous function)");
+ CheckFunctionName(script, "return 2", "obj.(anonymous function)");
+}
+
+
+TEST(FactoryHashmapConditional) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "function createMyObj() {\n"
+ " var obj = {};\n"
+ " obj[0 ? \"method1\" : \"method2\"] = function() { return 1; }\n"
+ " return obj;\n"
+ "}");
+ // Can't infer the function name statically.
+ CheckFunctionName(script, "return 1", "obj.(anonymous function)");
+}
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index ad242fe79..a2426cc0f 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -1,387 +1,18 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
//
// Tests for heap profiler
#ifdef ENABLE_LOGGING_AND_PROFILING
#include "v8.h"
+
+#include "cctest.h"
#include "heap-profiler.h"
#include "snapshot.h"
-#include "string-stream.h"
-#include "cctest.h"
-#include "zone-inl.h"
+#include "utils-inl.h"
#include "../include/v8-profiler.h"
namespace i = v8::internal;
-using i::ClustersCoarser;
-using i::JSObjectsCluster;
-using i::JSObjectsRetainerTree;
-using i::JSObjectsClusterTree;
-using i::RetainerHeapProfile;
-
-
-namespace {
-
-class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile {
- public:
- ConstructorHeapProfileTestHelper()
- : i::ConstructorHeapProfile(),
- f_name_(i::Factory::NewStringFromAscii(i::CStrVector("F"))),
- f_count_(0) {
- }
-
- void Call(const JSObjectsCluster& cluster,
- const i::NumberAndSizeInfo& number_and_size) {
- if (f_name_->Equals(cluster.constructor())) {
- CHECK_EQ(f_count_, 0);
- f_count_ = number_and_size.number();
- CHECK_GT(f_count_, 0);
- }
- }
-
- int f_count() { return f_count_; }
-
- private:
- i::Handle<i::String> f_name_;
- int f_count_;
-};
-
-} // namespace
-
-
-TEST(ConstructorProfile) {
- v8::HandleScope scope;
- LocalContext env;
-
- CompileRun(
- "function F() {} // A constructor\n"
- "var f1 = new F();\n"
- "var f2 = new F();\n");
-
- ConstructorHeapProfileTestHelper cons_profile;
- i::AssertNoAllocation no_alloc;
- i::HeapIterator iterator;
- for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
- cons_profile.CollectStats(obj);
- CHECK_EQ(0, cons_profile.f_count());
- cons_profile.PrintStats();
- CHECK_EQ(2, cons_profile.f_count());
-}
-
-
-static JSObjectsCluster AddHeapObjectToTree(JSObjectsRetainerTree* tree,
- i::String* constructor,
- int instance,
- JSObjectsCluster* ref1 = NULL,
- JSObjectsCluster* ref2 = NULL,
- JSObjectsCluster* ref3 = NULL) {
- JSObjectsCluster o(constructor, reinterpret_cast<i::Object*>(instance));
- JSObjectsClusterTree* o_tree = new JSObjectsClusterTree();
- JSObjectsClusterTree::Locator o_loc;
- if (ref1 != NULL) o_tree->Insert(*ref1, &o_loc);
- if (ref2 != NULL) o_tree->Insert(*ref2, &o_loc);
- if (ref3 != NULL) o_tree->Insert(*ref3, &o_loc);
- JSObjectsRetainerTree::Locator loc;
- tree->Insert(o, &loc);
- loc.set_value(o_tree);
- return o;
-}
-
-
-static void AddSelfReferenceToTree(JSObjectsRetainerTree* tree,
- JSObjectsCluster* self_ref) {
- JSObjectsRetainerTree::Locator loc;
- CHECK(tree->Find(*self_ref, &loc));
- JSObjectsClusterTree::Locator o_loc;
- CHECK_NE(NULL, loc.value());
- loc.value()->Insert(*self_ref, &o_loc);
-}
-
-
-static inline void CheckEqualsHelper(const char* file, int line,
- const char* expected_source,
- const JSObjectsCluster& expected,
- const char* value_source,
- const JSObjectsCluster& value) {
- if (JSObjectsCluster::Compare(expected, value) != 0) {
- i::HeapStringAllocator allocator;
- i::StringStream stream(&allocator);
- stream.Add("# Expected: ");
- expected.DebugPrint(&stream);
- stream.Add("\n# Found: ");
- value.DebugPrint(&stream);
- V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n%s",
- expected_source, value_source,
- *stream.ToCString());
- }
-}
-
-
-static inline void CheckNonEqualsHelper(const char* file, int line,
- const char* expected_source,
- const JSObjectsCluster& expected,
- const char* value_source,
- const JSObjectsCluster& value) {
- if (JSObjectsCluster::Compare(expected, value) == 0) {
- i::HeapStringAllocator allocator;
- i::StringStream stream(&allocator);
- stream.Add("# !Expected: ");
- expected.DebugPrint(&stream);
- stream.Add("\n# Found: ");
- value.DebugPrint(&stream);
- V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s",
- expected_source, value_source,
- *stream.ToCString());
- }
-}
-
-
-TEST(ClustersCoarserSimple) {
- v8::HandleScope scope;
- LocalContext env;
-
- i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
-
- JSObjectsRetainerTree tree;
- JSObjectsCluster function(i::Heap::function_class_symbol());
- JSObjectsCluster a(*i::Factory::NewStringFromAscii(i::CStrVector("A")));
- JSObjectsCluster b(*i::Factory::NewStringFromAscii(i::CStrVector("B")));
-
- // o1 <- Function
- JSObjectsCluster o1 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100, &function);
- // o2 <- Function
- JSObjectsCluster o2 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x200, &function);
- // o3 <- A, B
- JSObjectsCluster o3 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &a, &b);
- // o4 <- B, A
- JSObjectsCluster o4 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x400, &b, &a);
- // o5 <- A, B, Function
- JSObjectsCluster o5 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x500,
- &a, &b, &function);
-
- ClustersCoarser coarser;
- coarser.Process(&tree);
-
- CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
- CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4));
- CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3));
- CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5));
-}
-
-
-TEST(ClustersCoarserMultipleConstructors) {
- v8::HandleScope scope;
- LocalContext env;
-
- i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
-
- JSObjectsRetainerTree tree;
- JSObjectsCluster function(i::Heap::function_class_symbol());
-
- // o1 <- Function
- JSObjectsCluster o1 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100, &function);
- // a1 <- Function
- JSObjectsCluster a1 =
- AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x1000, &function);
- // o2 <- Function
- JSObjectsCluster o2 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x200, &function);
- // a2 <- Function
- JSObjectsCluster a2 =
- AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x2000, &function);
-
- ClustersCoarser coarser;
- coarser.Process(&tree);
-
- CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
- CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2));
-}
-
-
-TEST(ClustersCoarserPathsTraversal) {
- v8::HandleScope scope;
- LocalContext env;
-
- i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
-
- JSObjectsRetainerTree tree;
-
- // On the following graph:
- //
- // p
- // <- o21 <- o11 <-
- // q o
- // <- o22 <- o12 <-
- // r
- //
- // we expect that coarser will deduce equivalences: p ~ q ~ r,
- // o21 ~ o22, and o11 ~ o12.
-
- JSObjectsCluster o =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100);
- JSObjectsCluster o11 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x110, &o);
- JSObjectsCluster o12 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x120, &o);
- JSObjectsCluster o21 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x210, &o11);
- JSObjectsCluster o22 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x220, &o12);
- JSObjectsCluster p =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o21);
- JSObjectsCluster q =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o21, &o22);
- JSObjectsCluster r =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o22);
-
- ClustersCoarser coarser;
- coarser.Process(&tree);
-
- CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
- CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11));
- CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12));
- CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22));
- CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21));
- CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
- CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
- CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
- CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p));
- CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p));
-}
-
-
-TEST(ClustersCoarserSelf) {
- v8::HandleScope scope;
- LocalContext env;
-
- i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
-
- JSObjectsRetainerTree tree;
-
- // On the following graph:
- //
- // p (self-referencing)
- // <- o1 <-
- // q (self-referencing) o
- // <- o2 <-
- // r (self-referencing)
- //
- // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2;
-
- JSObjectsCluster o =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100);
- JSObjectsCluster o1 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x110, &o);
- JSObjectsCluster o2 =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x120, &o);
- JSObjectsCluster p =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o1);
- AddSelfReferenceToTree(&tree, &p);
- JSObjectsCluster q =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o1, &o2);
- AddSelfReferenceToTree(&tree, &q);
- JSObjectsCluster r =
- AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o2);
- AddSelfReferenceToTree(&tree, &r);
-
- ClustersCoarser coarser;
- coarser.Process(&tree);
-
- CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
- CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1));
- CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
- CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
- CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
- CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
- CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(p));
-}
-
-
-namespace {
-
-class RetainerProfilePrinter : public RetainerHeapProfile::Printer {
- public:
- RetainerProfilePrinter() : stream_(&allocator_), lines_(100) {}
-
- void PrintRetainers(const JSObjectsCluster& cluster,
- const i::StringStream& retainers) {
- cluster.Print(&stream_);
- stream_.Add("%s", *(retainers.ToCString()));
- stream_.Put('\0');
- }
-
- const char* GetRetainers(const char* constructor) {
- FillLines();
- const size_t cons_len = strlen(constructor);
- for (int i = 0; i < lines_.length(); ++i) {
- if (strncmp(constructor, lines_[i], cons_len) == 0 &&
- lines_[i][cons_len] == ',') {
- return lines_[i] + cons_len + 1;
- }
- }
- return NULL;
- }
-
- private:
- void FillLines() {
- if (lines_.length() > 0) return;
- stream_.Put('\0');
- stream_str_ = stream_.ToCString();
- const char* pos = *stream_str_;
- while (pos != NULL && *pos != '\0') {
- lines_.Add(pos);
- pos = strchr(pos, '\0');
- if (pos != NULL) ++pos;
- }
- }
-
- i::HeapStringAllocator allocator_;
- i::StringStream stream_;
- i::SmartPointer<const char> stream_str_;
- i::List<const char*> lines_;
-};
-
-} // namespace
-
-
-TEST(RetainerProfile) {
- v8::HandleScope scope;
- LocalContext env;
-
- CompileRun(
- "function A() {}\n"
- "function B(x) { this.x = x; }\n"
- "function C(x) { this.x1 = x; this.x2 = x; }\n"
- "var a = new A();\n"
- "var b1 = new B(a), b2 = new B(a);\n"
- "var c = new C(a);");
-
- RetainerHeapProfile ret_profile;
- i::AssertNoAllocation no_alloc;
- i::HeapIterator iterator;
- for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
- ret_profile.CollectStats(obj);
- ret_profile.CoarseAndAggregate();
- RetainerProfilePrinter printer;
- ret_profile.DebugPrintStats(&printer);
- const char* retainers_of_a = printer.GetRetainers("A");
- // The order of retainers is unspecified, so we check string length, and
- // verify each retainer separately.
- CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"),
- i::StrLength(retainers_of_a));
- CHECK(strstr(retainers_of_a, "(global property);1") != NULL);
- CHECK(strstr(retainers_of_a, "B;2") != NULL);
- CHECK(strstr(retainers_of_a, "C;2") != NULL);
- CHECK_EQ("(global property);2", printer.GetRetainers("B"));
- CHECK_EQ("(global property);1", printer.GetRetainers("C"));
-}
-
namespace {
@@ -414,8 +45,8 @@ static const v8::HeapGraphNode* GetGlobalObject(
CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount());
const v8::HeapGraphNode* global_obj =
snapshot->GetRoot()->GetChild(0)->GetToNode();
- CHECK_EQ("Object", const_cast<i::HeapEntry*>(
- reinterpret_cast<const i::HeapEntry*>(global_obj))->name());
+ CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>(
+ reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6));
return global_obj;
}
@@ -433,19 +64,6 @@ static const v8::HeapGraphNode* GetProperty(const v8::HeapGraphNode* node,
}
-static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
- v8::HeapGraphEdge::Type type,
- const char* name) {
- for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = node->GetRetainer(i);
- v8::String::AsciiValue prop_name(prop->GetName());
- if (prop->GetType() == type && strcmp(name, *prop_name) == 0)
- return true;
- }
- return false;
-}
-
-
static bool HasString(const v8::HeapGraphNode* node, const char* contents) {
for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
const v8::HeapGraphEdge* prop = node->GetChild(i);
@@ -496,56 +114,6 @@ TEST(HeapSnapshot) {
CHECK(det.has_A2);
CHECK(det.has_B2);
CHECK(det.has_C2);
-
- /*
- // Currently disabled. Too many retaining paths emerge, need to
- // reduce the amount.
-
- // Verify 'a2' object retainers. They are:
- // - (global object).a2
- // - c2.x1, c2.x2, c2[1]
- // - b2_1 and b2_2 closures: via 'x' variable
- CHECK_EQ(6, a2_node->GetRetainingPathsCount());
- bool has_global_obj_a2_ref = false;
- bool has_c2_x1_ref = false, has_c2_x2_ref = false, has_c2_1_ref = false;
- bool has_b2_1_x_ref = false, has_b2_2_x_ref = false;
- for (int i = 0; i < a2_node->GetRetainingPathsCount(); ++i) {
- const v8::HeapGraphPath* path = a2_node->GetRetainingPath(i);
- const int edges_count = path->GetEdgesCount();
- CHECK_GT(edges_count, 0);
- const v8::HeapGraphEdge* last_edge = path->GetEdge(edges_count - 1);
- v8::String::AsciiValue last_edge_name(last_edge->GetName());
- if (strcmp("a2", *last_edge_name) == 0
- && last_edge->GetType() == v8::HeapGraphEdge::kProperty) {
- has_global_obj_a2_ref = true;
- continue;
- }
- CHECK_GT(edges_count, 1);
- const v8::HeapGraphEdge* prev_edge = path->GetEdge(edges_count - 2);
- v8::String::AsciiValue prev_edge_name(prev_edge->GetName());
- if (strcmp("x1", *last_edge_name) == 0
- && last_edge->GetType() == v8::HeapGraphEdge::kProperty
- && strcmp("c2", *prev_edge_name) == 0) has_c2_x1_ref = true;
- if (strcmp("x2", *last_edge_name) == 0
- && last_edge->GetType() == v8::HeapGraphEdge::kProperty
- && strcmp("c2", *prev_edge_name) == 0) has_c2_x2_ref = true;
- if (strcmp("1", *last_edge_name) == 0
- && last_edge->GetType() == v8::HeapGraphEdge::kElement
- && strcmp("c2", *prev_edge_name) == 0) has_c2_1_ref = true;
- if (strcmp("x", *last_edge_name) == 0
- && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
- && strcmp("b2_1", *prev_edge_name) == 0) has_b2_1_x_ref = true;
- if (strcmp("x", *last_edge_name) == 0
- && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
- && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true;
- }
- CHECK(has_global_obj_a2_ref);
- CHECK(has_c2_x1_ref);
- CHECK(has_c2_x2_ref);
- CHECK(has_c2_1_ref);
- CHECK(has_b2_1_x_ref);
- CHECK(has_b2_2_x_ref);
- */
}
@@ -637,10 +205,10 @@ TEST(HeapSnapshotCodeObjects) {
// Find references to code.
const v8::HeapGraphNode* compiled_code =
- GetProperty(compiled, v8::HeapGraphEdge::kInternal, "code");
+ GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared");
CHECK_NE(NULL, compiled_code);
const v8::HeapGraphNode* lazy_code =
- GetProperty(lazy, v8::HeapGraphEdge::kInternal, "code");
+ GetProperty(lazy, v8::HeapGraphEdge::kInternal, "shared");
CHECK_NE(NULL, lazy_code);
// Verify that non-compiled code doesn't contain references to "x"
@@ -730,7 +298,7 @@ TEST(HeapEntryIdsAndGC) {
const v8::HeapSnapshot* snapshot1 =
v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
- i::Heap::CollectAllGarbage(true); // Enforce compaction.
+ HEAP->CollectAllGarbage(true); // Enforce compaction.
const v8::HeapSnapshot* snapshot2 =
v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
@@ -774,76 +342,6 @@ TEST(HeapEntryIdsAndGC) {
}
-TEST(HeapSnapshotsDiff) {
- v8::HandleScope scope;
- LocalContext env;
-
- CompileRun(
- "function A() {}\n"
- "function B(x) { this.x = x; }\n"
- "function A2(a) { for (var i = 0; i < a; ++i) this[i] = i; }\n"
- "var a = new A();\n"
- "var b = new B(a);");
- const v8::HeapSnapshot* snapshot1 =
- v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
-
- CompileRun(
- "delete a;\n"
- "b.x = null;\n"
- "var a = new A2(20);\n"
- "var b2 = new B(a);");
- const v8::HeapSnapshot* snapshot2 =
- v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
-
- const v8::HeapSnapshotsDiff* diff = snapshot1->CompareWith(snapshot2);
-
- // Verify additions: ensure that addition of A and B was detected.
- const v8::HeapGraphNode* additions_root = diff->GetAdditionsRoot();
- bool found_A = false, found_B = false;
- uint64_t s1_A_id = 0;
- for (int i = 0, count = additions_root->GetChildrenCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = additions_root->GetChild(i);
- const v8::HeapGraphNode* node = prop->GetToNode();
- if (node->GetType() == v8::HeapGraphNode::kObject) {
- v8::String::AsciiValue node_name(node->GetName());
- if (strcmp(*node_name, "A2") == 0) {
- CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "a"));
- CHECK(!found_A);
- found_A = true;
- s1_A_id = node->GetId();
- } else if (strcmp(*node_name, "B") == 0) {
- CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "b2"));
- CHECK(!found_B);
- found_B = true;
- }
- }
- }
- CHECK(found_A);
- CHECK(found_B);
-
- // Verify deletions: ensure that deletion of A was detected.
- const v8::HeapGraphNode* deletions_root = diff->GetDeletionsRoot();
- bool found_A_del = false;
- uint64_t s2_A_id = 0;
- for (int i = 0, count = deletions_root->GetChildrenCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = deletions_root->GetChild(i);
- const v8::HeapGraphNode* node = prop->GetToNode();
- if (node->GetType() == v8::HeapGraphNode::kObject) {
- v8::String::AsciiValue node_name(node->GetName());
- if (strcmp(*node_name, "A") == 0) {
- CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "a"));
- CHECK(!found_A_del);
- found_A_del = true;
- s2_A_id = node->GetId();
- }
- }
- }
- CHECK(found_A_del);
- CHECK_NE_UINT64_T(0, s1_A_id);
- CHECK(s1_A_id != s2_A_id);
-}
-
-
TEST(HeapSnapshotRootPreservedAfterSorting) {
v8::HandleScope scope;
LocalContext env;
@@ -857,116 +355,6 @@ TEST(HeapSnapshotRootPreservedAfterSorting) {
}
-static const v8::HeapGraphNode* GetChild(
- const v8::HeapGraphNode* node,
- v8::HeapGraphNode::Type type,
- const char* name,
- const v8::HeapGraphNode* after = NULL) {
- bool ignore_child = after == NULL ? false : true;
- for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = node->GetChild(i);
- const v8::HeapGraphNode* child = prop->GetToNode();
- v8::String::AsciiValue child_name(child->GetName());
- if (!ignore_child
- && child->GetType() == type
- && strcmp(name, *child_name) == 0)
- return child;
- if (after != NULL && child == after) ignore_child = false;
- }
- return NULL;
-}
-
-static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
- int element) {
- for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = node->GetRetainer(i);
- if (prop->GetType() == v8::HeapGraphEdge::kElement
- && element == prop->GetName()->Int32Value())
- return true;
- }
- return false;
-}
-
-TEST(AggregatedHeapSnapshot) {
- v8::HandleScope scope;
- LocalContext env;
-
- CompileRun(
- "function A() {}\n"
- "function B(x) { this.x = x; }\n"
- "var a = new A();\n"
- "var b = new B(a);");
- const v8::HeapSnapshot* snapshot =
- v8::HeapProfiler::TakeSnapshot(
- v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
- const v8::HeapGraphNode* strings = GetChild(snapshot->GetRoot(),
- v8::HeapGraphNode::kHidden,
- "STRING_TYPE");
- CHECK_NE(NULL, strings);
- CHECK_NE(0, strings->GetSelfSize());
- CHECK_NE(0, strings->GetInstancesCount());
- const v8::HeapGraphNode* maps = GetChild(snapshot->GetRoot(),
- v8::HeapGraphNode::kHidden,
- "MAP_TYPE");
- CHECK_NE(NULL, maps);
- CHECK_NE(0, maps->GetSelfSize());
- CHECK_NE(0, maps->GetInstancesCount());
-
- const v8::HeapGraphNode* a = GetChild(snapshot->GetRoot(),
- v8::HeapGraphNode::kObject,
- "A");
- CHECK_NE(NULL, a);
- CHECK_NE(0, a->GetSelfSize());
- CHECK_EQ(1, a->GetInstancesCount());
-
- const v8::HeapGraphNode* b = GetChild(snapshot->GetRoot(),
- v8::HeapGraphNode::kObject,
- "B");
- CHECK_NE(NULL, b);
- CHECK_NE(0, b->GetSelfSize());
- CHECK_EQ(1, b->GetInstancesCount());
-
- const v8::HeapGraphNode* glob_prop = GetChild(snapshot->GetRoot(),
- v8::HeapGraphNode::kObject,
- "(global property)",
- b);
- CHECK_NE(NULL, glob_prop);
- CHECK_EQ(0, glob_prop->GetSelfSize());
- CHECK_EQ(0, glob_prop->GetInstancesCount());
- CHECK_NE(0, glob_prop->GetChildrenCount());
-
- const v8::HeapGraphNode* a_from_glob_prop = GetChild(
- glob_prop,
- v8::HeapGraphNode::kObject,
- "A");
- CHECK_NE(NULL, a_from_glob_prop);
- CHECK_EQ(0, a_from_glob_prop->GetSelfSize());
- CHECK_EQ(0, a_from_glob_prop->GetInstancesCount());
- CHECK_EQ(0, a_from_glob_prop->GetChildrenCount()); // Retains nothing.
- CHECK(IsNodeRetainedAs(a_from_glob_prop, 1)); // (global propery) has 1 ref.
-
- const v8::HeapGraphNode* b_with_children = GetChild(
- snapshot->GetRoot(),
- v8::HeapGraphNode::kObject,
- "B",
- b);
- CHECK_NE(NULL, b_with_children);
- CHECK_EQ(0, b_with_children->GetSelfSize());
- CHECK_EQ(0, b_with_children->GetInstancesCount());
- CHECK_NE(0, b_with_children->GetChildrenCount());
-
- const v8::HeapGraphNode* a_from_b = GetChild(
- b_with_children,
- v8::HeapGraphNode::kObject,
- "A");
- CHECK_NE(NULL, a_from_b);
- CHECK_EQ(0, a_from_b->GetSelfSize());
- CHECK_EQ(0, a_from_b->GetInstancesCount());
- CHECK_EQ(0, a_from_b->GetChildrenCount()); // Retains nothing.
- CHECK(IsNodeRetainedAs(a_from_b, 1)); // B has 1 ref to A.
-}
-
-
TEST(HeapEntryDominator) {
// The graph looks like this:
//
@@ -1179,21 +567,6 @@ TEST(HeapSnapshotJSONSerializationAborting) {
}
-// Must not crash in debug mode.
-TEST(AggregatedHeapSnapshotJSONSerialization) {
- v8::HandleScope scope;
- LocalContext env;
-
- const v8::HeapSnapshot* snapshot =
- v8::HeapProfiler::TakeSnapshot(
- v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
- TestJSONStream stream;
- snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
- CHECK_GT(stream.size(), 0);
- CHECK_EQ(1, stream.eos_signaled());
-}
-
-
TEST(HeapSnapshotGetNodeById) {
v8::HandleScope scope;
LocalContext env;
@@ -1258,4 +631,267 @@ TEST(TakeHeapSnapshotAborting) {
CHECK_GT(control.total(), 0);
}
+
+namespace {
+
+class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
+ public:
+ TestRetainedObjectInfo(int hash,
+ const char* label,
+ intptr_t element_count = -1,
+ intptr_t size = -1)
+ : disposed_(false),
+ hash_(hash),
+ label_(label),
+ element_count_(element_count),
+ size_(size) {
+ instances.Add(this);
+ }
+ virtual ~TestRetainedObjectInfo() {}
+ virtual void Dispose() {
+ CHECK(!disposed_);
+ disposed_ = true;
+ }
+ virtual bool IsEquivalent(RetainedObjectInfo* other) {
+ return GetHash() == other->GetHash();
+ }
+ virtual intptr_t GetHash() { return hash_; }
+ virtual const char* GetLabel() { return label_; }
+ virtual intptr_t GetElementCount() { return element_count_; }
+ virtual intptr_t GetSizeInBytes() { return size_; }
+ bool disposed() { return disposed_; }
+
+ static v8::RetainedObjectInfo* WrapperInfoCallback(
+ uint16_t class_id, v8::Handle<v8::Value> wrapper) {
+ if (class_id == 1) {
+ if (wrapper->IsString()) {
+ v8::String::AsciiValue ascii(wrapper);
+ if (strcmp(*ascii, "AAA") == 0)
+ return new TestRetainedObjectInfo(1, "aaa", 100);
+ else if (strcmp(*ascii, "BBB") == 0)
+ return new TestRetainedObjectInfo(1, "aaa", 100);
+ }
+ } else if (class_id == 2) {
+ if (wrapper->IsString()) {
+ v8::String::AsciiValue ascii(wrapper);
+ if (strcmp(*ascii, "CCC") == 0)
+ return new TestRetainedObjectInfo(2, "ccc");
+ }
+ }
+ CHECK(false);
+ return NULL;
+ }
+
+ static i::List<TestRetainedObjectInfo*> instances;
+
+ private:
+ bool disposed_;
+ int category_;
+ int hash_;
+ const char* label_;
+ intptr_t element_count_;
+ intptr_t size_;
+};
+
+
+i::List<TestRetainedObjectInfo*> TestRetainedObjectInfo::instances;
+}
+
+
+static const v8::HeapGraphNode* GetNode(const v8::HeapGraphNode* parent,
+ v8::HeapGraphNode::Type type,
+ const char* name) {
+ for (int i = 0, count = parent->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphNode* node = parent->GetChild(i)->GetToNode();
+ if (node->GetType() == type && strcmp(name,
+ const_cast<i::HeapEntry*>(
+ reinterpret_cast<const i::HeapEntry*>(node))->name()) == 0) {
+ return node;
+ }
+ }
+ return NULL;
+}
+
+
+TEST(HeapSnapshotRetainedObjectInfo) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ v8::HeapProfiler::DefineWrapperClass(
+ 1, TestRetainedObjectInfo::WrapperInfoCallback);
+ v8::HeapProfiler::DefineWrapperClass(
+ 2, TestRetainedObjectInfo::WrapperInfoCallback);
+ v8::Persistent<v8::String> p_AAA =
+ v8::Persistent<v8::String>::New(v8_str("AAA"));
+ p_AAA.SetWrapperClassId(1);
+ v8::Persistent<v8::String> p_BBB =
+ v8::Persistent<v8::String>::New(v8_str("BBB"));
+ p_BBB.SetWrapperClassId(1);
+ v8::Persistent<v8::String> p_CCC =
+ v8::Persistent<v8::String>::New(v8_str("CCC"));
+ p_CCC.SetWrapperClassId(2);
+ CHECK_EQ(0, TestRetainedObjectInfo::instances.length());
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("retained"));
+
+ CHECK_EQ(3, TestRetainedObjectInfo::instances.length());
+ for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) {
+ CHECK(TestRetainedObjectInfo::instances[i]->disposed());
+ delete TestRetainedObjectInfo::instances[i];
+ }
+
+ const v8::HeapGraphNode* natives = GetNode(
+ snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(Native objects)");
+ CHECK_NE(NULL, natives);
+ CHECK_EQ(2, natives->GetChildrenCount());
+ const v8::HeapGraphNode* aaa = GetNode(
+ natives, v8::HeapGraphNode::kNative, "aaa / 100 entries");
+ CHECK_NE(NULL, aaa);
+ const v8::HeapGraphNode* ccc = GetNode(
+ natives, v8::HeapGraphNode::kNative, "ccc");
+ CHECK_NE(NULL, ccc);
+
+ CHECK_EQ(2, aaa->GetChildrenCount());
+ const v8::HeapGraphNode* n_AAA = GetNode(
+ aaa, v8::HeapGraphNode::kString, "AAA");
+ CHECK_NE(NULL, n_AAA);
+ const v8::HeapGraphNode* n_BBB = GetNode(
+ aaa, v8::HeapGraphNode::kString, "BBB");
+ CHECK_NE(NULL, n_BBB);
+ CHECK_EQ(1, ccc->GetChildrenCount());
+ const v8::HeapGraphNode* n_CCC = GetNode(
+ ccc, v8::HeapGraphNode::kString, "CCC");
+ CHECK_NE(NULL, n_CCC);
+
+ CHECK_EQ(aaa, GetProperty(n_AAA, v8::HeapGraphEdge::kInternal, "native"));
+ CHECK_EQ(aaa, GetProperty(n_BBB, v8::HeapGraphEdge::kInternal, "native"));
+ CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "native"));
+}
+
+
+TEST(DeleteAllHeapSnapshots) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+ v8::HeapProfiler::DeleteAllSnapshots();
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+ CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("1")));
+ CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
+ v8::HeapProfiler::DeleteAllSnapshots();
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+ CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("1")));
+ CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("2")));
+ CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount());
+ v8::HeapProfiler::DeleteAllSnapshots();
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+}
+
+
+TEST(DeleteHeapSnapshot) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+ const v8::HeapSnapshot* s1 =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("1"));
+ CHECK_NE(NULL, s1);
+ CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
+ unsigned uid1 = s1->GetUid();
+ CHECK_EQ(s1, v8::HeapProfiler::FindSnapshot(uid1));
+ const_cast<v8::HeapSnapshot*>(s1)->Delete();
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+ CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid1));
+
+ const v8::HeapSnapshot* s2 =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("2"));
+ CHECK_NE(NULL, s2);
+ CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
+ unsigned uid2 = s2->GetUid();
+ CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2));
+ CHECK_EQ(s2, v8::HeapProfiler::FindSnapshot(uid2));
+ const v8::HeapSnapshot* s3 =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("3"));
+ CHECK_NE(NULL, s3);
+ CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount());
+ unsigned uid3 = s3->GetUid();
+ CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3));
+ CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3));
+ const_cast<v8::HeapSnapshot*>(s2)->Delete();
+ CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
+ CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2));
+ CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3));
+ const_cast<v8::HeapSnapshot*>(s3)->Delete();
+ CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
+ CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3));
+}
+
+
+TEST(DocumentURL) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun("document = { URL:\"abcdefgh\" };");
+
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("document"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ CHECK_NE(NULL, global);
+ CHECK_EQ("Object / abcdefgh",
+ const_cast<i::HeapEntry*>(
+ reinterpret_cast<const i::HeapEntry*>(global))->name());
+}
+
+
+TEST(DocumentWithException) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun(
+ "this.__defineGetter__(\"document\", function() { throw new Error(); })");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("document"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ CHECK_NE(NULL, global);
+ CHECK_EQ("Object",
+ const_cast<i::HeapEntry*>(
+ reinterpret_cast<const i::HeapEntry*>(global))->name());
+}
+
+
+TEST(DocumentURLWithException) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun(
+ "function URLWithException() {}\n"
+ "URLWithException.prototype = { get URL() { throw new Error(); } };\n"
+ "document = { URL: new URLWithException() };");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("document"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ CHECK_NE(NULL, global);
+ CHECK_EQ("Object",
+ const_cast<i::HeapEntry*>(
+ reinterpret_cast<const i::HeapEntry*>(global))->name());
+}
+
+
+TEST(NodesIteration) {
+ v8::HandleScope scope;
+ LocalContext env;
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8::String::New("iteration"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ CHECK_NE(NULL, global);
+ // Verify that we can find this object by iteration.
+ const int nodes_count = snapshot->GetNodesCount();
+ int count = 0;
+ for (int i = 0; i < nodes_count; ++i) {
+ if (snapshot->GetNode(i) == global)
+ ++count;
+ }
+ CHECK_EQ(1, count);
+}
+
#endif // ENABLE_LOGGING_AND_PROFILING
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 9cce01eae..fac9f0a1b 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -24,9 +24,9 @@ static void InitializeVM() {
static void CheckMap(Map* map, int type, int instance_size) {
CHECK(map->IsHeapObject());
#ifdef DEBUG
- CHECK(Heap::Contains(map));
+ CHECK(HEAP->Contains(map));
#endif
- CHECK_EQ(Heap::meta_map(), map->map());
+ CHECK_EQ(HEAP->meta_map(), map->map());
CHECK_EQ(type, map->instance_type());
CHECK_EQ(instance_size, map->instance_size());
}
@@ -34,10 +34,10 @@ static void CheckMap(Map* map, int type, int instance_size) {
TEST(HeapMaps) {
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);
+ 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);
}
@@ -58,7 +58,7 @@ static void CheckSmi(int value, const char* string) {
static void CheckNumber(double value, const char* string) {
- Object* obj = Heap::NumberFromDouble(value)->ToObjectChecked();
+ Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked();
CHECK(obj->IsNumber());
bool exc;
Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc);
@@ -70,33 +70,33 @@ static void CheckFindCodeObject() {
// Test FindCodeObject
#define __ assm.
- Assembler assm(NULL, 0);
+ Assembler assm(Isolate::Current(), NULL, 0);
__ nop(); // supported on all architectures
CodeDesc desc;
assm.GetCode(&desc);
- Object* code = Heap::CreateCode(
+ Object* code = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(code->IsCode());
HeapObject* obj = HeapObject::cast(code);
Address obj_addr = obj->address();
for (int i = 0; i < obj->Size(); i += kPointerSize) {
- Object* found = Heap::FindCodeObject(obj_addr + i);
+ Object* found = HEAP->FindCodeObject(obj_addr + i);
CHECK_EQ(code, found);
}
- Object* copy = Heap::CreateCode(
+ Object* copy = HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
- Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
CHECK(copy->IsCode());
HeapObject* obj_copy = HeapObject::cast(copy);
- Object* not_right = Heap::FindCodeObject(obj_copy->address() +
+ Object* not_right = HEAP->FindCodeObject(obj_copy->address() +
obj_copy->Size() / 2);
CHECK(not_right != code);
}
@@ -106,41 +106,41 @@ TEST(HeapObjects) {
InitializeVM();
v8::HandleScope sc;
- Object* value = Heap::NumberFromDouble(1.000123)->ToObjectChecked();
+ Object* value = HEAP->NumberFromDouble(1.000123)->ToObjectChecked();
CHECK(value->IsHeapNumber());
CHECK(value->IsNumber());
CHECK_EQ(1.000123, value->Number());
- value = Heap::NumberFromDouble(1.0)->ToObjectChecked();
+ value = HEAP->NumberFromDouble(1.0)->ToObjectChecked();
CHECK(value->IsSmi());
CHECK(value->IsNumber());
CHECK_EQ(1.0, value->Number());
- value = Heap::NumberFromInt32(1024)->ToObjectChecked();
+ value = HEAP->NumberFromInt32(1024)->ToObjectChecked();
CHECK(value->IsSmi());
CHECK(value->IsNumber());
CHECK_EQ(1024.0, value->Number());
- value = Heap::NumberFromInt32(Smi::kMinValue)->ToObjectChecked();
+ value = HEAP->NumberFromInt32(Smi::kMinValue)->ToObjectChecked();
CHECK(value->IsSmi());
CHECK(value->IsNumber());
CHECK_EQ(Smi::kMinValue, Smi::cast(value)->value());
- value = Heap::NumberFromInt32(Smi::kMaxValue)->ToObjectChecked();
+ value = HEAP->NumberFromInt32(Smi::kMaxValue)->ToObjectChecked();
CHECK(value->IsSmi());
CHECK(value->IsNumber());
CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value());
#ifndef V8_TARGET_ARCH_X64
// TODO(lrn): We need a NumberFromIntptr function in order to test this.
- value = Heap::NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked();
+ value = HEAP->NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked();
CHECK(value->IsHeapNumber());
CHECK(value->IsNumber());
CHECK_EQ(static_cast<double>(Smi::kMinValue - 1), value->Number());
#endif
MaybeObject* maybe_value =
- Heap::NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1);
+ HEAP->NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1);
value = maybe_value->ToObjectChecked();
CHECK(value->IsHeapNumber());
CHECK(value->IsNumber());
@@ -148,21 +148,22 @@ TEST(HeapObjects) {
value->Number());
// nan oddball checks
- CHECK(Heap::nan_value()->IsNumber());
- CHECK(isnan(Heap::nan_value()->Number()));
+ CHECK(HEAP->nan_value()->IsNumber());
+ CHECK(isnan(HEAP->nan_value()->Number()));
- Handle<String> s = Factory::NewStringFromAscii(CStrVector("fisk hest "));
+ Handle<String> s = FACTORY->NewStringFromAscii(CStrVector("fisk hest "));
CHECK(s->IsString());
CHECK_EQ(10, s->length());
- String* object_symbol = String::cast(Heap::Object_symbol());
- CHECK(Top::context()->global()->HasLocalProperty(object_symbol));
+ String* object_symbol = String::cast(HEAP->Object_symbol());
+ CHECK(
+ Isolate::Current()->context()->global()->HasLocalProperty(object_symbol));
// Check ToString for oddballs
- CheckOddball(Heap::true_value(), "true");
- CheckOddball(Heap::false_value(), "false");
- CheckOddball(Heap::null_value(), "null");
- CheckOddball(Heap::undefined_value(), "undefined");
+ CheckOddball(HEAP->true_value(), "true");
+ CheckOddball(HEAP->false_value(), "false");
+ CheckOddball(HEAP->null_value(), "null");
+ CheckOddball(HEAP->undefined_value(), "undefined");
// Check ToString for Smis
CheckSmi(0, "0");
@@ -197,25 +198,25 @@ TEST(GarbageCollection) {
v8::HandleScope sc;
// Check GC.
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
- Handle<String> name = Factory::LookupAsciiSymbol("theFunction");
- Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot");
- Handle<String> prop_namex = Factory::LookupAsciiSymbol("theSlotx");
- Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject");
+ Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction");
+ Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot");
+ Handle<String> prop_namex = FACTORY->LookupAsciiSymbol("theSlotx");
+ Handle<String> obj_name = FACTORY->LookupAsciiSymbol("theObject");
{
v8::HandleScope inner_scope;
// Allocate a function and keep it in global object's property.
Handle<JSFunction> function =
- Factory::NewFunction(name, Factory::undefined_value());
+ FACTORY->NewFunction(name, FACTORY->undefined_value());
Handle<Map> initial_map =
- Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
function->set_initial_map(*initial_map);
- Top::context()->global()->SetProperty(
+ Isolate::Current()->context()->global()->SetProperty(
*name, *function, NONE, kNonStrictMode)->ToObjectChecked();
// Allocate an object. Unrooted after leaving the scope.
- Handle<JSObject> obj = Factory::NewJSObject(function);
+ Handle<JSObject> obj = FACTORY->NewJSObject(function);
obj->SetProperty(
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
obj->SetProperty(
@@ -225,34 +226,34 @@ TEST(GarbageCollection) {
CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex));
}
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
// Function should be alive.
- CHECK(Top::context()->global()->HasLocalProperty(*name));
+ CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*name));
// Check function is retained.
- Object* func_value =
- Top::context()->global()->GetProperty(*name)->ToObjectChecked();
+ Object* func_value = Isolate::Current()->context()->global()->
+ GetProperty(*name)->ToObjectChecked();
CHECK(func_value->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(func_value));
{
HandleScope inner_scope;
// Allocate another object, make it reachable from global.
- Handle<JSObject> obj = Factory::NewJSObject(function);
- Top::context()->global()->SetProperty(
+ Handle<JSObject> obj = FACTORY->NewJSObject(function);
+ Isolate::Current()->context()->global()->SetProperty(
*obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked();
obj->SetProperty(
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
}
// After gc, it should survive.
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
- CHECK(Top::context()->global()->HasLocalProperty(*obj_name));
- CHECK(Top::context()->global()->GetProperty(*obj_name)->ToObjectChecked()->
- IsJSObject());
- Object* obj =
- Top::context()->global()->GetProperty(*obj_name)->ToObjectChecked();
+ CHECK(Isolate::Current()->context()->global()->HasLocalProperty(*obj_name));
+ CHECK(Isolate::Current()->context()->global()->
+ GetProperty(*obj_name)->ToObjectChecked()->IsJSObject());
+ Object* obj = Isolate::Current()->context()->global()->
+ GetProperty(*obj_name)->ToObjectChecked();
JSObject* js_obj = JSObject::cast(obj);
CHECK_EQ(Smi::FromInt(23), js_obj->GetProperty(*prop_name));
}
@@ -260,7 +261,7 @@ TEST(GarbageCollection) {
static void VerifyStringAllocation(const char* string) {
v8::HandleScope scope;
- Handle<String> s = Factory::NewStringFromUtf8(CStrVector(string));
+ Handle<String> s = FACTORY->NewStringFromUtf8(CStrVector(string));
CHECK_EQ(StrLength(string), s->length());
for (int index = 0; index < s->length(); index++) {
CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index));
@@ -284,12 +285,13 @@ TEST(LocalHandles) {
v8::HandleScope scope;
const char* name = "Kasper the spunky";
- Handle<String> string = Factory::NewStringFromAscii(CStrVector(name));
+ Handle<String> string = FACTORY->NewStringFromAscii(CStrVector(name));
CHECK_EQ(StrLength(name), string->length());
}
TEST(GlobalHandles) {
+ GlobalHandles* global_handles = Isolate::Current()->global_handles();
InitializeVM();
Handle<Object> h1;
@@ -300,17 +302,17 @@ TEST(GlobalHandles) {
{
HandleScope scope;
- Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk"));
- Handle<Object> u = Factory::NewNumber(1.12344);
+ Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
+ Handle<Object> u = FACTORY->NewNumber(1.12344);
- h1 = GlobalHandles::Create(*i);
- h2 = GlobalHandles::Create(*u);
- h3 = GlobalHandles::Create(*i);
- h4 = GlobalHandles::Create(*u);
+ h1 = global_handles->Create(*i);
+ h2 = global_handles->Create(*u);
+ h3 = global_handles->Create(*i);
+ h4 = global_handles->Create(*u);
}
// after gc, it should survive
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
CHECK((*h1)->IsString());
CHECK((*h2)->IsHeapNumber());
@@ -318,12 +320,12 @@ TEST(GlobalHandles) {
CHECK((*h4)->IsHeapNumber());
CHECK_EQ(*h3, *h1);
- GlobalHandles::Destroy(h1.location());
- GlobalHandles::Destroy(h3.location());
+ global_handles->Destroy(h1.location());
+ global_handles->Destroy(h3.location());
CHECK_EQ(*h4, *h2);
- GlobalHandles::Destroy(h2.location());
- GlobalHandles::Destroy(h4.location());
+ global_handles->Destroy(h2.location());
+ global_handles->Destroy(h4.location());
}
@@ -337,6 +339,7 @@ static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle,
TEST(WeakGlobalHandlesScavenge) {
+ GlobalHandles* global_handles = Isolate::Current()->global_handles();
InitializeVM();
WeakPointerCleared = false;
@@ -347,33 +350,34 @@ TEST(WeakGlobalHandlesScavenge) {
{
HandleScope scope;
- Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk"));
- Handle<Object> u = Factory::NewNumber(1.12344);
+ Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
+ Handle<Object> u = FACTORY->NewNumber(1.12344);
- h1 = GlobalHandles::Create(*i);
- h2 = GlobalHandles::Create(*u);
+ h1 = global_handles->Create(*i);
+ h2 = global_handles->Create(*u);
}
- GlobalHandles::MakeWeak(h2.location(),
- reinterpret_cast<void*>(1234),
- &TestWeakGlobalHandleCallback);
+ global_handles->MakeWeak(h2.location(),
+ reinterpret_cast<void*>(1234),
+ &TestWeakGlobalHandleCallback);
// Scavenge treats weak pointers as normal roots.
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK((*h1)->IsString());
CHECK((*h2)->IsHeapNumber());
CHECK(!WeakPointerCleared);
- CHECK(!GlobalHandles::IsNearDeath(h2.location()));
- CHECK(!GlobalHandles::IsNearDeath(h1.location()));
+ CHECK(!global_handles->IsNearDeath(h2.location()));
+ CHECK(!global_handles->IsNearDeath(h1.location()));
- GlobalHandles::Destroy(h1.location());
- GlobalHandles::Destroy(h2.location());
+ global_handles->Destroy(h1.location());
+ global_handles->Destroy(h2.location());
}
TEST(WeakGlobalHandlesMark) {
+ GlobalHandles* global_handles = Isolate::Current()->global_handles();
InitializeVM();
WeakPointerCleared = false;
@@ -384,34 +388,35 @@ TEST(WeakGlobalHandlesMark) {
{
HandleScope scope;
- Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk"));
- Handle<Object> u = Factory::NewNumber(1.12344);
+ Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
+ Handle<Object> u = FACTORY->NewNumber(1.12344);
- h1 = GlobalHandles::Create(*i);
- h2 = GlobalHandles::Create(*u);
+ h1 = global_handles->Create(*i);
+ h2 = global_handles->Create(*u);
}
- Heap::CollectGarbage(OLD_POINTER_SPACE);
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
// Make sure the object is promoted.
- GlobalHandles::MakeWeak(h2.location(),
- reinterpret_cast<void*>(1234),
- &TestWeakGlobalHandleCallback);
+ global_handles->MakeWeak(h2.location(),
+ reinterpret_cast<void*>(1234),
+ &TestWeakGlobalHandleCallback);
CHECK(!GlobalHandles::IsNearDeath(h1.location()));
CHECK(!GlobalHandles::IsNearDeath(h2.location()));
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
CHECK((*h1)->IsString());
CHECK(WeakPointerCleared);
CHECK(!GlobalHandles::IsNearDeath(h1.location()));
- GlobalHandles::Destroy(h1.location());
+ global_handles->Destroy(h1.location());
}
TEST(DeleteWeakGlobalHandle) {
+ GlobalHandles* global_handles = Isolate::Current()->global_handles();
InitializeVM();
WeakPointerCleared = false;
@@ -421,21 +426,21 @@ TEST(DeleteWeakGlobalHandle) {
{
HandleScope scope;
- Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk"));
- h = GlobalHandles::Create(*i);
+ Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk"));
+ h = global_handles->Create(*i);
}
- GlobalHandles::MakeWeak(h.location(),
- reinterpret_cast<void*>(1234),
- &TestWeakGlobalHandleCallback);
+ global_handles->MakeWeak(h.location(),
+ reinterpret_cast<void*>(1234),
+ &TestWeakGlobalHandleCallback);
// Scanvenge does not recognize weak reference.
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK(!WeakPointerCleared);
// Mark-compact treats weak reference properly.
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
CHECK(WeakPointerCleared);
}
@@ -507,12 +512,12 @@ static const char* not_so_random_string_table[] = {
static void CheckSymbols(const char** strings) {
for (const char* string = *strings; *strings != 0; string = *strings++) {
Object* a;
- MaybeObject* maybe_a = Heap::LookupAsciiSymbol(string);
+ MaybeObject* maybe_a = HEAP->LookupAsciiSymbol(string);
// LookupAsciiSymbol may return a failure if a GC is needed.
if (!maybe_a->ToObject(&a)) continue;
CHECK(a->IsSymbol());
Object* b;
- MaybeObject *maybe_b = Heap::LookupAsciiSymbol(string);
+ MaybeObject* maybe_b = HEAP->LookupAsciiSymbol(string);
if (!maybe_b->ToObject(&b)) continue;
CHECK_EQ(b, a);
CHECK(String::cast(b)->IsEqualTo(CStrVector(string)));
@@ -532,15 +537,15 @@ TEST(FunctionAllocation) {
InitializeVM();
v8::HandleScope sc;
- Handle<String> name = Factory::LookupAsciiSymbol("theFunction");
+ Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction");
Handle<JSFunction> function =
- Factory::NewFunction(name, Factory::undefined_value());
+ FACTORY->NewFunction(name, FACTORY->undefined_value());
Handle<Map> initial_map =
- Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
function->set_initial_map(*initial_map);
- Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot");
- Handle<JSObject> obj = Factory::NewJSObject(function);
+ Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot");
+ Handle<JSObject> obj = FACTORY->NewJSObject(function);
obj->SetProperty(
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
@@ -555,14 +560,14 @@ TEST(ObjectProperties) {
InitializeVM();
v8::HandleScope sc;
- String* object_symbol = String::cast(Heap::Object_symbol());
- Object* raw_object =
- Top::context()->global()->GetProperty(object_symbol)->ToObjectChecked();
+ String* object_symbol = String::cast(HEAP->Object_symbol());
+ Object* raw_object = Isolate::Current()->context()->global()->
+ GetProperty(object_symbol)->ToObjectChecked();
JSFunction* object_function = JSFunction::cast(raw_object);
Handle<JSFunction> constructor(object_function);
- Handle<JSObject> obj = Factory::NewJSObject(constructor);
- Handle<String> first = Factory::LookupAsciiSymbol("first");
- Handle<String> second = Factory::LookupAsciiSymbol("second");
+ Handle<JSObject> obj = FACTORY->NewJSObject(constructor);
+ Handle<String> first = FACTORY->LookupAsciiSymbol("first");
+ Handle<String> second = FACTORY->LookupAsciiSymbol("second");
// check for empty
CHECK(!obj->HasLocalProperty(*first));
@@ -608,18 +613,18 @@ TEST(ObjectProperties) {
// check string and symbol match
static const char* string1 = "fisk";
- Handle<String> s1 = Factory::NewStringFromAscii(CStrVector(string1));
+ Handle<String> s1 = FACTORY->NewStringFromAscii(CStrVector(string1));
obj->SetProperty(
*s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
- Handle<String> s1_symbol = Factory::LookupAsciiSymbol(string1);
+ Handle<String> s1_symbol = FACTORY->LookupAsciiSymbol(string1);
CHECK(obj->HasLocalProperty(*s1_symbol));
// check symbol and string match
static const char* string2 = "fugl";
- Handle<String> s2_symbol = Factory::LookupAsciiSymbol(string2);
+ Handle<String> s2_symbol = FACTORY->LookupAsciiSymbol(string2);
obj->SetProperty(
*s2_symbol, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
- Handle<String> s2 = Factory::NewStringFromAscii(CStrVector(string2));
+ Handle<String> s2 = FACTORY->NewStringFromAscii(CStrVector(string2));
CHECK(obj->HasLocalProperty(*s2));
}
@@ -628,15 +633,15 @@ TEST(JSObjectMaps) {
InitializeVM();
v8::HandleScope sc;
- Handle<String> name = Factory::LookupAsciiSymbol("theFunction");
+ Handle<String> name = FACTORY->LookupAsciiSymbol("theFunction");
Handle<JSFunction> function =
- Factory::NewFunction(name, Factory::undefined_value());
+ FACTORY->NewFunction(name, FACTORY->undefined_value());
Handle<Map> initial_map =
- Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
function->set_initial_map(*initial_map);
- Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot");
- Handle<JSObject> obj = Factory::NewJSObject(function);
+ Handle<String> prop_name = FACTORY->LookupAsciiSymbol("theSlot");
+ Handle<JSObject> obj = FACTORY->NewJSObject(function);
// Set a propery
obj->SetProperty(
@@ -652,14 +657,14 @@ TEST(JSArray) {
InitializeVM();
v8::HandleScope sc;
- Handle<String> name = Factory::LookupAsciiSymbol("Array");
- Object* raw_object =
- Top::context()->global()->GetProperty(*name)->ToObjectChecked();
+ Handle<String> name = FACTORY->LookupAsciiSymbol("Array");
+ Object* raw_object = Isolate::Current()->context()->global()->
+ GetProperty(*name)->ToObjectChecked();
Handle<JSFunction> function = Handle<JSFunction>(
JSFunction::cast(raw_object));
// Allocate the object.
- Handle<JSObject> object = Factory::NewJSObject(function);
+ Handle<JSObject> object = FACTORY->NewJSObject(function);
Handle<JSArray> array = Handle<JSArray>::cast(object);
// We just initialized the VM, no heap allocation failure yet.
Object* ok = array->Initialize(0)->ToObjectChecked();
@@ -670,13 +675,13 @@ TEST(JSArray) {
CHECK(array->HasFastElements()); // Must be in fast mode.
// array[length] = name.
- ok = array->SetElement(0, *name)->ToObjectChecked();
+ ok = array->SetElement(0, *name, kNonStrictMode, true)->ToObjectChecked();
CHECK_EQ(Smi::FromInt(1), array->length());
CHECK_EQ(array->GetElement(0), *name);
// Set array length with larger than smi value.
Handle<Object> length =
- Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
+ FACTORY->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
ok = array->SetElementsLength(*length)->ToObjectChecked();
uint32_t int_length = 0;
@@ -685,7 +690,8 @@ TEST(JSArray) {
CHECK(array->HasDictionaryElements()); // Must be in slow mode.
// array[length] = name.
- ok = array->SetElement(int_length, *name)->ToObjectChecked();
+ ok = array->SetElement(
+ int_length, *name, kNonStrictMode, true)->ToObjectChecked();
uint32_t new_int_length = 0;
CHECK(array->length()->ToArrayIndex(&new_int_length));
CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
@@ -698,23 +704,24 @@ TEST(JSObjectCopy) {
InitializeVM();
v8::HandleScope sc;
- String* object_symbol = String::cast(Heap::Object_symbol());
- Object* raw_object =
- Top::context()->global()->GetProperty(object_symbol)->ToObjectChecked();
+ String* object_symbol = String::cast(HEAP->Object_symbol());
+ Object* raw_object = Isolate::Current()->context()->global()->
+ GetProperty(object_symbol)->ToObjectChecked();
JSFunction* object_function = JSFunction::cast(raw_object);
Handle<JSFunction> constructor(object_function);
- Handle<JSObject> obj = Factory::NewJSObject(constructor);
- Handle<String> first = Factory::LookupAsciiSymbol("first");
- Handle<String> second = Factory::LookupAsciiSymbol("second");
+ Handle<JSObject> obj = FACTORY->NewJSObject(constructor);
+ Handle<String> first = FACTORY->LookupAsciiSymbol("first");
+ Handle<String> second = FACTORY->LookupAsciiSymbol("second");
obj->SetProperty(
*first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
obj->SetProperty(
*second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
- Object* ok = obj->SetElement(0, *first)->ToObjectChecked();
+ Object* ok =
+ obj->SetElement(0, *first, kNonStrictMode, true)->ToObjectChecked();
- ok = obj->SetElement(1, *second)->ToObjectChecked();
+ ok = obj->SetElement(1, *second, kNonStrictMode, true)->ToObjectChecked();
// Make the clone.
Handle<JSObject> clone = Copy(obj);
@@ -732,8 +739,8 @@ TEST(JSObjectCopy) {
clone->SetProperty(
*second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
- ok = clone->SetElement(0, *second)->ToObjectChecked();
- ok = clone->SetElement(1, *first)->ToObjectChecked();
+ ok = clone->SetElement(0, *second, kNonStrictMode, true)->ToObjectChecked();
+ ok = clone->SetElement(1, *first, kNonStrictMode, true)->ToObjectChecked();
CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
@@ -761,17 +768,17 @@ TEST(StringAllocation) {
non_ascii[3 * i + 2] = chars[2];
}
Handle<String> non_ascii_sym =
- Factory::LookupSymbol(Vector<const char>(non_ascii, 3 * length));
+ FACTORY->LookupSymbol(Vector<const char>(non_ascii, 3 * length));
CHECK_EQ(length, non_ascii_sym->length());
Handle<String> ascii_sym =
- Factory::LookupSymbol(Vector<const char>(ascii, length));
+ FACTORY->LookupSymbol(Vector<const char>(ascii, length));
CHECK_EQ(length, ascii_sym->length());
Handle<String> non_ascii_str =
- Factory::NewStringFromUtf8(Vector<const char>(non_ascii, 3 * length));
+ FACTORY->NewStringFromUtf8(Vector<const char>(non_ascii, 3 * length));
non_ascii_str->Hash();
CHECK_EQ(length, non_ascii_str->length());
Handle<String> ascii_str =
- Factory::NewStringFromUtf8(Vector<const char>(ascii, length));
+ FACTORY->NewStringFromUtf8(Vector<const char>(ascii, length));
ascii_str->Hash();
CHECK_EQ(length, ascii_str->length());
DeleteArray(non_ascii);
@@ -805,22 +812,22 @@ TEST(Iteration) {
int next_objs_index = 0;
// Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE
- objs[next_objs_index++] = Factory::NewJSArray(10);
- objs[next_objs_index++] = Factory::NewJSArray(10, TENURED);
+ objs[next_objs_index++] = FACTORY->NewJSArray(10);
+ objs[next_objs_index++] = FACTORY->NewJSArray(10, TENURED);
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
objs[next_objs_index++] =
- Factory::NewStringFromAscii(CStrVector("abcdefghij"));
+ FACTORY->NewStringFromAscii(CStrVector("abcdefghij"));
objs[next_objs_index++] =
- Factory::NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
+ FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
// Allocate a large string (for large object space).
- int large_size = Heap::MaxObjectSizeInPagedSpace() + 1;
+ int large_size = HEAP->MaxObjectSizeInPagedSpace() + 1;
char* str = new char[large_size];
for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
str[large_size - 1] = '\0';
objs[next_objs_index++] =
- Factory::NewStringFromAscii(CStrVector(str), TENURED);
+ FACTORY->NewStringFromAscii(CStrVector(str), TENURED);
delete[] str;
// Add a Map object to look for.
@@ -834,9 +841,9 @@ TEST(Iteration) {
TEST(LargeObjectSpaceContains) {
InitializeVM();
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
- Address current_top = Heap::new_space()->top();
+ Address current_top = HEAP->new_space()->top();
Page* page = Page::FromAddress(current_top);
Address current_page = page->address();
Address next_page = current_page + Page::kPageSize;
@@ -859,7 +866,7 @@ TEST(LargeObjectSpaceContains) {
kPointerSize;
CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements));
FixedArray* array = FixedArray::cast(
- Heap::AllocateFixedArray(n_elements)->ToObjectChecked());
+ HEAP->AllocateFixedArray(n_elements)->ToObjectChecked());
int index = n_elements - 1;
CHECK_EQ(flags_ptr,
@@ -869,8 +876,8 @@ TEST(LargeObjectSpaceContains) {
// CHECK(Page::FromAddress(next_page)->IsLargeObjectPage());
HeapObject* addr = HeapObject::FromAddress(next_page + 2 * kPointerSize);
- CHECK(Heap::new_space()->Contains(addr));
- CHECK(!Heap::lo_space()->Contains(addr));
+ CHECK(HEAP->new_space()->Contains(addr));
+ CHECK(!HEAP->lo_space()->Contains(addr));
}
@@ -901,7 +908,7 @@ TEST(Regression39128) {
// Increase the chance of 'bump-the-pointer' allocation in old space.
bool force_compaction = true;
- Heap::CollectAllGarbage(force_compaction);
+ HEAP->CollectAllGarbage(force_compaction);
v8::HandleScope scope;
@@ -910,11 +917,12 @@ TEST(Regression39128) {
// that region dirty marks are updated correctly.
// Step 1: prepare a map for the object. We add 1 inobject property to it.
- Handle<JSFunction> object_ctor(Top::global_context()->object_function());
+ Handle<JSFunction> object_ctor(
+ Isolate::Current()->global_context()->object_function());
CHECK(object_ctor->has_initial_map());
Handle<Map> object_map(object_ctor->initial_map());
// Create a map with single inobject property.
- Handle<Map> my_map = Factory::CopyMap(object_map, 1);
+ Handle<Map> my_map = FACTORY->CopyMap(object_map, 1);
int n_properties = my_map->inobject_properties();
CHECK_GT(n_properties, 0);
@@ -924,15 +932,15 @@ TEST(Regression39128) {
// just enough room to allocate JSObject and thus fill the newspace.
int allocation_amount = Min(FixedArray::kMaxSize,
- Heap::MaxObjectSizeInNewSpace());
+ HEAP->MaxObjectSizeInNewSpace());
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));
}
@@ -941,12 +949,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());
@@ -958,15 +966,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()));
// Step 5: verify validity of region dirty marks.
Address clone_addr = clone->address();
@@ -988,7 +996,7 @@ TEST(TestCodeFlushing) {
" var z = x + y;"
"};"
"foo()";
- Handle<String> foo_name = Factory::LookupAsciiSymbol("foo");
+ Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo");
// This compile will add the code to the compilation cache.
{ v8::HandleScope scope;
@@ -996,23 +1004,23 @@ TEST(TestCodeFlushing) {
}
// Check function is compiled.
- Object* func_value =
- Top::context()->global()->GetProperty(*foo_name)->ToObjectChecked();
+ Object* func_value = Isolate::Current()->context()->global()->
+ GetProperty(*foo_name)->ToObjectChecked();
CHECK(func_value->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(func_value));
CHECK(function->shared()->is_compiled());
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
CHECK(function->shared()->is_compiled());
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
// foo should no longer be in the compilation cache
CHECK(!function->shared()->is_compiled() || function->IsOptimized());
@@ -1027,7 +1035,7 @@ TEST(TestCodeFlushing) {
// Count the number of global contexts in the weak list of global contexts.
static int CountGlobalContexts() {
int count = 0;
- Object* object = Heap::global_contexts_list();
+ Object* object = HEAP->global_contexts_list();
while (!object->IsUndefined()) {
count++;
object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK);
@@ -1051,6 +1059,8 @@ static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) {
TEST(TestInternalWeakLists) {
+ v8::V8::Initialize();
+
static const int kNumTestContexts = 10;
v8::HandleScope scope;
@@ -1094,35 +1104,35 @@ TEST(TestInternalWeakLists) {
// Scavenge treats these references as strong.
for (int j = 0; j < 10; j++) {
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
}
// Mark compact handles the weak references.
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
// Get rid of f3 and f5 in the same way.
CompileRun("f3=null");
for (int j = 0; j < 10; j++) {
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
}
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
CompileRun("f5=null");
for (int j = 0; j < 10; j++) {
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
}
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
ctx[i]->Exit();
}
// Force compilation cache cleanup.
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
// Dispose the global contexts one by one.
for (int i = 0; i < kNumTestContexts; i++) {
@@ -1131,12 +1141,12 @@ TEST(TestInternalWeakLists) {
// Scavenge treats these references as strong.
for (int j = 0; j < 10; j++) {
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
}
// Mark compact handles the weak references.
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
}
@@ -1148,10 +1158,10 @@ TEST(TestInternalWeakLists) {
// causing a GC after the specified number of elements.
static int CountGlobalContextsWithGC(int n) {
int count = 0;
- Handle<Object> object(Heap::global_contexts_list());
+ Handle<Object> object(HEAP->global_contexts_list());
while (!object->IsUndefined()) {
count++;
- if (count == n) Heap::CollectAllGarbage(true);
+ if (count == n) HEAP->CollectAllGarbage(true);
object =
Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
}
@@ -1170,7 +1180,7 @@ static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
while (object->IsJSFunction() &&
!Handle<JSFunction>::cast(object)->IsBuiltin()) {
count++;
- if (count == n) Heap::CollectAllGarbage(true);
+ if (count == n) HEAP->CollectAllGarbage(true);
object = Handle<Object>(
Object::cast(JSFunction::cast(*object)->next_function_link()));
}
@@ -1179,6 +1189,8 @@ static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
TEST(TestInternalWeakListsTraverseWithGC) {
+ v8::V8::Initialize();
+
static const int kNumTestContexts = 10;
v8::HandleScope scope;
@@ -1228,7 +1240,7 @@ TEST(TestInternalWeakListsTraverseWithGC) {
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
InitializeVM();
- intptr_t size_of_objects_1 = Heap::SizeOfObjects();
+ intptr_t size_of_objects_1 = HEAP->SizeOfObjects();
HeapIterator iterator(HeapIterator::kFilterFreeListNodes);
intptr_t size_of_objects_2 = 0;
for (HeapObject* obj = iterator.next();
@@ -1283,10 +1295,10 @@ TEST(HeapIteratorFilterUnreachable) {
InitializeVM();
v8::HandleScope scope;
CompileRun("a = {}; b = {};");
- v8::Handle<Object> a(Top::context()->global()->GetProperty(
- *Factory::LookupAsciiSymbol("a"))->ToObjectChecked());
- v8::Handle<Object> b(Top::context()->global()->GetProperty(
- *Factory::LookupAsciiSymbol("b"))->ToObjectChecked());
+ v8::Handle<Object> a(ISOLATE->context()->global()->GetProperty(
+ *FACTORY->LookupAsciiSymbol("a"))->ToObjectChecked());
+ v8::Handle<Object> b(ISOLATE->context()->global()->GetProperty(
+ *FACTORY->LookupAsciiSymbol("b"))->ToObjectChecked());
CHECK_NE(*a, *b);
{
HeapIteratorTestHelper helper(*a, *b);
@@ -1294,8 +1306,8 @@ TEST(HeapIteratorFilterUnreachable) {
CHECK(helper.a_found());
CHECK(helper.b_found());
}
- CHECK(Top::context()->global()->DeleteProperty(
- *Factory::LookupAsciiSymbol("a"), JSObject::FORCE_DELETION));
+ CHECK(ISOLATE->context()->global()->DeleteProperty(
+ *FACTORY->LookupAsciiSymbol("a"), JSObject::FORCE_DELETION));
// We ensure that GC will not happen, so our raw pointer stays valid.
AssertNoAllocation no_alloc;
Object* a_saved = *a;
diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc
index 244980a19..2498fca90 100644
--- a/deps/v8/test/cctest/test-liveedit.cc
+++ b/deps/v8/test/cctest/test-liveedit.cc
@@ -44,13 +44,13 @@ class StringCompareInput : public Comparator::Input {
public:
StringCompareInput(const char* s1, const char* s2) : s1_(s1), s2_(s2) {
}
- int getLength1() {
+ int GetLength1() {
return StrLength(s1_);
}
- int getLength2() {
+ int GetLength2() {
return StrLength(s2_);
}
- bool equals(int index1, int index2) {
+ bool Equals(int index1, int index2) {
return s1_[index1] == s2_[index2];
}
@@ -95,7 +95,7 @@ void CompareStringsOneWay(const char* s1, const char* s2,
int expected_diff_parameter = -1) {
StringCompareInput input(s1, s2);
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
DiffChunkStruct* first_chunk;
ListDiffOutputWriter writer(&first_chunk);
@@ -158,6 +158,7 @@ void CompareStrings(const char* s1, const char* s2,
// --- T h e A c t u a l T e s t s
TEST(LiveEditDiffer) {
+ v8::internal::V8::Initialize(NULL);
CompareStrings("zz1zzz12zz123zzz", "zzzzzzzzzz", 6);
CompareStrings("zz1zzz12zz123zzz", "zz0zzz0zz0zzz", 9);
CompareStrings("123456789", "987654321", 16);
diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc
new file mode 100644
index 000000000..4579361f3
--- /dev/null
+++ b/deps/v8/test/cctest/test-lockers.cc
@@ -0,0 +1,629 @@
+// Copyright 2007-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.
+
+#include <limits.h>
+
+#include "v8.h"
+
+#include "api.h"
+#include "isolate.h"
+#include "compilation-cache.h"
+#include "execution.h"
+#include "snapshot.h"
+#include "platform.h"
+#include "utils.h"
+#include "cctest.h"
+#include "parser.h"
+#include "unicode-inl.h"
+
+using ::v8::AccessorInfo;
+using ::v8::Context;
+using ::v8::Extension;
+using ::v8::Function;
+using ::v8::HandleScope;
+using ::v8::Local;
+using ::v8::Object;
+using ::v8::ObjectTemplate;
+using ::v8::Persistent;
+using ::v8::Script;
+using ::v8::String;
+using ::v8::Value;
+using ::v8::V8;
+
+namespace i = ::i;
+
+
+
+
+// Migrating an isolate
+class KangarooThread : public v8::internal::Thread {
+ public:
+ KangarooThread(v8::Isolate* isolate,
+ v8::Handle<v8::Context> context, int value)
+ : Thread("KangarooThread"),
+ isolate_(isolate), context_(context), value_(value) {
+ }
+
+ void Run() {
+ {
+ v8::Locker locker(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ CHECK_EQ(isolate_, v8::internal::Isolate::Current());
+ v8::HandleScope scope;
+ v8::Context::Scope context_scope(context_);
+ Local<Value> v = CompileRun("getValue()");
+ CHECK(v->IsNumber());
+ CHECK_EQ(30, static_cast<int>(v->NumberValue()));
+ }
+ {
+ v8::Locker locker(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::Context::Scope context_scope(context_);
+ v8::HandleScope scope;
+ Local<Value> v = CompileRun("getValue()");
+ CHECK(v->IsNumber());
+ CHECK_EQ(30, static_cast<int>(v->NumberValue()));
+ }
+ isolate_->Dispose();
+ }
+
+ private:
+ v8::Isolate* isolate_;
+ Persistent<v8::Context> context_;
+ int value_;
+};
+
+// Migrates an isolate from one thread to another
+TEST(KangarooIsolates) {
+ v8::Isolate* isolate = v8::Isolate::New();
+ Persistent<v8::Context> context;
+ {
+ v8::Locker locker(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope;
+ context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+ CHECK_EQ(isolate, v8::internal::Isolate::Current());
+ CompileRun("function getValue() { return 30; }");
+ }
+ KangarooThread thread1(isolate, context, 1);
+ thread1.Start();
+ thread1.Join();
+}
+
+static void CalcFibAndCheck() {
+ Local<Value> v = CompileRun("function fib(n) {"
+ " if (n <= 2) return 1;"
+ " return fib(n-1) + fib(n-2);"
+ "}"
+ "fib(10)");
+ CHECK(v->IsNumber());
+ CHECK_EQ(55, static_cast<int>(v->NumberValue()));
+}
+
+class JoinableThread {
+ public:
+ explicit JoinableThread(const char* name)
+ : name_(name),
+ semaphore_(i::OS::CreateSemaphore(0)),
+ thread_(this) {
+ }
+
+ virtual ~JoinableThread() {
+ delete semaphore_;
+ }
+
+ void Start() {
+ thread_.Start();
+ }
+
+ void Join() {
+ semaphore_->Wait();
+ }
+
+ virtual void Run() = 0;
+ private:
+ class ThreadWithSemaphore : public i::Thread {
+ public:
+ explicit ThreadWithSemaphore(JoinableThread* joinable_thread)
+ : Thread(joinable_thread->name_),
+ joinable_thread_(joinable_thread) {
+ }
+
+ virtual void Run() {
+ joinable_thread_->Run();
+ joinable_thread_->semaphore_->Signal();
+ }
+
+ private:
+ JoinableThread* joinable_thread_;
+ };
+
+ const char* name_;
+ i::Semaphore* semaphore_;
+ ThreadWithSemaphore thread_;
+
+ friend class ThreadWithSemaphore;
+
+ DISALLOW_COPY_AND_ASSIGN(JoinableThread);
+};
+
+
+class IsolateLockingThreadWithLocalContext : public JoinableThread {
+ public:
+ explicit IsolateLockingThreadWithLocalContext(v8::Isolate* isolate)
+ : JoinableThread("IsolateLockingThread"),
+ isolate_(isolate) {
+ }
+
+ virtual void Run() {
+ v8::Locker locker(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::HandleScope handle_scope;
+ LocalContext local_context;
+ CHECK_EQ(isolate_, v8::internal::Isolate::Current());
+ CalcFibAndCheck();
+ }
+ private:
+ v8::Isolate* isolate_;
+};
+
+static void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) {
+ for (int i = 0; i < threads.length(); i++) {
+ threads[i]->Start();
+ }
+ for (int i = 0; i < threads.length(); i++) {
+ threads[i]->Join();
+ }
+ for (int i = 0; i < threads.length(); i++) {
+ delete threads[i];
+ }
+}
+
+
+// Run many threads all locking on the same isolate
+TEST(IsolateLockingStress) {
+ const int kNThreads = 100;
+ i::List<JoinableThread*> threads(kNThreads);
+ v8::Isolate* isolate = v8::Isolate::New();
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new IsolateLockingThreadWithLocalContext(isolate));
+ }
+ StartJoinAndDeleteThreads(threads);
+ isolate->Dispose();
+}
+
+class IsolateNonlockingThread : public JoinableThread {
+ public:
+ explicit IsolateNonlockingThread()
+ : JoinableThread("IsolateNonlockingThread") {
+ }
+
+ virtual void Run() {
+ v8::Isolate* isolate = v8::Isolate::New();
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::Context> context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+ CHECK_EQ(isolate, v8::internal::Isolate::Current());
+ CalcFibAndCheck();
+ }
+ isolate->Dispose();
+ }
+ private:
+};
+
+// Run many threads each accessing its own isolate without locking
+TEST(MultithreadedParallelIsolates) {
+#ifdef V8_TARGET_ARCH_ARM
+ const int kNThreads = 10;
+#else
+ const int kNThreads = 50;
+#endif
+ i::List<JoinableThread*> threads(kNThreads);
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new IsolateNonlockingThread());
+ }
+ StartJoinAndDeleteThreads(threads);
+}
+
+
+class IsolateNestedLockingThread : public JoinableThread {
+ public:
+ explicit IsolateNestedLockingThread(v8::Isolate* isolate)
+ : JoinableThread("IsolateNestedLocking"), isolate_(isolate) {
+ }
+ virtual void Run() {
+ v8::Locker lock(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::HandleScope handle_scope;
+ LocalContext local_context;
+ {
+ v8::Locker another_lock(isolate_);
+ CalcFibAndCheck();
+ }
+ {
+ v8::Locker another_lock(isolate_);
+ CalcFibAndCheck();
+ }
+ }
+ private:
+ v8::Isolate* isolate_;
+};
+
+// Run many threads with nested locks
+TEST(IsolateNestedLocking) {
+ const int kNThreads = 100;
+ v8::Isolate* isolate = v8::Isolate::New();
+ i::List<JoinableThread*> threads(kNThreads);
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new IsolateNestedLockingThread(isolate));
+ }
+ StartJoinAndDeleteThreads(threads);
+}
+
+
+class SeparateIsolatesLocksNonexclusiveThread : public JoinableThread {
+ public:
+ SeparateIsolatesLocksNonexclusiveThread(v8::Isolate* isolate1,
+ v8::Isolate* isolate2)
+ : JoinableThread("SeparateIsolatesLocksNonexclusiveThread"),
+ isolate1_(isolate1), isolate2_(isolate2) {
+ }
+
+ virtual void Run() {
+ v8::Locker lock(isolate1_);
+ v8::Isolate::Scope isolate_scope(isolate1_);
+ v8::HandleScope handle_scope;
+ LocalContext local_context;
+
+ IsolateLockingThreadWithLocalContext threadB(isolate2_);
+ threadB.Start();
+ CalcFibAndCheck();
+ threadB.Join();
+ }
+ private:
+ v8::Isolate* isolate1_;
+ v8::Isolate* isolate2_;
+};
+
+// Run parallel threads that lock and access different isolates in parallel
+TEST(SeparateIsolatesLocksNonexclusive) {
+ const int kNThreads = 100;
+ v8::Isolate* isolate1 = v8::Isolate::New();
+ v8::Isolate* isolate2 = v8::Isolate::New();
+ i::List<JoinableThread*> threads(kNThreads);
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new SeparateIsolatesLocksNonexclusiveThread(isolate1,
+ isolate2));
+ }
+ StartJoinAndDeleteThreads(threads);
+ isolate2->Dispose();
+ isolate1->Dispose();
+}
+
+class LockIsolateAndCalculateFibSharedContextThread : public JoinableThread {
+ public:
+ explicit LockIsolateAndCalculateFibSharedContextThread(
+ v8::Isolate* isolate, v8::Handle<v8::Context> context)
+ : JoinableThread("LockIsolateAndCalculateFibThread"),
+ isolate_(isolate),
+ context_(context) {
+ }
+
+ virtual void Run() {
+ v8::Locker lock(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ HandleScope handle_scope;
+ v8::Context::Scope context_scope(context_);
+ CalcFibAndCheck();
+ }
+ private:
+ v8::Isolate* isolate_;
+ Persistent<v8::Context> context_;
+};
+
+class LockerUnlockerThread : public JoinableThread {
+ public:
+ explicit LockerUnlockerThread(v8::Isolate* isolate)
+ : JoinableThread("LockerUnlockerThread"),
+ isolate_(isolate) {
+ }
+
+ virtual void Run() {
+ v8::Locker lock(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::Context> context = v8::Context::New();
+ {
+ v8::Context::Scope context_scope(context);
+ CalcFibAndCheck();
+ }
+ {
+ isolate_->Exit();
+ v8::Unlocker unlocker(isolate_);
+ LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
+ thread.Start();
+ thread.Join();
+ }
+ isolate_->Enter();
+ {
+ v8::Context::Scope context_scope(context);
+ CalcFibAndCheck();
+ }
+ }
+ private:
+ v8::Isolate* isolate_;
+};
+
+// Use unlocker inside of a Locker, multiple threads.
+TEST(LockerUnlocker) {
+ const int kNThreads = 100;
+ i::List<JoinableThread*> threads(kNThreads);
+ v8::Isolate* isolate = v8::Isolate::New();
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new LockerUnlockerThread(isolate));
+ }
+ StartJoinAndDeleteThreads(threads);
+ isolate->Dispose();
+}
+
+class LockTwiceAndUnlockThread : public JoinableThread {
+ public:
+ explicit LockTwiceAndUnlockThread(v8::Isolate* isolate)
+ : JoinableThread("LockTwiceAndUnlockThread"),
+ isolate_(isolate) {
+ }
+
+ virtual void Run() {
+ v8::Locker lock(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::Context> context = v8::Context::New();
+ {
+ v8::Context::Scope context_scope(context);
+ CalcFibAndCheck();
+ }
+ {
+ v8::Locker second_lock(isolate_);
+ {
+ isolate_->Exit();
+ v8::Unlocker unlocker(isolate_);
+ LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
+ thread.Start();
+ thread.Join();
+ }
+ }
+ isolate_->Enter();
+ {
+ v8::Context::Scope context_scope(context);
+ CalcFibAndCheck();
+ }
+ }
+ private:
+ v8::Isolate* isolate_;
+};
+
+// Use Unlocker inside two Lockers.
+TEST(LockTwiceAndUnlock) {
+ const int kNThreads = 100;
+ i::List<JoinableThread*> threads(kNThreads);
+ v8::Isolate* isolate = v8::Isolate::New();
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new LockTwiceAndUnlockThread(isolate));
+ }
+ StartJoinAndDeleteThreads(threads);
+ isolate->Dispose();
+}
+
+class LockAndUnlockDifferentIsolatesThread : public JoinableThread {
+ public:
+ LockAndUnlockDifferentIsolatesThread(v8::Isolate* isolate1,
+ v8::Isolate* isolate2)
+ : JoinableThread("LockAndUnlockDifferentIsolatesThread"),
+ isolate1_(isolate1),
+ isolate2_(isolate2) {
+ }
+
+ virtual void Run() {
+ Persistent<v8::Context> context1;
+ Persistent<v8::Context> context2;
+ v8::Locker lock1(isolate1_);
+ CHECK(v8::Locker::IsLocked(isolate1_));
+ CHECK(!v8::Locker::IsLocked(isolate2_));
+ {
+ v8::Isolate::Scope isolate_scope(isolate1_);
+ v8::HandleScope handle_scope;
+ context1 = v8::Context::New();
+ {
+ v8::Context::Scope context_scope(context1);
+ CalcFibAndCheck();
+ }
+ }
+ v8::Locker lock2(isolate2_);
+ CHECK(v8::Locker::IsLocked(isolate1_));
+ CHECK(v8::Locker::IsLocked(isolate2_));
+ {
+ v8::Isolate::Scope isolate_scope(isolate2_);
+ v8::HandleScope handle_scope;
+ context2 = v8::Context::New();
+ {
+ v8::Context::Scope context_scope(context2);
+ CalcFibAndCheck();
+ }
+ }
+ {
+ v8::Unlocker unlock1(isolate1_);
+ CHECK(!v8::Locker::IsLocked(isolate1_));
+ CHECK(v8::Locker::IsLocked(isolate2_));
+ v8::Isolate::Scope isolate_scope(isolate2_);
+ v8::HandleScope handle_scope;
+ v8::Context::Scope context_scope(context2);
+ LockIsolateAndCalculateFibSharedContextThread thread(isolate1_, context1);
+ thread.Start();
+ CalcFibAndCheck();
+ thread.Join();
+ }
+ }
+ private:
+ v8::Isolate* isolate1_;
+ v8::Isolate* isolate2_;
+};
+
+// Lock two isolates and unlock one of them.
+TEST(LockAndUnlockDifferentIsolates) {
+ v8::Isolate* isolate1 = v8::Isolate::New();
+ v8::Isolate* isolate2 = v8::Isolate::New();
+ LockAndUnlockDifferentIsolatesThread thread(isolate1, isolate2);
+ thread.Start();
+ thread.Join();
+ isolate2->Dispose();
+ isolate1->Dispose();
+}
+
+class LockUnlockLockThread : public JoinableThread {
+ public:
+ LockUnlockLockThread(v8::Isolate* isolate, v8::Handle<v8::Context> context)
+ : JoinableThread("LockUnlockLockThread"),
+ isolate_(isolate),
+ context_(context) {
+ }
+
+ virtual void Run() {
+ v8::Locker lock1(isolate_);
+ CHECK(v8::Locker::IsLocked(isolate_));
+ CHECK(!v8::Locker::IsLocked());
+ {
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::HandleScope handle_scope;
+ v8::Context::Scope context_scope(context_);
+ CalcFibAndCheck();
+ }
+ {
+ v8::Unlocker unlock1(isolate_);
+ CHECK(!v8::Locker::IsLocked(isolate_));
+ CHECK(!v8::Locker::IsLocked());
+ {
+ v8::Locker lock2(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
+ v8::HandleScope handle_scope;
+ CHECK(v8::Locker::IsLocked(isolate_));
+ CHECK(!v8::Locker::IsLocked());
+ v8::Context::Scope context_scope(context_);
+ CalcFibAndCheck();
+ }
+ }
+ }
+
+ private:
+ v8::Isolate* isolate_;
+ v8::Persistent<v8::Context> context_;
+};
+
+// Locker inside an Unlocker inside a Locker.
+TEST(LockUnlockLockMultithreaded) {
+ const int kNThreads = 100;
+ v8::Isolate* isolate = v8::Isolate::New();
+ Persistent<v8::Context> context;
+ {
+ v8::Locker locker_(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope;
+ context = v8::Context::New();
+ }
+ i::List<JoinableThread*> threads(kNThreads);
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new LockUnlockLockThread(isolate, context));
+ }
+ StartJoinAndDeleteThreads(threads);
+}
+
+class LockUnlockLockDefaultIsolateThread : public JoinableThread {
+ public:
+ explicit LockUnlockLockDefaultIsolateThread(v8::Handle<v8::Context> context)
+ : JoinableThread("LockUnlockLockDefaultIsolateThread"),
+ context_(context) {
+ }
+
+ virtual void Run() {
+ v8::Locker lock1;
+ {
+ v8::HandleScope handle_scope;
+ v8::Context::Scope context_scope(context_);
+ CalcFibAndCheck();
+ }
+ {
+ v8::Unlocker unlock1;
+ {
+ v8::Locker lock2;
+ v8::HandleScope handle_scope;
+ v8::Context::Scope context_scope(context_);
+ CalcFibAndCheck();
+ }
+ }
+ }
+
+ private:
+ v8::Persistent<v8::Context> context_;
+};
+
+// Locker inside an Unlocker inside a Locker for default isolate.
+TEST(LockUnlockLockDefaultIsolateMultithreaded) {
+ const int kNThreads = 100;
+ Persistent<v8::Context> context;
+ {
+ v8::Locker locker_;
+ v8::HandleScope handle_scope;
+ context = v8::Context::New();
+ }
+ i::List<JoinableThread*> threads(kNThreads);
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new LockUnlockLockDefaultIsolateThread(context));
+ }
+ StartJoinAndDeleteThreads(threads);
+}
+
+
+TEST(Regress1433) {
+ for (int i = 0; i < 10; i++) {
+ v8::Isolate* isolate = v8::Isolate::New();
+ {
+ v8::Locker lock(isolate);
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope;
+ v8::Persistent<Context> context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+ v8::Handle<String> source = v8::String::New("1+1");
+ v8::Handle<Script> script = v8::Script::Compile(source);
+ v8::Handle<Value> result = script->Run();
+ v8::String::AsciiValue ascii(result);
+ context.Dispose();
+ }
+ isolate->Dispose();
+ }
+}
diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc
index bf72184fb..b967c7388 100644
--- a/deps/v8/test/cctest/test-log-stack-tracer.cc
+++ b/deps/v8/test/cctest/test-log-stack-tracer.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// 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:
@@ -36,10 +36,9 @@
#include "api.h"
#include "codegen.h"
#include "log.h"
-#include "top.h"
+#include "isolate.h"
#include "cctest.h"
#include "disassembler.h"
-#include "register-allocator-inl.h"
#include "vm-state-inl.h"
using v8::Function;
@@ -52,10 +51,10 @@ using v8::Value;
using v8::internal::byte;
using v8::internal::Address;
using v8::internal::Handle;
+using v8::internal::Isolate;
using v8::internal::JSFunction;
using v8::internal::StackTracer;
using v8::internal::TickSample;
-using v8::internal::Top;
namespace i = v8::internal;
@@ -78,18 +77,19 @@ static void DoTrace(Address fp) {
// sp is only used to define stack high bound
trace_env.sample->sp =
reinterpret_cast<Address>(trace_env.sample) - 10240;
- StackTracer::Trace(trace_env.sample);
+ StackTracer::Trace(Isolate::Current(), trace_env.sample);
}
// Hide c_entry_fp to emulate situation when sampling is done while
// pure JS code is being executed
static void DoTraceHideCEntryFPAddress(Address fp) {
- v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address());
+ v8::internal::Address saved_c_frame_fp =
+ *(Isolate::Current()->c_entry_fp_address());
CHECK(saved_c_frame_fp);
- *(Top::c_entry_fp_address()) = 0;
+ *(Isolate::Current()->c_entry_fp_address()) = 0;
DoTrace(fp);
- *(Top::c_entry_fp_address()) = saved_c_frame_fp;
+ *(Isolate::Current()->c_entry_fp_address()) = saved_c_frame_fp;
}
@@ -163,8 +163,8 @@ v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) {
static Address GetJsEntrySp() {
- CHECK_NE(NULL, Top::GetCurrentThread());
- return Top::js_entry_sp(Top::GetCurrentThread());
+ CHECK_NE(NULL, i::Isolate::Current()->thread_local_top());
+ return Isolate::js_entry_sp(i::Isolate::Current()->thread_local_top());
}
@@ -276,9 +276,12 @@ static void CreateTraceCallerFunction(const char* func_name,
// This test verifies that stack tracing works when called during
// execution of a native function called from JS code. In this case,
-// StackTracer uses Top::c_entry_fp as a starting point for stack
+// StackTracer uses Isolate::c_entry_fp as a starting point for stack
// walking.
TEST(CFromJSStackTrace) {
+ // BUG(1303) Inlining of JSFuncDoTrace() in JSTrace below breaks this test.
+ i::FLAG_use_inlining = false;
+
TickSample sample;
InitTraceEnv(&sample);
@@ -302,13 +305,11 @@ TEST(CFromJSStackTrace) {
// DoTrace(EBP) [native]
// StackTracer::Trace
- // The VM state tracking keeps track of external callbacks and puts
- // them at the top of the sample stack.
- int base = 0;
- CHECK(sample.stack[0] == FUNCTION_ADDR(TraceExtension::Trace));
- base++;
+ CHECK(sample.has_external_callback);
+ CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback);
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
+ int base = 0;
CHECK_GT(sample.frames_count, base + 1);
CHECK(IsAddressWithinFuncCode("JSFuncDoTrace", sample.stack[base + 0]));
CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 1]));
@@ -318,7 +319,7 @@ TEST(CFromJSStackTrace) {
// This test verifies that stack tracing works when called during
// execution of JS code. However, as calling StackTracer requires
// entering native code, we can only emulate pure JS by erasing
-// Top::c_entry_fp value. In this case, StackTracer uses passed frame
+// Isolate::c_entry_fp value. In this case, StackTracer uses passed frame
// pointer value as a starting point for stack walking.
TEST(PureJSStackTrace) {
// This test does not pass with inlining enabled since inlined functions
@@ -353,13 +354,11 @@ TEST(PureJSStackTrace) {
// StackTracer::Trace
//
- // The VM state tracking keeps track of external callbacks and puts
- // them at the top of the sample stack.
- int base = 0;
- CHECK(sample.stack[0] == FUNCTION_ADDR(TraceExtension::JSTrace));
- base++;
+ CHECK(sample.has_external_callback);
+ CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace), sample.external_callback);
// 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]));
@@ -397,6 +396,7 @@ static int CFunc(int depth) {
TEST(PureCStackTrace) {
TickSample sample;
InitTraceEnv(&sample);
+ InitializeVM();
// Check that sampler doesn't crash
CHECK_EQ(10, CFunc(10));
}
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index 30b8a48db..e7a178cc5 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -29,61 +29,61 @@ static void SetUp() {
// Log to memory buffer.
i::FLAG_logfile = "*";
i::FLAG_log = true;
- Logger::Setup();
+ LOGGER->Setup();
}
static void TearDown() {
- Logger::TearDown();
+ LOGGER->TearDown();
}
TEST(EmptyLog) {
SetUp();
- CHECK_EQ(0, Logger::GetLogLines(0, NULL, 0));
- CHECK_EQ(0, Logger::GetLogLines(100, NULL, 0));
- CHECK_EQ(0, Logger::GetLogLines(0, NULL, 100));
- CHECK_EQ(0, Logger::GetLogLines(100, NULL, 100));
+ CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
+ CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0));
+ CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 100));
+ CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 100));
TearDown();
}
TEST(GetMessages) {
SetUp();
- Logger::StringEvent("aaa", "bbb");
- Logger::StringEvent("cccc", "dddd");
- CHECK_EQ(0, Logger::GetLogLines(0, NULL, 0));
+ LOGGER->StringEvent("aaa", "bbb");
+ LOGGER->StringEvent("cccc", "dddd");
+ CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
char log_lines[100];
memset(log_lines, 0, sizeof(log_lines));
// See Logger::StringEvent.
const char* line_1 = "aaa,\"bbb\"\n";
const int line_1_len = StrLength(line_1);
// The exact size.
- CHECK_EQ(line_1_len, Logger::GetLogLines(0, log_lines, line_1_len));
+ CHECK_EQ(line_1_len, LOGGER->GetLogLines(0, log_lines, line_1_len));
CHECK_EQ(line_1, log_lines);
memset(log_lines, 0, sizeof(log_lines));
// A bit more than the first line length.
- CHECK_EQ(line_1_len, Logger::GetLogLines(0, log_lines, line_1_len + 3));
+ CHECK_EQ(line_1_len, LOGGER->GetLogLines(0, log_lines, line_1_len + 3));
log_lines[line_1_len] = '\0';
CHECK_EQ(line_1, log_lines);
memset(log_lines, 0, sizeof(log_lines));
const char* line_2 = "cccc,\"dddd\"\n";
const int line_2_len = StrLength(line_2);
// Now start with line_2 beginning.
- CHECK_EQ(0, Logger::GetLogLines(line_1_len, log_lines, 0));
- CHECK_EQ(line_2_len, Logger::GetLogLines(line_1_len, log_lines, line_2_len));
+ CHECK_EQ(0, LOGGER->GetLogLines(line_1_len, log_lines, 0));
+ CHECK_EQ(line_2_len, LOGGER->GetLogLines(line_1_len, log_lines, line_2_len));
CHECK_EQ(line_2, log_lines);
memset(log_lines, 0, sizeof(log_lines));
CHECK_EQ(line_2_len,
- Logger::GetLogLines(line_1_len, log_lines, line_2_len + 3));
+ LOGGER->GetLogLines(line_1_len, log_lines, line_2_len + 3));
CHECK_EQ(line_2, log_lines);
memset(log_lines, 0, sizeof(log_lines));
// Now get entire buffer contents.
const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n";
const int all_lines_len = StrLength(all_lines);
- CHECK_EQ(all_lines_len, Logger::GetLogLines(0, log_lines, all_lines_len));
+ CHECK_EQ(all_lines_len, LOGGER->GetLogLines(0, log_lines, all_lines_len));
CHECK_EQ(all_lines, log_lines);
memset(log_lines, 0, sizeof(log_lines));
- CHECK_EQ(all_lines_len, Logger::GetLogLines(0, log_lines, all_lines_len + 3));
+ CHECK_EQ(all_lines_len, LOGGER->GetLogLines(0, log_lines, all_lines_len + 3));
CHECK_EQ(all_lines, log_lines);
memset(log_lines, 0, sizeof(log_lines));
TearDown();
@@ -91,26 +91,26 @@ TEST(GetMessages) {
static int GetLogLines(int start_pos, i::Vector<char>* buffer) {
- return Logger::GetLogLines(start_pos, buffer->start(), buffer->length());
+ return LOGGER->GetLogLines(start_pos, buffer->start(), buffer->length());
}
TEST(BeyondWritePosition) {
SetUp();
- Logger::StringEvent("aaa", "bbb");
- Logger::StringEvent("cccc", "dddd");
+ LOGGER->StringEvent("aaa", "bbb");
+ LOGGER->StringEvent("cccc", "dddd");
// See Logger::StringEvent.
const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n";
const int all_lines_len = StrLength(all_lines);
EmbeddedVector<char, 100> buffer;
const int beyond_write_pos = all_lines_len;
- CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos, buffer.start(), 1));
+ CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos, buffer.start(), 1));
CHECK_EQ(0, GetLogLines(beyond_write_pos, &buffer));
- CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos + 1, buffer.start(), 1));
+ CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos + 1, buffer.start(), 1));
CHECK_EQ(0, GetLogLines(beyond_write_pos + 1, &buffer));
- CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos + 100, buffer.start(), 1));
+ CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos + 100, buffer.start(), 1));
CHECK_EQ(0, GetLogLines(beyond_write_pos + 100, &buffer));
- CHECK_EQ(0, Logger::GetLogLines(10 * 1024 * 1024, buffer.start(), 1));
+ CHECK_EQ(0, LOGGER->GetLogLines(10 * 1024 * 1024, buffer.start(), 1));
CHECK_EQ(0, GetLogLines(10 * 1024 * 1024, &buffer));
TearDown();
}
@@ -120,12 +120,12 @@ TEST(MemoryLoggingTurnedOff) {
// Log to stdout
i::FLAG_logfile = "-";
i::FLAG_log = true;
- Logger::Setup();
- CHECK_EQ(0, Logger::GetLogLines(0, NULL, 0));
- CHECK_EQ(0, Logger::GetLogLines(100, NULL, 0));
- CHECK_EQ(0, Logger::GetLogLines(0, NULL, 100));
- CHECK_EQ(0, Logger::GetLogLines(100, NULL, 100));
- Logger::TearDown();
+ LOGGER->Setup();
+ CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
+ CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0));
+ CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 100));
+ CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 100));
+ LOGGER->TearDown();
}
@@ -139,12 +139,12 @@ namespace internal {
class LoggerTestHelper : public AllStatic {
public:
- static bool IsSamplerActive() { return Logger::IsProfilerSamplerActive(); }
+ static bool IsSamplerActive() { return LOGGER->IsProfilerSamplerActive(); }
static void ResetSamplesTaken() {
- reinterpret_cast<Sampler*>(Logger::ticker_)->ResetSamplesTaken();
+ reinterpret_cast<Sampler*>(LOGGER->ticker_)->ResetSamplesTaken();
}
static bool has_samples_taken() {
- return reinterpret_cast<Sampler*>(Logger::ticker_)->samples_taken() > 0;
+ return reinterpret_cast<Sampler*>(LOGGER->ticker_)->samples_taken() > 0;
}
};
@@ -166,13 +166,13 @@ class ScopedLoggerInitializer {
need_to_set_up_logger_(i::V8::IsRunning()),
scope_(),
env_(v8::Context::New()) {
- if (need_to_set_up_logger_) Logger::Setup();
+ if (need_to_set_up_logger_) LOGGER->Setup();
env_->Enter();
}
~ScopedLoggerInitializer() {
env_->Exit();
- Logger::TearDown();
+ LOGGER->TearDown();
i::FLAG_prof_lazy = saved_prof_lazy_;
i::FLAG_prof = saved_prof_;
i::FLAG_prof_auto = saved_prof_auto_;
@@ -251,7 +251,7 @@ static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
!LoggerTestHelper::IsSamplerActive());
LoggerTestHelper::ResetSamplesTaken();
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
CHECK(LoggerTestHelper::IsSamplerActive());
// Verify that the current map of compiled functions has been logged.
@@ -273,7 +273,7 @@ static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
i::OS::Sleep(1);
}
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
CHECK(i::RuntimeProfiler::IsEnabled() ||
!LoggerTestHelper::IsSamplerActive());
@@ -329,8 +329,8 @@ namespace {
class LoopingThread : public v8::internal::Thread {
public:
- LoopingThread()
- : v8::internal::Thread(),
+ explicit LoopingThread(v8::internal::Isolate* isolate)
+ : v8::internal::Thread(isolate),
semaphore_(v8::internal::OS::CreateSemaphore(0)),
run_(true) {
}
@@ -369,9 +369,12 @@ class LoopingThread : public v8::internal::Thread {
class LoopingJsThread : public LoopingThread {
public:
+ explicit LoopingJsThread(v8::internal::Isolate* isolate)
+ : LoopingThread(isolate) { }
void RunLoop() {
v8::Locker locker;
- CHECK(v8::internal::ThreadManager::HasId());
+ CHECK(i::Isolate::Current() != NULL);
+ CHECK_GT(i::Isolate::Current()->thread_manager()->CurrentId(), 0);
SetV8ThreadId();
while (IsRunning()) {
v8::HandleScope scope;
@@ -392,11 +395,14 @@ class LoopingJsThread : public LoopingThread {
class LoopingNonJsThread : public LoopingThread {
public:
+ explicit LoopingNonJsThread(v8::internal::Isolate* isolate)
+ : LoopingThread(isolate) { }
void RunLoop() {
v8::Locker locker;
v8::Unlocker unlocker;
// Now thread has V8's id, but will not run VM code.
- CHECK(v8::internal::ThreadManager::HasId());
+ CHECK(i::Isolate::Current() != NULL);
+ CHECK_GT(i::Isolate::Current()->thread_manager()->CurrentId(), 0);
double i = 10;
SignalRunning();
while (IsRunning()) {
@@ -409,8 +415,8 @@ class LoopingNonJsThread : public LoopingThread {
class TestSampler : public v8::internal::Sampler {
public:
- TestSampler()
- : Sampler(0, true, true),
+ explicit TestSampler(v8::internal::Isolate* isolate)
+ : Sampler(isolate, 0, true, true),
semaphore_(v8::internal::OS::CreateSemaphore(0)),
was_sample_stack_called_(false) {
}
@@ -441,14 +447,14 @@ TEST(ProfMultipleThreads) {
TestSampler* sampler = NULL;
{
v8::Locker locker;
- sampler = new TestSampler();
+ sampler = new TestSampler(v8::internal::Isolate::Current());
sampler->Start();
CHECK(sampler->IsActive());
}
- LoopingJsThread jsThread;
+ LoopingJsThread jsThread(v8::internal::Isolate::Current());
jsThread.Start();
- LoopingNonJsThread nonJsThread;
+ LoopingNonJsThread nonJsThread(v8::internal::Isolate::Current());
nonJsThread.Start();
CHECK(!sampler->WasSampleStackCalled());
@@ -515,7 +521,7 @@ TEST(Issue23768) {
i_source->set_resource(NULL);
// Must not crash.
- i::Logger::LogCompiledFunctions();
+ LOGGER->LogCompiledFunctions();
}
@@ -541,7 +547,7 @@ TEST(LogCallbacks) {
initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
CompileAndRunScript("Obj.prototype.method1.toString();");
- i::Logger::LogCompiledFunctions();
+ LOGGER->LogCompiledFunctions();
CHECK_GT(matcher.GetNextChunk(), 0);
const char* callback_rec = "code-creation,Callback,";
@@ -584,7 +590,7 @@ TEST(LogAccessorCallbacks) {
inst->SetAccessor(v8::String::New("prop1"), Prop1Getter, Prop1Setter);
inst->SetAccessor(v8::String::New("prop2"), Prop2Getter);
- i::Logger::LogAccessorCallbacks();
+ LOGGER->LogAccessorCallbacks();
CHECK_GT(matcher.GetNextChunk(), 0);
matcher.PrintBuffer();
@@ -616,11 +622,11 @@ TEST(LogTags) {
const char* close_tag = "close-tag,";
// Check compatibility with the old style behavior.
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
CHECK_EQ(NULL, matcher.Find(open_tag));
CHECK_EQ(NULL, matcher.Find(close_tag));
@@ -628,11 +634,11 @@ TEST(LogTags) {
const char* close_tag1 = "close-tag,1\n";
// Check non-nested tag case.
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
CHECK_GT(matcher.GetNextChunk(), 0);
CHECK(matcher.IsInSequence(open_tag1, close_tag1));
@@ -640,15 +646,15 @@ TEST(LogTags) {
const char* close_tag2 = "close-tag,2\n";
// Check nested tags case.
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
CHECK_GT(matcher.GetNextChunk(), 0);
// open_tag1 < open_tag2 < close_tag2 < close_tag1
CHECK(matcher.IsInSequence(open_tag1, open_tag2));
@@ -656,15 +662,15 @@ TEST(LogTags) {
CHECK(matcher.IsInSequence(close_tag2, close_tag1));
// Check overlapped tags case.
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
CHECK_GT(matcher.GetNextChunk(), 0);
// open_tag1 < open_tag2 < close_tag1 < close_tag2
CHECK(matcher.IsInSequence(open_tag1, open_tag2));
@@ -675,19 +681,19 @@ TEST(LogTags) {
const char* close_tag3 = "close-tag,3\n";
// Check pausing overflow case.
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
- CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 3);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 3);
- CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules());
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
+ CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 3);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 3);
+ CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
// Must be no tags, because logging must be disabled.
CHECK_EQ(NULL, matcher.Find(open_tag3));
CHECK_EQ(NULL, matcher.Find(close_tag3));
@@ -697,29 +703,11 @@ TEST(LogTags) {
TEST(IsLoggingPreserved) {
ScopedLoggerInitializer initialize_logger(false);
- CHECK(Logger::is_logging());
- Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK(Logger::is_logging());
- Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
- CHECK(Logger::is_logging());
-
- CHECK(Logger::is_logging());
- Logger::ResumeProfiler(
- v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
- CHECK(Logger::is_logging());
- Logger::PauseProfiler(
- v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
- CHECK(Logger::is_logging());
-
- CHECK(Logger::is_logging());
- Logger::ResumeProfiler(
- v8::PROFILER_MODULE_CPU |
- v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
- CHECK(Logger::is_logging());
- Logger::PauseProfiler(
- v8::PROFILER_MODULE_CPU |
- v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
- CHECK(Logger::is_logging());
+ CHECK(LOGGER->is_logging());
+ LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK(LOGGER->is_logging());
+ LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
+ CHECK(LOGGER->is_logging());
}
@@ -1128,7 +1116,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
" obj.test =\n"
" (function a(j) { return function b() { return j; } })(100);\n"
"})(this);");
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
EmbeddedVector<char, 204800> buffer;
int log_size;
@@ -1148,9 +1136,9 @@ TEST(EquivalenceOfLoggingAndTraversal) {
}
// Iterate heap to find compiled functions, will write to log.
- i::Logger::LogCompiledFunctions();
+ LOGGER->LogCompiledFunctions();
char* new_log_start = buffer.start() + log_size;
- const int new_log_size = Logger::GetLogLines(
+ const int new_log_size = LOGGER->GetLogLines(
log_size, new_log_start, buffer.length() - log_size);
CHECK_GT(new_log_size, 0);
CHECK_GT(buffer.length(), log_size + new_log_size);
@@ -1184,7 +1172,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
CHECK(results_equal);
env->Exit();
- Logger::TearDown();
+ LOGGER->TearDown();
i::FLAG_always_compact = saved_always_compact;
}
diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc
index 9b1fc46ea..59eeed906 100755
--- a/deps/v8/test/cctest/test-macro-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc
@@ -35,48 +35,49 @@
#include "serialize.h"
#include "cctest.h"
-using v8::internal::byte;
-using v8::internal::OS;
using v8::internal::Assembler;
+using v8::internal::CodeDesc;
using v8::internal::Condition;
-using v8::internal::MacroAssembler;
+using v8::internal::FUNCTION_CAST;
using v8::internal::HandleScope;
-using v8::internal::Operand;
using v8::internal::Immediate;
-using v8::internal::SmiIndex;
+using v8::internal::Isolate;
using v8::internal::Label;
+using v8::internal::MacroAssembler;
+using v8::internal::OS;
+using v8::internal::Operand;
using v8::internal::RelocInfo;
+using v8::internal::Smi;
+using v8::internal::SmiIndex;
+using v8::internal::byte;
+using v8::internal::carry;
+using v8::internal::greater;
+using v8::internal::greater_equal;
+using v8::internal::kIntSize;
+using v8::internal::kPointerSize;
+using v8::internal::kSmiTagMask;
+using v8::internal::kSmiValueSize;
+using v8::internal::less_equal;
+using v8::internal::negative;
+using v8::internal::not_carry;
+using v8::internal::not_equal;
+using v8::internal::not_zero;
+using v8::internal::positive;
+using v8::internal::r11;
+using v8::internal::r13;
+using v8::internal::r14;
+using v8::internal::r15;
+using v8::internal::r8;
+using v8::internal::r9;
using v8::internal::rax;
+using v8::internal::rbp;
using v8::internal::rbx;
-using v8::internal::rsi;
-using v8::internal::rdi;
using v8::internal::rcx;
+using v8::internal::rdi;
using v8::internal::rdx;
-using v8::internal::rbp;
+using v8::internal::rsi;
using v8::internal::rsp;
-using v8::internal::r8;
-using v8::internal::r9;
-using v8::internal::r11;
-using v8::internal::r12;
-using v8::internal::r13;
-using v8::internal::r14;
using v8::internal::times_pointer_size;
-using v8::internal::FUNCTION_CAST;
-using v8::internal::CodeDesc;
-using v8::internal::less_equal;
-using v8::internal::not_equal;
-using v8::internal::not_zero;
-using v8::internal::greater;
-using v8::internal::greater_equal;
-using v8::internal::carry;
-using v8::internal::not_carry;
-using v8::internal::negative;
-using v8::internal::positive;
-using v8::internal::Smi;
-using v8::internal::kSmiTagMask;
-using v8::internal::kSmiValueSize;
-using v8::internal::kPointerSize;
-using v8::internal::kIntSize;
// Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
@@ -95,7 +96,9 @@ typedef int (*F0)();
static void EntryCode(MacroAssembler* masm) {
// Smi constant register is callee save.
__ push(v8::internal::kSmiConstantRegister);
+ __ push(v8::internal::kRootRegister);
__ InitializeSmiConstantRegister();
+ __ InitializeRootRegister();
}
@@ -105,6 +108,7 @@ static void ExitCode(MacroAssembler* masm) {
__ cmpq(rdx, v8::internal::kSmiConstantRegister);
__ movq(rdx, Immediate(-1));
__ cmovq(not_equal, rax, rdx);
+ __ pop(v8::internal::kRootRegister);
__ pop(v8::internal::kSmiConstantRegister);
}
@@ -146,6 +150,7 @@ static void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) {
// Test that we can move a Smi value literally into a register.
TEST(SmiMove) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -153,7 +158,9 @@ TEST(SmiMove) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
masm->set_allow_stub_calls(false);
EntryCode(masm);
@@ -220,7 +227,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ j(less_equal, exit);
}
} else {
- __ SmiCompare(rcx, rcx);
+ __ cmpq(rcx, rcx);
__ movl(rax, Immediate(id + 11));
__ j(not_equal, exit);
__ incq(rax);
@@ -232,15 +239,18 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) {
// Test that we can compare smis for equality (and more).
TEST(SmiCompare) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+ static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
&actual_size,
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -282,6 +292,7 @@ TEST(SmiCompare) {
TEST(Integer32ToSmi) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -289,7 +300,9 @@ TEST(Integer32ToSmi) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -300,35 +313,35 @@ TEST(Integer32ToSmi) {
__ movl(rcx, Immediate(0));
__ Integer32ToSmi(rcx, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(0)));
- __ SmiCompare(rcx, rdx);
+ __ cmpq(rcx, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(2)); // Test number.
__ movl(rcx, Immediate(1024));
__ Integer32ToSmi(rcx, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(1024)));
- __ SmiCompare(rcx, rdx);
+ __ cmpq(rcx, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(3)); // Test number.
__ movl(rcx, Immediate(-1));
__ Integer32ToSmi(rcx, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(-1)));
- __ SmiCompare(rcx, rdx);
+ __ cmpq(rcx, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(4)); // Test number.
__ movl(rcx, Immediate(Smi::kMaxValue));
__ Integer32ToSmi(rcx, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMaxValue)));
- __ SmiCompare(rcx, rdx);
+ __ cmpq(rcx, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(5)); // Test number.
__ movl(rcx, Immediate(Smi::kMinValue));
__ Integer32ToSmi(rcx, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMinValue)));
- __ SmiCompare(rcx, rdx);
+ __ cmpq(rcx, rdx);
__ j(not_equal, &exit);
// Different target register.
@@ -337,35 +350,35 @@ TEST(Integer32ToSmi) {
__ movl(rcx, Immediate(0));
__ Integer32ToSmi(r8, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(0)));
- __ SmiCompare(r8, rdx);
+ __ cmpq(r8, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(7)); // Test number.
__ movl(rcx, Immediate(1024));
__ Integer32ToSmi(r8, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(1024)));
- __ SmiCompare(r8, rdx);
+ __ cmpq(r8, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(8)); // Test number.
__ movl(rcx, Immediate(-1));
__ Integer32ToSmi(r8, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(-1)));
- __ SmiCompare(r8, rdx);
+ __ cmpq(r8, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(9)); // Test number.
__ movl(rcx, Immediate(Smi::kMaxValue));
__ Integer32ToSmi(r8, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMaxValue)));
- __ SmiCompare(r8, rdx);
+ __ cmpq(r8, rdx);
__ j(not_equal, &exit);
__ movq(rax, Immediate(10)); // Test number.
__ movl(rcx, Immediate(Smi::kMinValue));
__ Integer32ToSmi(r8, rcx);
__ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMinValue)));
- __ SmiCompare(r8, rdx);
+ __ cmpq(r8, rdx);
__ j(not_equal, &exit);
@@ -394,21 +407,22 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm,
__ movq(rcx, x, RelocInfo::NONE);
__ movq(r11, rcx);
__ Integer64PlusConstantToSmi(rdx, rcx, y);
- __ SmiCompare(rdx, r8);
+ __ cmpq(rdx, r8);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ Integer64PlusConstantToSmi(rcx, rcx, y);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
}
TEST(Integer64PlusConstantToSmi) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -416,7 +430,9 @@ TEST(Integer64PlusConstantToSmi) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -452,6 +468,7 @@ TEST(Integer64PlusConstantToSmi) {
TEST(SmiCheck) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -459,7 +476,9 @@ TEST(SmiCheck) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -660,14 +679,14 @@ void TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) {
__ SmiNeg(r9, rcx, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiNeg(rcx, rcx, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
} else {
Label smi_ok, smi_ok2;
@@ -679,11 +698,11 @@ void TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) {
__ jmp(exit);
__ bind(&smi_ok);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
@@ -691,13 +710,14 @@ void TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) {
__ jmp(exit);
__ bind(&smi_ok2);
__ incq(rax);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
}
}
TEST(SmiNeg) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -706,7 +726,9 @@ TEST(SmiNeg) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -751,12 +773,12 @@ static void SmiAddTest(MacroAssembler* masm,
__ movl(rax, Immediate(id)); // Test number.
__ SmiAdd(r9, rcx, rdx, exit);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
__ SmiAdd(rcx, rcx, rdx, exit); \
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ movl(rcx, Immediate(first));
@@ -764,11 +786,11 @@ static void SmiAddTest(MacroAssembler* masm,
__ incq(rax);
__ SmiAddConstant(r9, rcx, Smi::FromInt(second));
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ SmiAddConstant(rcx, rcx, Smi::FromInt(second));
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ movl(rcx, Immediate(first));
@@ -776,16 +798,17 @@ static void SmiAddTest(MacroAssembler* masm,
__ incq(rax);
__ SmiAddConstant(r9, rcx, Smi::FromInt(second), exit);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
__ SmiAddConstant(rcx, rcx, Smi::FromInt(second), exit);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ 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,
@@ -793,7 +816,9 @@ TEST(SmiAdd) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -834,36 +859,36 @@ static void SmiSubTest(MacroAssembler* masm,
__ movl(rax, Immediate(id)); // Test 0.
__ SmiSub(r9, rcx, rdx, exit);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax); // Test 1.
__ SmiSub(rcx, rcx, rdx, exit);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ Move(rcx, Smi::FromInt(first));
__ incq(rax); // Test 2.
__ SmiSubConstant(r9, rcx, Smi::FromInt(second));
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax); // Test 3.
__ SmiSubConstant(rcx, rcx, Smi::FromInt(second));
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ Move(rcx, Smi::FromInt(first));
__ incq(rax); // Test 4.
__ SmiSubConstant(r9, rcx, Smi::FromInt(second), exit);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax); // Test 5.
__ SmiSubConstant(rcx, rcx, Smi::FromInt(second), exit);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
}
@@ -886,7 +911,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -897,7 +922,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -909,7 +934,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -920,7 +945,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -933,7 +958,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -944,7 +969,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -956,7 +981,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
@@ -967,13 +992,14 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
}
TEST(SmiSub) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -982,7 +1008,9 @@ TEST(SmiSub) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1032,15 +1060,15 @@ void TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ Move(r8, Smi::FromIntptr(result));
__ SmiMul(r9, rcx, rdx, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
__ SmiMul(rcx, rcx, rdx, exit);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
} else {
__ movl(rax, Immediate(id + 8));
@@ -1049,7 +1077,7 @@ void TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ jmp(exit);
__ bind(&overflow_ok);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiMul(rcx, rcx, rdx, &overflow_ok2);
@@ -1057,13 +1085,14 @@ void TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ bind(&overflow_ok2);
// 31-bit version doesn't preserve rcx on failure.
// __ incq(rax);
- // __ SmiCompare(r11, rcx);
+ // __ cmpq(r11, rcx);
// __ j(not_equal, exit);
}
}
TEST(SmiMul) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -1071,7 +1100,9 @@ TEST(SmiMul) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1120,30 +1151,30 @@ void TestSmiDiv(MacroAssembler* masm, Label* exit, int id, int x, int y) {
if (!fraction && !overflow && !negative_zero && !division_by_zero) {
// Division succeeds
__ movq(rcx, r11);
- __ movq(r12, Immediate(id));
+ __ movq(r15, Immediate(id));
int result = x / y;
__ Move(r8, Smi::FromInt(result));
__ SmiDiv(r9, rcx, r14, exit);
// Might have destroyed rcx and r14.
- __ incq(r12);
- __ SmiCompare(r9, r8);
+ __ incq(r15);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
- __ incq(r12);
+ __ incq(r15);
__ movq(rcx, r11);
__ Move(r14, Smi::FromInt(y));
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
- __ incq(r12);
+ __ incq(r15);
__ SmiDiv(rcx, rcx, r14, exit);
- __ incq(r12);
- __ SmiCompare(rcx, r8);
+ __ incq(r15);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
} else {
// Division fails.
- __ movq(r12, Immediate(id + 8));
+ __ movq(r15, Immediate(id + 8));
Label fail_ok, fail_ok2;
__ movq(rcx, r11);
@@ -1151,23 +1182,24 @@ void TestSmiDiv(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ jmp(exit);
__ bind(&fail_ok);
- __ incq(r12);
- __ SmiCompare(rcx, r11);
+ __ incq(r15);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
- __ incq(r12);
+ __ incq(r15);
__ SmiDiv(rcx, rcx, r14, &fail_ok2);
__ jmp(exit);
__ bind(&fail_ok2);
- __ incq(r12);
- __ SmiCompare(rcx, r11);
+ __ incq(r15);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
}
TEST(SmiDiv) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1176,7 +1208,9 @@ TEST(SmiDiv) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1184,7 +1218,7 @@ TEST(SmiDiv) {
Label exit;
__ push(r14);
- __ push(r12);
+ __ push(r15);
TestSmiDiv(masm, &exit, 0x10, 1, 1);
TestSmiDiv(masm, &exit, 0x20, 1, 0);
TestSmiDiv(masm, &exit, 0x30, -1, 0);
@@ -1206,10 +1240,10 @@ TEST(SmiDiv) {
TestSmiDiv(masm, &exit, 0x130, Smi::kMinValue, Smi::kMinValue);
TestSmiDiv(masm, &exit, 0x140, Smi::kMinValue, -1);
- __ xor_(r12, r12); // Success.
+ __ xor_(r15, r15); // Success.
__ bind(&exit);
- __ movq(rax, r12);
- __ pop(r12);
+ __ movq(rax, r15);
+ __ pop(r15);
__ pop(r14);
ExitCode(masm);
__ ret(0);
@@ -1232,51 +1266,52 @@ void TestSmiMod(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ Move(r14, Smi::FromInt(y));
if (!division_overflow && !negative_zero && !division_by_zero) {
// Modulo succeeds
- __ movq(r12, Immediate(id));
+ __ movq(r15, Immediate(id));
int result = x % y;
__ Move(r8, Smi::FromInt(result));
__ SmiMod(r9, rcx, r14, exit);
- __ incq(r12);
- __ SmiCompare(r9, r8);
+ __ incq(r15);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
- __ incq(r12);
- __ SmiCompare(rcx, r11);
+ __ incq(r15);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
- __ incq(r12);
+ __ incq(r15);
__ SmiMod(rcx, rcx, r14, exit);
- __ incq(r12);
- __ SmiCompare(rcx, r8);
+ __ incq(r15);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
} else {
// Modulo fails.
- __ movq(r12, Immediate(id + 8));
+ __ movq(r15, Immediate(id + 8));
Label fail_ok, fail_ok2;
__ SmiMod(r9, rcx, r14, &fail_ok);
__ jmp(exit);
__ bind(&fail_ok);
- __ incq(r12);
- __ SmiCompare(rcx, r11);
+ __ incq(r15);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
- __ incq(r12);
+ __ incq(r15);
__ SmiMod(rcx, rcx, r14, &fail_ok2);
__ jmp(exit);
__ bind(&fail_ok2);
- __ incq(r12);
- __ SmiCompare(rcx, r11);
+ __ incq(r15);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
}
}
TEST(SmiMod) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1285,7 +1320,9 @@ TEST(SmiMod) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1293,7 +1330,7 @@ TEST(SmiMod) {
Label exit;
__ push(r14);
- __ push(r12);
+ __ push(r15);
TestSmiMod(masm, &exit, 0x10, 1, 1);
TestSmiMod(masm, &exit, 0x20, 1, 0);
TestSmiMod(masm, &exit, 0x30, -1, 0);
@@ -1315,10 +1352,10 @@ TEST(SmiMod) {
TestSmiMod(masm, &exit, 0x130, Smi::kMinValue, Smi::kMinValue);
TestSmiMod(masm, &exit, 0x140, Smi::kMinValue, -1);
- __ xor_(r12, r12); // Success.
+ __ xor_(r15, r15); // Success.
__ bind(&exit);
- __ movq(rax, r12);
- __ pop(r12);
+ __ movq(rax, r15);
+ __ pop(r15);
__ pop(r14);
ExitCode(masm);
__ ret(0);
@@ -1340,7 +1377,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
ASSERT(index.reg.is(rcx) || index.reg.is(rdx));
__ shl(index.reg, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(x) << i);
- __ SmiCompare(index.reg, r8);
+ __ cmpq(index.reg, r8);
__ j(not_equal, exit);
__ incq(rax);
__ Move(rcx, Smi::FromInt(x));
@@ -1348,7 +1385,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
ASSERT(index.reg.is(rcx));
__ shl(rcx, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(x) << i);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1357,7 +1394,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
ASSERT(index.reg.is(rcx) || index.reg.is(rdx));
__ shl(index.reg, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(-x) << i);
- __ SmiCompare(index.reg, r8);
+ __ cmpq(index.reg, r8);
__ j(not_equal, exit);
__ incq(rax);
__ Move(rcx, Smi::FromInt(x));
@@ -1365,13 +1402,14 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
ASSERT(index.reg.is(rcx));
__ shl(rcx, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(-x) << i);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ incq(rax);
}
}
TEST(SmiIndex) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1380,7 +1418,9 @@ TEST(SmiIndex) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1414,7 +1454,7 @@ void TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ SelectNonSmi(r9, rcx, rdx, exit);
__ incq(rax);
- __ SmiCompare(r9, rdx);
+ __ cmpq(r9, rdx);
__ j(not_equal, exit);
__ incq(rax);
@@ -1424,7 +1464,7 @@ void TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ SelectNonSmi(r9, rcx, rdx, exit);
__ incq(rax);
- __ SmiCompare(r9, rcx);
+ __ cmpq(r9, rcx);
__ j(not_equal, exit);
__ incq(rax);
@@ -1440,6 +1480,7 @@ void TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) {
TEST(SmiSelectNonSmi) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1448,7 +1489,9 @@ TEST(SmiSelectNonSmi) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false); // Avoid inline checks.
@@ -1488,36 +1531,37 @@ void TestSmiAnd(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ Move(rdx, Smi::FromInt(y));
__ Move(r8, Smi::FromInt(result));
__ SmiAnd(r9, rcx, rdx);
- __ SmiCompare(r8, r9);
+ __ cmpq(r8, r9);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiAnd(rcx, rcx, rdx);
- __ SmiCompare(r8, rcx);
+ __ cmpq(r8, rcx);
__ j(not_equal, exit);
__ movq(rcx, r11);
__ incq(rax);
__ SmiAndConstant(r9, rcx, Smi::FromInt(y));
- __ SmiCompare(r8, r9);
+ __ cmpq(r8, r9);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiAndConstant(rcx, rcx, Smi::FromInt(y));
- __ SmiCompare(r8, rcx);
+ __ cmpq(r8, rcx);
__ j(not_equal, exit);
}
TEST(SmiAnd) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1526,7 +1570,9 @@ TEST(SmiAnd) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1568,36 +1614,37 @@ void TestSmiOr(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ Move(rdx, Smi::FromInt(y));
__ Move(r8, Smi::FromInt(result));
__ SmiOr(r9, rcx, rdx);
- __ SmiCompare(r8, r9);
+ __ cmpq(r8, r9);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiOr(rcx, rcx, rdx);
- __ SmiCompare(r8, rcx);
+ __ cmpq(r8, rcx);
__ j(not_equal, exit);
__ movq(rcx, r11);
__ incq(rax);
__ SmiOrConstant(r9, rcx, Smi::FromInt(y));
- __ SmiCompare(r8, r9);
+ __ cmpq(r8, r9);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiOrConstant(rcx, rcx, Smi::FromInt(y));
- __ SmiCompare(r8, rcx);
+ __ cmpq(r8, rcx);
__ j(not_equal, exit);
}
TEST(SmiOr) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1606,7 +1653,9 @@ TEST(SmiOr) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1650,36 +1699,37 @@ void TestSmiXor(MacroAssembler* masm, Label* exit, int id, int x, int y) {
__ Move(rdx, Smi::FromInt(y));
__ Move(r8, Smi::FromInt(result));
__ SmiXor(r9, rcx, rdx);
- __ SmiCompare(r8, r9);
+ __ cmpq(r8, r9);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiXor(rcx, rcx, rdx);
- __ SmiCompare(r8, rcx);
+ __ cmpq(r8, rcx);
__ j(not_equal, exit);
__ movq(rcx, r11);
__ incq(rax);
__ SmiXorConstant(r9, rcx, Smi::FromInt(y));
- __ SmiCompare(r8, r9);
+ __ cmpq(r8, r9);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiXorConstant(rcx, rcx, Smi::FromInt(y));
- __ SmiCompare(r8, rcx);
+ __ cmpq(r8, rcx);
__ j(not_equal, exit);
}
TEST(SmiXor) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1688,7 +1738,9 @@ TEST(SmiXor) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1731,21 +1783,22 @@ void TestSmiNot(MacroAssembler* masm, Label* exit, int id, int x) {
__ movq(r11, rcx);
__ SmiNot(r9, rcx);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx);
+ __ cmpq(r11, rcx);
__ j(not_equal, exit);
__ incq(rax);
__ SmiNot(rcx, rcx);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
}
TEST(SmiNot) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1754,7 +1807,9 @@ TEST(SmiNot) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1797,7 +1852,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
__ SmiShiftLeftConstant(r9, rcx, shift);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1805,7 +1860,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
__ SmiShiftLeftConstant(rcx, rcx, shift);
__ incq(rax);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1814,7 +1869,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
__ SmiShiftLeft(r9, rdx, rcx);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1823,7 +1878,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
__ SmiShiftLeft(r9, rdx, r11);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1832,7 +1887,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
__ SmiShiftLeft(rdx, rdx, r11);
__ incq(rax);
- __ SmiCompare(rdx, r8);
+ __ cmpq(rdx, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1841,6 +1896,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
TEST(SmiShiftLeft) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1849,7 +1905,9 @@ TEST(SmiShiftLeft) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1893,7 +1951,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
__ SmiShiftLogicalRightConstant(r9, rcx, shift, exit);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1902,7 +1960,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
__ SmiShiftLogicalRight(r9, rdx, rcx, exit);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1911,7 +1969,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
__ SmiShiftLogicalRight(r9, rdx, r11, exit);
__ incq(rax);
- __ SmiCompare(r9, r8);
+ __ cmpq(r9, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -1925,7 +1983,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
__ bind(&fail_ok);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
__ incq(rax);
@@ -1936,7 +1994,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
__ bind(&fail_ok3);
__ incq(rax);
- __ SmiCompare(rcx, r11);
+ __ cmpq(rcx, r11);
__ j(not_equal, exit);
__ addq(rax, Immediate(3));
@@ -1946,6 +2004,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
TEST(SmiShiftLogicalRight) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -1954,7 +2013,9 @@ TEST(SmiShiftLogicalRight) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -1997,7 +2058,7 @@ void TestSmiShiftArithmeticRight(MacroAssembler* masm,
__ Move(rcx, Smi::FromInt(x));
__ SmiShiftArithmeticRightConstant(rcx, rcx, shift);
- __ SmiCompare(rcx, r8);
+ __ cmpq(rcx, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -2005,7 +2066,7 @@ void TestSmiShiftArithmeticRight(MacroAssembler* masm,
__ Move(r11, Smi::FromInt(shift));
__ SmiShiftArithmeticRight(rdx, rdx, r11);
- __ SmiCompare(rdx, r8);
+ __ cmpq(rdx, r8);
__ j(not_equal, exit);
__ incq(rax);
@@ -2014,6 +2075,7 @@ void TestSmiShiftArithmeticRight(MacroAssembler* masm,
TEST(SmiShiftArithmeticRight) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
@@ -2022,7 +2084,9 @@ TEST(SmiShiftArithmeticRight) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -2062,14 +2126,14 @@ void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) {
__ Move(rcx, Smi::FromInt(x));
__ movq(r11, rcx);
__ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rcx, power);
- __ SmiCompare(rdx, r8);
+ __ cmpq(rdx, r8);
__ j(not_equal, exit);
__ incq(rax);
- __ SmiCompare(r11, rcx); // rcx unchanged.
+ __ cmpq(r11, rcx); // rcx unchanged.
__ j(not_equal, exit);
__ incq(rax);
__ PositiveSmiTimesPowerOfTwoToInteger64(rcx, rcx, power);
- __ SmiCompare(rdx, r8);
+ __ cmpq(rdx, r8);
__ j(not_equal, exit);
__ incq(rax);
}
@@ -2077,15 +2141,18 @@ void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) {
TEST(PositiveSmiTimesPowerOfTwoToInteger64) {
+ v8::internal::V8::Initialize(NULL);
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer =
- static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2,
+ static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4,
&actual_size,
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -2116,6 +2183,7 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) {
TEST(OperandOffset) {
+ v8::internal::V8::Initialize(NULL);
int data[256];
for (int i = 0; i < 256; i++) { data[i] = i * 0x01010101; }
@@ -2127,7 +2195,9 @@ TEST(OperandOffset) {
true));
CHECK(buffer);
HandleScope handles;
- MacroAssembler assembler(buffer, static_cast<int>(actual_size));
+ MacroAssembler assembler(Isolate::Current(),
+ buffer,
+ static_cast<int>(actual_size));
MacroAssembler* masm = &assembler;
masm->set_allow_stub_calls(false);
@@ -2150,7 +2220,7 @@ TEST(OperandOffset) {
__ push(Immediate(0x108));
__ push(Immediate(0x109)); // <-- rsp
// rbp = rsp[9]
- // r12 = rsp[3]
+ // r15 = rsp[3]
// rbx = rsp[5]
// r13 = rsp[7]
__ lea(r14, Operand(rsp, 3 * kPointerSize));
diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc
index 3e3175e73..dcb51a0bc 100644
--- a/deps/v8/test/cctest/test-mark-compact.cc
+++ b/deps/v8/test/cctest/test-mark-compact.cc
@@ -31,7 +31,6 @@
#include "global-handles.h"
#include "snapshot.h"
-#include "top.h"
#include "cctest.h"
using namespace v8::internal;
@@ -79,7 +78,7 @@ TEST(Promotion) {
// from new space.
FLAG_gc_global = true;
FLAG_always_compact = true;
- Heap::ConfigureHeap(2*256*KB, 4*MB, 4*MB);
+ HEAP->ConfigureHeap(2*256*KB, 4*MB, 4*MB);
InitializeVM();
@@ -87,25 +86,25 @@ TEST(Promotion) {
// Allocate a fixed array in the new space.
int array_size =
- (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
+ (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
(kPointerSize * 4);
- Object* obj = Heap::AllocateFixedArray(array_size)->ToObjectChecked();
+ Object* obj = HEAP->AllocateFixedArray(array_size)->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);
+ 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, 4*MB, 4*MB);
+ HEAP->ConfigureHeap(2*256*KB, 4*MB, 4*MB);
// Test the situation that some objects in new space are promoted to
// the old space
@@ -114,23 +113,23 @@ TEST(NoPromotion) {
v8::HandleScope sc;
// Do a mark compact GC to shrink the heap.
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
// Allocate a big Fixed array in the new space.
- int size = (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
+ int size = (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
kPointerSize;
- Object* obj = Heap::AllocateFixedArray(size)->ToObjectChecked();
+ Object* obj = HEAP->AllocateFixedArray(size)->ToObjectChecked();
Handle<FixedArray> array(FixedArray::cast(obj));
// Array still stays in the new space.
- CHECK(Heap::InSpace(*array, 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);
+ { MaybeObject* maybe_obj = HEAP->AllocateFixedArray(100, TENURED);
if (!maybe_obj->ToObject(&obj)) break;
}
@@ -139,10 +138,10 @@ TEST(NoPromotion) {
}
// Call mark compact GC, and it should pass.
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
// array should not be promoted because the old space is full.
- CHECK(Heap::InSpace(*array, NEW_SPACE));
+ CHECK(HEAP->InSpace(*array, NEW_SPACE));
}
@@ -151,90 +150,86 @@ TEST(MarkCompactCollector) {
v8::HandleScope sc;
// call mark-compact when heap is empty
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
// keep allocating garbage in new space until it fails
const int ARRAY_SIZE = 100;
Object* array;
MaybeObject* maybe_array;
do {
- maybe_array = Heap::AllocateFixedArray(ARRAY_SIZE);
+ maybe_array = HEAP->AllocateFixedArray(ARRAY_SIZE);
} while (maybe_array->ToObject(&array));
- Heap::CollectGarbage(NEW_SPACE);
+ HEAP->CollectGarbage(NEW_SPACE);
- array = Heap::AllocateFixedArray(ARRAY_SIZE)->ToObjectChecked();
+ array = HEAP->AllocateFixedArray(ARRAY_SIZE)->ToObjectChecked();
// keep allocating maps until it fails
Object* mapp;
MaybeObject* maybe_mapp;
do {
- maybe_mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ maybe_mapp = HEAP->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
} while (maybe_mapp->ToObject(&mapp));
- Heap::CollectGarbage(MAP_SPACE);
- mapp = Heap::AllocateMap(JS_OBJECT_TYPE,
+ HEAP->CollectGarbage(MAP_SPACE);
+ mapp = HEAP->AllocateMap(JS_OBJECT_TYPE,
JSObject::kHeaderSize)->ToObjectChecked();
// allocate a garbage
String* func_name =
- String::cast(Heap::LookupAsciiSymbol("theFunction")->ToObjectChecked());
+ String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked());
SharedFunctionInfo* function_share = SharedFunctionInfo::cast(
- Heap::AllocateSharedFunctionInfo(func_name)->ToObjectChecked());
+ HEAP->AllocateSharedFunctionInfo(func_name)->ToObjectChecked());
JSFunction* function = JSFunction::cast(
- Heap::AllocateFunction(*Top::function_map(),
+ HEAP->AllocateFunction(*Isolate::Current()->function_map(),
function_share,
- Heap::undefined_value())->ToObjectChecked());
+ HEAP->undefined_value())->ToObjectChecked());
Map* initial_map =
- Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE,
+ Map::cast(HEAP->AllocateMap(JS_OBJECT_TYPE,
JSObject::kHeaderSize)->ToObjectChecked());
function->set_initial_map(initial_map);
- Top::context()->global()->SetProperty(func_name,
- function,
- NONE,
- kNonStrictMode)->ToObjectChecked();
+ Isolate::Current()->context()->global()->SetProperty(
+ func_name, function, NONE, kNonStrictMode)->ToObjectChecked();
- JSObject* obj =
- JSObject::cast(Heap::AllocateJSObject(function)->ToObjectChecked());
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ JSObject* obj = JSObject::cast(
+ HEAP->AllocateJSObject(function)->ToObjectChecked());
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
func_name =
- String::cast(Heap::LookupAsciiSymbol("theFunction")->ToObjectChecked());
- CHECK(Top::context()->global()->HasLocalProperty(func_name));
- Object* func_value =
- Top::context()->global()->GetProperty(func_name)->ToObjectChecked();
+ String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked());
+ CHECK(Isolate::Current()->context()->global()->HasLocalProperty(func_name));
+ Object* func_value = Isolate::Current()->context()->global()->
+ GetProperty(func_name)->ToObjectChecked();
CHECK(func_value->IsJSFunction());
function = JSFunction::cast(func_value);
- obj = JSObject::cast(Heap::AllocateJSObject(function)->ToObjectChecked());
+ obj = JSObject::cast(HEAP->AllocateJSObject(function)->ToObjectChecked());
String* obj_name =
- String::cast(Heap::LookupAsciiSymbol("theObject")->ToObjectChecked());
- Top::context()->global()->SetProperty(obj_name,
- obj,
- NONE,
- kNonStrictMode)->ToObjectChecked();
+ String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked());
+ Isolate::Current()->context()->global()->SetProperty(
+ obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked();
String* prop_name =
- String::cast(Heap::LookupAsciiSymbol("theSlot")->ToObjectChecked());
+ String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked());
obj->SetProperty(prop_name,
Smi::FromInt(23),
NONE,
kNonStrictMode)->ToObjectChecked();
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
obj_name =
- String::cast(Heap::LookupAsciiSymbol("theObject")->ToObjectChecked());
- CHECK(Top::context()->global()->HasLocalProperty(obj_name));
- CHECK(Top::context()->global()->
- GetProperty(obj_name)->ToObjectChecked()->IsJSObject());
- obj = JSObject::cast(
- Top::context()->global()->GetProperty(obj_name)->ToObjectChecked());
+ String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked());
+ CHECK(Isolate::Current()->context()->global()->HasLocalProperty(obj_name));
+ CHECK(Isolate::Current()->context()->global()->
+ GetProperty(obj_name)->ToObjectChecked()->IsJSObject());
+ obj = JSObject::cast(Isolate::Current()->context()->global()->
+ GetProperty(obj_name)->ToObjectChecked());
prop_name =
- String::cast(Heap::LookupAsciiSymbol("theSlot")->ToObjectChecked());
- CHECK(obj->GetProperty(prop_name)->ToObjectChecked() == Smi::FromInt(23));
+ String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked());
+ CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23));
}
static Handle<Map> CreateMap() {
- return Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ return FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
}
@@ -246,20 +241,20 @@ TEST(MapCompact) {
v8::HandleScope sc;
// keep allocating maps while pointers are still encodable and thus
// mark compact is permitted.
- Handle<JSObject> root = Factory::NewJSObjectFromMap(CreateMap());
+ Handle<JSObject> root = FACTORY->NewJSObjectFromMap(CreateMap());
do {
Handle<Map> map = CreateMap();
map->set_prototype(*root);
- root = Factory::NewJSObjectFromMap(map);
- } while (Heap::map_space()->MapPointersEncodable());
+ root = FACTORY->NewJSObjectFromMap(map);
+ } while (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(true);
+ HEAP->CollectAllGarbage(true);
// And now map pointers should be encodable again.
- CHECK(Heap::map_space()->MapPointersEncodable());
+ CHECK(HEAP->map_space()->MapPointersEncodable());
}
@@ -281,16 +276,16 @@ static void GCEpilogueCallbackFunc() {
TEST(GCCallback) {
InitializeVM();
- Heap::SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc);
- Heap::SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc);
+ HEAP->SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc);
+ HEAP->SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc);
// Scavenge does not call GC callback functions.
- Heap::PerformScavenge();
+ HEAP->PerformScavenge();
CHECK_EQ(0, gc_starts);
CHECK_EQ(gc_ends, gc_starts);
- Heap::CollectGarbage(OLD_POINTER_SPACE);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
CHECK_EQ(1, gc_starts);
CHECK_EQ(gc_ends, gc_starts);
}
@@ -298,39 +293,51 @@ TEST(GCCallback) {
static int NumberOfWeakCalls = 0;
static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) {
+ ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
handle.Dispose();
}
TEST(ObjectGroups) {
InitializeVM();
+ GlobalHandles* global_handles = Isolate::Current()->global_handles();
NumberOfWeakCalls = 0;
v8::HandleScope handle_scope;
Handle<Object> g1s1 =
- GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked());
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
Handle<Object> g1s2 =
- GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked());
- GlobalHandles::MakeWeak(g1s1.location(),
- reinterpret_cast<void*>(1234),
- &WeakPointerCallback);
- GlobalHandles::MakeWeak(g1s2.location(),
- reinterpret_cast<void*>(1234),
- &WeakPointerCallback);
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
+ Handle<Object> g1c1 =
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
+ global_handles->MakeWeak(g1s1.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+ global_handles->MakeWeak(g1s2.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+ global_handles->MakeWeak(g1c1.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
Handle<Object> g2s1 =
- GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked());
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
Handle<Object> g2s2 =
- GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked());
- GlobalHandles::MakeWeak(g2s1.location(),
- reinterpret_cast<void*>(1234),
- &WeakPointerCallback);
- GlobalHandles::MakeWeak(g2s2.location(),
- reinterpret_cast<void*>(1234),
- &WeakPointerCallback);
-
- Handle<Object> root = GlobalHandles::Create(*g1s1); // make a root.
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
+ Handle<Object> g2c1 =
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
+ global_handles->MakeWeak(g2s1.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+ global_handles->MakeWeak(g2s2.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+ global_handles->MakeWeak(g2c1.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+
+ Handle<Object> root = global_handles->Create(*g1s1); // make a root.
// Connect group 1 and 2, make a cycle.
Handle<FixedArray>::cast(g1s2)->set(0, *g2s2);
@@ -338,31 +345,100 @@ TEST(ObjectGroups) {
{
Object** g1_objects[] = { g1s1.location(), g1s2.location() };
+ Object** g1_children[] = { g1c1.location() };
Object** g2_objects[] = { g2s1.location(), g2s2.location() };
- GlobalHandles::AddGroup(g1_objects, 2);
- GlobalHandles::AddGroup(g2_objects, 2);
+ Object** g2_children[] = { g2c1.location() };
+ global_handles->AddObjectGroup(g1_objects, 2, NULL);
+ global_handles->AddImplicitReferences(
+ Handle<HeapObject>::cast(g1s1).location(), g1_children, 1);
+ global_handles->AddObjectGroup(g2_objects, 2, NULL);
+ global_handles->AddImplicitReferences(
+ Handle<HeapObject>::cast(g2s2).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);
// Weaken the root.
- GlobalHandles::MakeWeak(root.location(),
- reinterpret_cast<void*>(1234),
- &WeakPointerCallback);
+ global_handles->MakeWeak(root.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+ // But make children strong roots---all the objects (except for children)
+ // should be collectable now.
+ global_handles->ClearWeakness(g1c1.location());
+ global_handles->ClearWeakness(g2c1.location());
// Groups are deleted, rebuild groups.
{
Object** g1_objects[] = { g1s1.location(), g1s2.location() };
+ Object** g1_children[] = { g1c1.location() };
Object** g2_objects[] = { g2s1.location(), g2s2.location() };
- GlobalHandles::AddGroup(g1_objects, 2);
- GlobalHandles::AddGroup(g2_objects, 2);
+ Object** g2_children[] = { g2c1.location() };
+ global_handles->AddObjectGroup(g1_objects, 2, NULL);
+ global_handles->AddImplicitReferences(
+ Handle<HeapObject>::cast(g1s1).location(), g1_children, 1);
+ global_handles->AddObjectGroup(g2_objects, 2, NULL);
+ global_handles->AddImplicitReferences(
+ Handle<HeapObject>::cast(g2s2).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);
+
+ // And now make children weak again and collect them.
+ global_handles->MakeWeak(g1c1.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+ global_handles->MakeWeak(g2c1.location(),
+ reinterpret_cast<void*>(1234),
+ &WeakPointerCallback);
+
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
+ CHECK_EQ(7, NumberOfWeakCalls);
+}
+
+
+class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
+ public:
+ TestRetainedObjectInfo() : has_been_disposed_(false) {}
+
+ bool has_been_disposed() { return has_been_disposed_; }
+
+ virtual void Dispose() {
+ ASSERT(!has_been_disposed_);
+ has_been_disposed_ = true;
+ }
+
+ virtual bool IsEquivalent(v8::RetainedObjectInfo* other) {
+ return other == this;
+ }
+
+ virtual intptr_t GetHash() { return 0; }
+
+ virtual const char* GetLabel() { return "whatever"; }
+
+ private:
+ bool has_been_disposed_;
+};
+
+
+TEST(EmptyObjectGroups) {
+ InitializeVM();
+ GlobalHandles* global_handles = Isolate::Current()->global_handles();
+
+ v8::HandleScope handle_scope;
+
+ Handle<Object> object =
+ global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
+
+ TestRetainedObjectInfo info;
+ global_handles->AddObjectGroup(NULL, 0, &info);
+ ASSERT(info.has_been_disposed());
+
+ global_handles->AddImplicitReferences(
+ Handle<HeapObject>::cast(object).location(), NULL, 0);
}
diff --git a/deps/v8/test/cctest/test-mips.cc b/deps/v8/test/cctest/test-mips.cc
deleted file mode 100644
index efd4cc975..000000000
--- a/deps/v8/test/cctest/test-mips.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.
-
-
-#include "v8.h"
-#include "execution.h"
-
-#include "cctest.h"
-
-using ::v8::Local;
-using ::v8::String;
-using ::v8::Script;
-
-namespace i = ::v8::internal;
-
-TEST(MIPSFunctionCalls) {
- // Disable compilation of natives.
- i::FLAG_disable_native_files = true;
- i::FLAG_full_compiler = false;
-
- v8::HandleScope scope;
- LocalContext env; // from cctest.h
-
- const char* c_source = "function foo() { return 0x1234; }; foo();";
- Local<String> source = ::v8::String::New(c_source);
- Local<Script> script = ::v8::Script::Compile(source);
- CHECK_EQ(0x1234, script->Run()->Int32Value());
-}
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index 8ee40385a..96a181d7a 100755
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// 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:
@@ -31,6 +31,7 @@
#include "v8.h"
+#include "isolate.h"
#include "token.h"
#include "scanner.h"
#include "parser.h"
@@ -136,8 +137,9 @@ TEST(ScanHTMLEndComments) {
// Regression test. See:
// http://code.google.com/p/chromium/issues/detail?id=53548
// Tests that --> is correctly interpreted as comment-to-end-of-line if there
- // is only whitespace before it on the line, even after a multiline-comment
- // comment. This was not the case if it occurred before the first real token
+ // is only whitespace before it on the line (with comments considered as
+ // whitespace, even a multiline-comment containing a newline).
+ // This was not the case if it occurred before the first real token
// in the input.
const char* tests[] = {
// Before first real token.
@@ -151,9 +153,19 @@ TEST(ScanHTMLEndComments) {
NULL
};
+ const char* fail_tests[] = {
+ "x --> is eol-comment\nvar y = 37;\n",
+ "\"\\n\" --> is eol-comment\nvar y = 37;\n",
+ "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
+ "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
+ "var x = 42; --> is eol-comment\nvar y = 37;\n",
+ "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
+ NULL
+ };
+
// Parser/Scanner needs a stack limit.
int marker;
- i::StackGuard::SetStackLimit(
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
for (int i = 0; tests[i]; i++) {
@@ -162,6 +174,13 @@ TEST(ScanHTMLEndComments) {
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]));
+ CHECK(data == NULL || data->HasError());
+ delete data;
+ }
}
@@ -184,7 +203,7 @@ TEST(Preparsing) {
v8::Persistent<v8::Context> context = v8::Context::New();
v8::Context::Scope context_scope(context);
int marker;
- i::StackGuard::SetStackLimit(
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
// Source containing functions that might be lazily compiled and all types
@@ -245,26 +264,26 @@ TEST(Preparsing) {
TEST(StandAlonePreParser) {
int marker;
- i::StackGuard::SetStackLimit(
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* programs[] = {
"{label: 42}",
"var x = 42;",
"function foo(x, y) { return x + y; }",
- "native function foo(); return %ArgleBargle(glop);",
+ "%ArgleBargle(glop);",
"var x = new new Function('this.x = 42');",
NULL
};
- uintptr_t stack_limit = i::StackGuard::real_climit();
+ uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
for (int i = 0; programs[i]; i++) {
const char* program = programs[i];
i::Utf8ToUC16CharacterStream stream(
reinterpret_cast<const i::byte*>(program),
static_cast<unsigned>(strlen(program)));
i::CompleteParserRecorder log;
- i::V8JavaScriptScanner scanner;
+ i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
v8::preparser::PreParser::PreParseResult result =
@@ -281,7 +300,7 @@ TEST(StandAlonePreParser) {
TEST(RegressChromium62639) {
int marker;
- i::StackGuard::SetStackLimit(
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* program = "var x = 'something';\n"
@@ -306,7 +325,7 @@ TEST(Regress928) {
// the block could be lazily compiled, and an extra, unexpected,
// entry was added to the data.
int marker;
- i::StackGuard::SetStackLimit(
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* program =
@@ -342,7 +361,7 @@ TEST(Regress928) {
TEST(PreParseOverflow) {
int marker;
- i::StackGuard::SetStackLimit(
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
size_t kProgramSize = 1024 * 1024;
@@ -351,13 +370,13 @@ TEST(PreParseOverflow) {
memset(*program, '(', kProgramSize);
program[kProgramSize] = '\0';
- uintptr_t stack_limit = i::StackGuard::real_climit();
+ uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
i::Utf8ToUC16CharacterStream stream(
reinterpret_cast<const i::byte*>(*program),
static_cast<unsigned>(kProgramSize));
i::CompleteParserRecorder log;
- i::V8JavaScriptScanner scanner;
+ i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
@@ -405,10 +424,10 @@ void TestCharacterStream(const char* ascii_source,
}
i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length));
i::Handle<i::String> ascii_string(
- i::Factory::NewStringFromAscii(ascii_vector));
+ FACTORY->NewStringFromAscii(ascii_vector));
TestExternalResource resource(*uc16_buffer, length);
i::Handle<i::String> uc16_string(
- i::Factory::NewExternalStringFromTwoByte(&resource));
+ FACTORY->NewExternalStringFromTwoByte(&resource));
i::ExternalTwoByteStringUC16CharacterStream uc16_stream(
i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
@@ -575,7 +594,7 @@ void TestStreamScanner(i::UC16CharacterStream* stream,
i::Token::Value* expected_tokens,
int skip_pos = 0, // Zero means not skipping.
int skip_to = 0) {
- i::V8JavaScriptScanner scanner;
+ i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(stream);
int i = 0;
@@ -654,7 +673,7 @@ void TestScanRegExp(const char* re_source, const char* expected) {
i::Utf8ToUC16CharacterStream stream(
reinterpret_cast<const i::byte*>(re_source),
static_cast<unsigned>(strlen(re_source)));
- i::V8JavaScriptScanner scanner;
+ i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
i::Token::Value start = scanner.peek();
diff --git a/deps/v8/test/cctest/test-platform-linux.cc b/deps/v8/test/cctest/test-platform-linux.cc
index e1a00e106..756b9473c 100644
--- a/deps/v8/test/cctest/test-platform-linux.cc
+++ b/deps/v8/test/cctest/test-platform-linux.cc
@@ -67,6 +67,7 @@ TEST(BusyLock) {
TEST(VirtualMemory) {
+ OS::Setup();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
diff --git a/deps/v8/test/cctest/test-platform-tls.cc b/deps/v8/test/cctest/test-platform-tls.cc
new file mode 100644
index 000000000..7f33aa2fb
--- /dev/null
+++ b/deps/v8/test/cctest/test-platform-tls.cc
@@ -0,0 +1,66 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+//
+// Tests of fast TLS support.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "checks.h"
+#include "platform.h"
+
+using v8::internal::Thread;
+
+static const int kValueCount = 128;
+
+static Thread::LocalStorageKey keys[kValueCount];
+
+static void* GetValue(int num) {
+ return reinterpret_cast<void*>(static_cast<intptr_t>(num + 1));
+}
+
+static void DoTest() {
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK(!Thread::HasThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ Thread::SetThreadLocal(keys[i], GetValue(i));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK(Thread::HasThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys[i]));
+ CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ Thread::SetThreadLocal(keys[i], GetValue(kValueCount - i - 1));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK(Thread::HasThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK_EQ(GetValue(kValueCount - i - 1),
+ Thread::GetThreadLocal(keys[i]));
+ CHECK_EQ(GetValue(kValueCount - i - 1),
+ Thread::GetExistingThreadLocal(keys[i]));
+ }
+}
+
+class TestThread : public Thread {
+ public:
+ TestThread() : Thread("TestThread") {}
+
+ virtual void Run() {
+ DoTest();
+ }
+};
+
+TEST(FastTLS) {
+ for (int i = 0; i < kValueCount; i++) {
+ keys[i] = Thread::CreateThreadLocalKey();
+ }
+ DoTest();
+ TestThread thread;
+ thread.Start();
+ thread.Join();
+}
diff --git a/deps/v8/test/cctest/test-platform-win32.cc b/deps/v8/test/cctest/test-platform-win32.cc
index a5a6dd58a..9bd0014c6 100644
--- a/deps/v8/test/cctest/test-platform-win32.cc
+++ b/deps/v8/test/cctest/test-platform-win32.cc
@@ -13,6 +13,7 @@ using namespace ::v8::internal;
TEST(VirtualMemory) {
+ OS::Setup();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index c60d0720a..fbe5834e5 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -56,7 +56,7 @@ TEST(TokenEnumerator) {
CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
}
CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2));
- i::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2));
CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index 51fef7146..6588c68b7 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/test/cctest/test-regexp.cc
@@ -45,6 +45,10 @@
#include "arm/macro-assembler-arm.h"
#include "arm/regexp-macro-assembler-arm.h"
#endif
+#ifdef V8_TARGET_ARCH_MIPS
+#include "mips/macro-assembler-mips.h"
+#include "mips/regexp-macro-assembler-mips.h"
+#endif
#ifdef V8_TARGET_ARCH_X64
#include "x64/macro-assembler-x64.h"
#include "x64/regexp-macro-assembler-x64.h"
@@ -61,8 +65,8 @@ using namespace v8::internal;
static bool CheckParse(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
- ZoneScope zone_scope(DELETE_ON_EXIT);
- FlatStringReader reader(CStrVector(input));
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
return v8::internal::RegExpParser::ParseRegExp(&reader, false, &result);
}
@@ -71,8 +75,8 @@ static bool CheckParse(const char* input) {
static SmartPointer<const char> Parse(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
- ZoneScope zone_scope(DELETE_ON_EXIT);
- FlatStringReader reader(CStrVector(input));
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
CHECK(result.tree != NULL);
@@ -85,8 +89,8 @@ static bool CheckSimple(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
unibrow::Utf8InputBuffer<> buffer(input, StrLength(input));
- ZoneScope zone_scope(DELETE_ON_EXIT);
- FlatStringReader reader(CStrVector(input));
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
CHECK(result.tree != NULL);
@@ -103,8 +107,8 @@ static MinMaxPair CheckMinMaxMatch(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
unibrow::Utf8InputBuffer<> buffer(input, StrLength(input));
- ZoneScope zone_scope(DELETE_ON_EXIT);
- FlatStringReader reader(CStrVector(input));
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
CHECK(result.tree != NULL);
@@ -374,8 +378,8 @@ static void ExpectError(const char* input,
const char* expected) {
V8::Initialize(NULL);
v8::HandleScope scope;
- ZoneScope zone_scope(DELETE_ON_EXIT);
- FlatStringReader reader(CStrVector(input));
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ FlatStringReader reader(Isolate::Current(), CStrVector(input));
RegExpCompileData result;
CHECK(!v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
CHECK(result.tree == NULL);
@@ -456,7 +460,7 @@ static bool NotWord(uc16 c) {
static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) {
- ZoneScope scope(DELETE_ON_EXIT);
+ ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
CharacterRange::AddClassEscape(c, ranges);
for (unsigned i = 0; i < (1 << 16); i++) {
@@ -471,6 +475,7 @@ static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) {
TEST(CharacterClassEscapes) {
+ v8::internal::V8::Initialize(NULL);
TestCharacterClassEscapes('.', IsRegExpNewline);
TestCharacterClassEscapes('d', IsDigit);
TestCharacterClassEscapes('D', NotDigit);
@@ -483,12 +488,14 @@ TEST(CharacterClassEscapes) {
static RegExpNode* Compile(const char* input, bool multiline, bool is_ascii) {
V8::Initialize(NULL);
- FlatStringReader reader(CStrVector(input));
+ Isolate* isolate = Isolate::Current();
+ FlatStringReader reader(isolate, CStrVector(input));
RegExpCompileData compile_data;
if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline,
&compile_data))
return NULL;
- Handle<String> pattern = Factory::NewStringFromUtf8(CStrVector(input));
+ Handle<String> pattern = isolate->factory()->
+ NewStringFromUtf8(CStrVector(input));
RegExpEngine::Compile(&compile_data, false, multiline, pattern, is_ascii);
return compile_data.node;
}
@@ -499,7 +506,7 @@ static void Execute(const char* input,
bool is_ascii,
bool dot_output = false) {
v8::HandleScope scope;
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
RegExpNode* node = Compile(input, multiline, is_ascii);
USE(node);
#ifdef DEBUG
@@ -538,8 +545,9 @@ static unsigned PseudoRandom(int i, int j) {
TEST(SplayTreeSimple) {
+ v8::internal::V8::Initialize(NULL);
static const unsigned kLimit = 1000;
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneSplayTree<TestConfig> tree;
bool seen[kLimit];
for (unsigned i = 0; i < kLimit; i++) seen[i] = false;
@@ -590,6 +598,7 @@ TEST(SplayTreeSimple) {
TEST(DispatchTableConstruction) {
+ v8::internal::V8::Initialize(NULL);
// Initialize test data.
static const int kLimit = 1000;
static const int kRangeCount = 8;
@@ -606,7 +615,7 @@ TEST(DispatchTableConstruction) {
}
}
// Enter test data into dispatch table.
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
DispatchTable table;
for (int i = 0; i < kRangeCount; i++) {
uc16* range = ranges[i];
@@ -667,13 +676,13 @@ typedef RegExpMacroAssemblerX64 ArchRegExpMacroAssembler;
#elif V8_TARGET_ARCH_ARM
typedef RegExpMacroAssemblerARM ArchRegExpMacroAssembler;
#elif V8_TARGET_ARCH_MIPS
-typedef RegExpMacroAssembler ArchRegExpMacroAssembler;
+typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler;
#endif
class ContextInitializer {
public:
ContextInitializer()
- : env_(), scope_(), zone_(DELETE_ON_EXIT), stack_guard_() {
+ : env_(), scope_(), zone_(Isolate::Current(), DELETE_ON_EXIT) {
env_ = v8::Context::New();
env_->Enter();
}
@@ -685,7 +694,6 @@ class ContextInitializer {
v8::Persistent<v8::Context> env_;
v8::HandleScope scope_;
v8::internal::ZoneScope zone_;
- v8::internal::StackGuard stack_guard_;
};
@@ -701,24 +709,26 @@ static ArchRegExpMacroAssembler::Result Execute(Code* code,
start_offset,
input_start,
input_end,
- captures);
+ captures,
+ Isolate::Current());
}
TEST(MacroAssemblerNativeSuccess) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
m.Succeed();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector(""));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector(""));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
int captures[4] = {42, 37, 87, 117};
- Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
+ Handle<String> input = factory->NewStringFromAscii(CStrVector("foofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
const byte* start_adr =
reinterpret_cast<const byte*>(seq_input->GetCharsAddress());
@@ -742,6 +752,7 @@ TEST(MacroAssemblerNativeSuccess) {
TEST(MacroAssemblerNativeSimple) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
@@ -757,12 +768,12 @@ TEST(MacroAssemblerNativeSimple) {
m.Bind(&fail);
m.Fail();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("^foo"));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("^foo"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
int captures[4] = {42, 37, 87, 117};
- Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
+ Handle<String> input = factory->NewStringFromAscii(CStrVector("foofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -780,7 +791,7 @@ TEST(MacroAssemblerNativeSimple) {
CHECK_EQ(-1, captures[2]);
CHECK_EQ(-1, captures[3]);
- input = Factory::NewStringFromAscii(CStrVector("barbarbar"));
+ input = factory->NewStringFromAscii(CStrVector("barbarbar"));
seq_input = Handle<SeqAsciiString>::cast(input);
start_adr = seq_input->GetCharsAddress();
@@ -798,6 +809,7 @@ TEST(MacroAssemblerNativeSimple) {
TEST(MacroAssemblerNativeSimpleUC16) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4);
@@ -813,14 +825,14 @@ TEST(MacroAssemblerNativeSimpleUC16) {
m.Bind(&fail);
m.Fail();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("^foo"));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("^foo"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
int captures[4] = {42, 37, 87, 117};
const uc16 input_data[6] = {'f', 'o', 'o', 'f', 'o', '\xa0'};
Handle<String> input =
- Factory::NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
+ factory->NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -839,7 +851,7 @@ TEST(MacroAssemblerNativeSimpleUC16) {
CHECK_EQ(-1, captures[3]);
const uc16 input_data2[9] = {'b', 'a', 'r', 'b', 'a', 'r', 'b', 'a', '\xa0'};
- input = Factory::NewStringFromTwoByte(Vector<const uc16>(input_data2, 9));
+ input = factory->NewStringFromTwoByte(Vector<const uc16>(input_data2, 9));
seq_input = Handle<SeqTwoByteString>::cast(input);
start_adr = seq_input->GetCharsAddress();
@@ -857,6 +869,7 @@ TEST(MacroAssemblerNativeSimpleUC16) {
TEST(MacroAssemblerNativeBacktrack) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0);
@@ -871,11 +884,11 @@ TEST(MacroAssemblerNativeBacktrack) {
m.Bind(&backtrack);
m.Fail();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector(".........."));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector(".........."));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
- Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
+ Handle<String> input = factory->NewStringFromAscii(CStrVector("foofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -894,6 +907,7 @@ TEST(MacroAssemblerNativeBacktrack) {
TEST(MacroAssemblerNativeBackReferenceASCII) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
@@ -912,11 +926,11 @@ TEST(MacroAssemblerNativeBackReferenceASCII) {
m.Bind(&missing_match);
m.Fail();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("^(..)..\1"));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("^(..)..\1"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
- Handle<String> input = Factory::NewStringFromAscii(CStrVector("fooofo"));
+ Handle<String> input = factory->NewStringFromAscii(CStrVector("fooofo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -940,6 +954,7 @@ TEST(MacroAssemblerNativeBackReferenceASCII) {
TEST(MacroAssemblerNativeBackReferenceUC16) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4);
@@ -958,13 +973,13 @@ TEST(MacroAssemblerNativeBackReferenceUC16) {
m.Bind(&missing_match);
m.Fail();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("^(..)..\1"));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("^(..)..\1"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
const uc16 input_data[6] = {'f', 0x2028, 'o', 'o', 'f', 0x2028};
Handle<String> input =
- Factory::NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
+ factory->NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -989,6 +1004,7 @@ TEST(MacroAssemblerNativeBackReferenceUC16) {
TEST(MacroAssemblernativeAtStart) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0);
@@ -1013,11 +1029,11 @@ TEST(MacroAssemblernativeAtStart) {
m.CheckNotCharacter('b', &fail);
m.Succeed();
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("(^f|ob)"));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("(^f|ob)"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
- Handle<String> input = Factory::NewStringFromAscii(CStrVector("foobar"));
+ Handle<String> input = factory->NewStringFromAscii(CStrVector("foobar"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -1045,6 +1061,7 @@ TEST(MacroAssemblernativeAtStart) {
TEST(MacroAssemblerNativeBackRefNoCase) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
@@ -1071,12 +1088,12 @@ TEST(MacroAssemblerNativeBackRefNoCase) {
m.Succeed();
Handle<String> source =
- Factory::NewStringFromAscii(CStrVector("^(abc)\1\1(?!\1)...(?!\1)"));
+ factory->NewStringFromAscii(CStrVector("^(abc)\1\1(?!\1)...(?!\1)"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
Handle<String> input =
- Factory::NewStringFromAscii(CStrVector("aBcAbCABCxYzab"));
+ factory->NewStringFromAscii(CStrVector("aBcAbCABCxYzab"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -1101,6 +1118,7 @@ TEST(MacroAssemblerNativeBackRefNoCase) {
TEST(MacroAssemblerNativeRegisters) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Factory* factory = Isolate::Current()->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 6);
@@ -1169,13 +1187,13 @@ TEST(MacroAssemblerNativeRegisters) {
m.Fail();
Handle<String> source =
- Factory::NewStringFromAscii(CStrVector("<loop test>"));
+ factory->NewStringFromAscii(CStrVector("<loop test>"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
// String long enough for test (content doesn't matter).
Handle<String> input =
- Factory::NewStringFromAscii(CStrVector("foofoofoofoofoo"));
+ factory->NewStringFromAscii(CStrVector("foofoofoofoofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -1201,6 +1219,8 @@ TEST(MacroAssemblerNativeRegisters) {
TEST(MacroAssemblerStackOverflow) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0);
@@ -1210,13 +1230,13 @@ TEST(MacroAssemblerStackOverflow) {
m.GoTo(&loop);
Handle<String> source =
- Factory::NewStringFromAscii(CStrVector("<stack overflow test>"));
+ factory->NewStringFromAscii(CStrVector("<stack overflow test>"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
// String long enough for test (content doesn't matter).
Handle<String> input =
- Factory::NewStringFromAscii(CStrVector("dummy"));
+ factory->NewStringFromAscii(CStrVector("dummy"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -1229,14 +1249,16 @@ TEST(MacroAssemblerStackOverflow) {
NULL);
CHECK_EQ(NativeRegExpMacroAssembler::EXCEPTION, result);
- CHECK(Top::has_pending_exception());
- Top::clear_pending_exception();
+ CHECK(isolate->has_pending_exception());
+ isolate->clear_pending_exception();
}
TEST(MacroAssemblerNativeLotsOfRegisters) {
v8::V8::Initialize();
ContextInitializer initializer;
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 2);
@@ -1254,13 +1276,13 @@ TEST(MacroAssemblerNativeLotsOfRegisters) {
m.Succeed();
Handle<String> source =
- Factory::NewStringFromAscii(CStrVector("<huge register space test>"));
+ factory->NewStringFromAscii(CStrVector("<huge register space test>"));
Handle<Object> code_object = m.GetCode(source);
Handle<Code> code = Handle<Code>::cast(code_object);
// String long enough for test (content doesn't matter).
Handle<String> input =
- Factory::NewStringFromAscii(CStrVector("sample text"));
+ factory->NewStringFromAscii(CStrVector("sample text"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
@@ -1277,7 +1299,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) {
CHECK_EQ(0, captures[0]);
CHECK_EQ(42, captures[1]);
- Top::clear_pending_exception();
+ isolate->clear_pending_exception();
}
#else // V8_INTERPRETED_REGEXP
@@ -1320,17 +1342,19 @@ TEST(MacroAssembler) {
m.PopRegister(0);
m.Fail();
- v8::HandleScope scope;
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope scope(isolate);
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("^f(o)o"));
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("^f(o)o"));
Handle<ByteArray> array = Handle<ByteArray>::cast(m.GetCode(source));
int captures[5];
const uc16 str1[] = {'f', 'o', 'o', 'b', 'a', 'r'};
Handle<String> f1_16 =
- Factory::NewStringFromTwoByte(Vector<const uc16>(str1, 6));
+ factory->NewStringFromTwoByte(Vector<const uc16>(str1, 6));
- CHECK(IrregexpInterpreter::Match(array, f1_16, captures, 0));
+ CHECK(IrregexpInterpreter::Match(isolate, array, f1_16, captures, 0));
CHECK_EQ(0, captures[0]);
CHECK_EQ(3, captures[1]);
CHECK_EQ(1, captures[2]);
@@ -1339,9 +1363,9 @@ TEST(MacroAssembler) {
const uc16 str2[] = {'b', 'a', 'r', 'f', 'o', 'o'};
Handle<String> f2_16 =
- Factory::NewStringFromTwoByte(Vector<const uc16>(str2, 6));
+ factory->NewStringFromTwoByte(Vector<const uc16>(str2, 6));
- CHECK(!IrregexpInterpreter::Match(array, f2_16, captures, 0));
+ CHECK(!IrregexpInterpreter::Match(isolate, array, f2_16, captures, 0));
CHECK_EQ(42, captures[0]);
}
@@ -1349,10 +1373,11 @@ TEST(MacroAssembler) {
TEST(AddInverseToTable) {
+ v8::internal::V8::Initialize(NULL);
static const int kLimit = 1000;
static const int kRangeCount = 16;
for (int t = 0; t < 10; t++) {
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneList<CharacterRange>* ranges =
new ZoneList<CharacterRange>(kRangeCount);
for (int i = 0; i < kRangeCount; i++) {
@@ -1373,7 +1398,7 @@ TEST(AddInverseToTable) {
CHECK_EQ(is_on, set->Get(0) == false);
}
}
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneList<CharacterRange>* ranges =
new ZoneList<CharacterRange>(1);
ranges->Add(CharacterRange(0xFFF0, 0xFFFE));
@@ -1486,7 +1511,7 @@ TEST(UncanonicalizeEquivalence) {
static void TestRangeCaseIndependence(CharacterRange input,
Vector<CharacterRange> expected) {
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
int count = expected.length();
ZoneList<CharacterRange>* list = new ZoneList<CharacterRange>(count);
input.AddCaseEquivalents(list, false);
@@ -1507,6 +1532,7 @@ static void TestSimpleRangeCaseIndependence(CharacterRange input,
TEST(CharacterRangeCaseIndependence) {
+ v8::internal::V8::Initialize(NULL);
TestSimpleRangeCaseIndependence(CharacterRange::Singleton('a'),
CharacterRange::Singleton('A'));
TestSimpleRangeCaseIndependence(CharacterRange::Singleton('z'),
@@ -1548,7 +1574,8 @@ static bool InClass(uc16 c, ZoneList<CharacterRange>* ranges) {
TEST(CharClassDifference) {
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ v8::internal::V8::Initialize(NULL);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneList<CharacterRange>* base = new ZoneList<CharacterRange>(1);
base->Add(CharacterRange::Everything());
Vector<const uc16> overlay = CharacterRange::GetWordBounds();
@@ -1574,7 +1601,8 @@ TEST(CharClassDifference) {
TEST(CanonicalizeCharacterSets) {
- ZoneScope scope(DELETE_ON_EXIT);
+ v8::internal::V8::Initialize(NULL);
+ ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneList<CharacterRange>* list = new ZoneList<CharacterRange>(4);
CharacterSet set(list);
@@ -1644,7 +1672,8 @@ static bool CharacterInSet(ZoneList<CharacterRange>* set, uc16 value) {
}
TEST(CharacterRangeMerge) {
- ZoneScope zone_scope(DELETE_ON_EXIT);
+ v8::internal::V8::Initialize(NULL);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
ZoneList<CharacterRange> l1(4);
ZoneList<CharacterRange> l2(4);
// Create all combinations of intersections of ranges, both singletons and
diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc
index 2b9beac12..0378fb341 100644
--- a/deps/v8/test/cctest/test-reloc-info.cc
+++ b/deps/v8/test/cctest/test-reloc-info.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// 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:
@@ -42,24 +42,31 @@ static void WriteRinfo(RelocInfoWriter* writer,
// Tests that writing both types of positions and then reading either
// or both works as expected.
TEST(Positions) {
- const int instr_size = 10 << 10;
- const int reloc_size = 10 << 10;
- const int buf_size = instr_size + reloc_size;
- SmartPointer<byte> buf(new byte[buf_size]);
- byte* pc = *buf;
- CodeDesc desc = { *buf, buf_size, instr_size, reloc_size, NULL };
+ const int code_size = 10 * KB;
+ int relocation_info_size = 10 * KB;
+ const int buffer_size = code_size + relocation_info_size;
+ SmartPointer<byte> buffer(new byte[buffer_size]);
- RelocInfoWriter writer(*buf + buf_size, pc);
+ byte* pc = *buffer;
+ byte* buffer_end = *buffer + buffer_size;
+
+ RelocInfoWriter writer(buffer_end, pc);
+ byte* relocation_info_end = buffer_end - relocation_info_size;
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
RelocInfo::Mode mode = (i % 2 == 0) ?
RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
WriteRinfo(&writer, pc, mode, pos);
+ CHECK(writer.pos() - RelocInfoWriter::kMaxSize >= relocation_info_end);
}
+ relocation_info_size = static_cast<int>(buffer_end - writer.pos());
+ CodeDesc desc = { *buffer, buffer_size, code_size,
+ relocation_info_size, NULL };
+
// Read only (non-statement) positions.
{
RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION));
- pc = *buf;
+ pc = *buffer;
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
RelocInfo::Mode mode = (i % 2 == 0) ?
RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
@@ -76,7 +83,7 @@ TEST(Positions) {
// Read only statement positions.
{
RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
- pc = *buf;
+ pc = *buffer;
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
RelocInfo::Mode mode = (i % 2 == 0) ?
RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
@@ -93,7 +100,7 @@ TEST(Positions) {
// Read both types of positions.
{
RelocIterator it(desc, RelocInfo::kPositionMask);
- pc = *buf;
+ pc = *buffer;
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
RelocInfo::Mode mode = (i % 2 == 0) ?
RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 80910c256..730d72a95 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -83,7 +83,7 @@ static int* counter_function(const char* name) {
template <class T>
static Address AddressOf(T id) {
- return ExternalReference(id).address();
+ return ExternalReference(id, i::Isolate::Current()).address();
}
@@ -99,70 +99,75 @@ static int make_code(TypeCode type, int id) {
TEST(ExternalReferenceEncoder) {
- StatsTable::SetCounterFunction(counter_function);
- Heap::Setup(false);
+ OS::Setup();
+ Isolate* isolate = i::Isolate::Current();
+ isolate->stats_table()->SetCounterFunction(counter_function);
+ HEAP->Setup(false);
ExternalReferenceEncoder encoder;
- CHECK_EQ(make_code(BUILTIN, Builtins::ArrayCode),
- Encode(encoder, Builtins::ArrayCode));
+ CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode),
+ Encode(encoder, Builtins::kArrayCode));
CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
Encode(encoder, Runtime::kAbort));
CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty),
Encode(encoder, IC_Utility(IC::kLoadCallbackProperty)));
ExternalReference keyed_load_function_prototype =
- ExternalReference(&Counters::keyed_load_function_prototype);
+ ExternalReference(isolate->counters()->keyed_load_function_prototype());
CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
encoder.Encode(keyed_load_function_prototype.address()));
ExternalReference the_hole_value_location =
- ExternalReference::the_hole_value_location();
+ ExternalReference::the_hole_value_location(isolate);
CHECK_EQ(make_code(UNCLASSIFIED, 2),
encoder.Encode(the_hole_value_location.address()));
ExternalReference stack_limit_address =
- ExternalReference::address_of_stack_limit();
+ ExternalReference::address_of_stack_limit(isolate);
CHECK_EQ(make_code(UNCLASSIFIED, 4),
encoder.Encode(stack_limit_address.address()));
ExternalReference real_stack_limit_address =
- ExternalReference::address_of_real_stack_limit();
+ ExternalReference::address_of_real_stack_limit(isolate);
CHECK_EQ(make_code(UNCLASSIFIED, 5),
encoder.Encode(real_stack_limit_address.address()));
#ifdef ENABLE_DEBUGGER_SUPPORT
CHECK_EQ(make_code(UNCLASSIFIED, 15),
- encoder.Encode(ExternalReference::debug_break().address()));
+ encoder.Encode(ExternalReference::debug_break(isolate).address()));
#endif // ENABLE_DEBUGGER_SUPPORT
CHECK_EQ(make_code(UNCLASSIFIED, 10),
- encoder.Encode(ExternalReference::new_space_start().address()));
+ encoder.Encode(
+ ExternalReference::new_space_start(isolate).address()));
CHECK_EQ(make_code(UNCLASSIFIED, 3),
- encoder.Encode(ExternalReference::roots_address().address()));
+ encoder.Encode(ExternalReference::roots_address(isolate).address()));
}
TEST(ExternalReferenceDecoder) {
- StatsTable::SetCounterFunction(counter_function);
- Heap::Setup(false);
+ OS::Setup();
+ Isolate* isolate = i::Isolate::Current();
+ isolate->stats_table()->SetCounterFunction(counter_function);
+ HEAP->Setup(false);
ExternalReferenceDecoder decoder;
- CHECK_EQ(AddressOf(Builtins::ArrayCode),
- decoder.Decode(make_code(BUILTIN, Builtins::ArrayCode)));
+ CHECK_EQ(AddressOf(Builtins::kArrayCode),
+ decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
CHECK_EQ(AddressOf(Runtime::kAbort),
decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
Runtime::kAbort)));
CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
ExternalReference keyed_load_function =
- ExternalReference(&Counters::keyed_load_function_prototype);
+ ExternalReference(isolate->counters()->keyed_load_function_prototype());
CHECK_EQ(keyed_load_function.address(),
decoder.Decode(
make_code(STATS_COUNTER,
Counters::k_keyed_load_function_prototype)));
- CHECK_EQ(ExternalReference::the_hole_value_location().address(),
+ CHECK_EQ(ExternalReference::the_hole_value_location(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 2)));
- CHECK_EQ(ExternalReference::address_of_stack_limit().address(),
+ CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 4)));
- CHECK_EQ(ExternalReference::address_of_real_stack_limit().address(),
+ CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 5)));
#ifdef ENABLE_DEBUGGER_SUPPORT
- CHECK_EQ(ExternalReference::debug_break().address(),
+ CHECK_EQ(ExternalReference::debug_break(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 15)));
#endif // ENABLE_DEBUGGER_SUPPORT
- CHECK_EQ(ExternalReference::new_space_start().address(),
+ CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 10)));
}
@@ -276,12 +281,12 @@ static void Deserialize() {
static void SanityCheck() {
v8::HandleScope scope;
#ifdef DEBUG
- Heap::Verify();
+ HEAP->Verify();
#endif
- CHECK(Top::global()->IsJSObject());
- CHECK(Top::global_context()->IsContext());
- CHECK(Heap::symbol_table()->IsSymbolTable());
- CHECK(!Factory::LookupAsciiSymbol("Empty")->IsFailure());
+ CHECK(Isolate::Current()->global()->IsJSObject());
+ CHECK(Isolate::Current()->global_context()->IsContext());
+ CHECK(HEAP->symbol_table()->IsSymbolTable());
+ CHECK(!FACTORY->LookupAsciiSymbol("Empty")->IsFailure());
}
@@ -291,7 +296,6 @@ DEPENDENT_TEST(Deserialize, Serialize) {
// serialize a snapshot in a VM that is booted from a snapshot.
if (!Snapshot::IsEnabled()) {
v8::HandleScope scope;
-
Deserialize();
v8::Persistent<v8::Context> env = v8::Context::New();
@@ -305,7 +309,6 @@ DEPENDENT_TEST(Deserialize, Serialize) {
DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
if (!Snapshot::IsEnabled()) {
v8::HandleScope scope;
-
Deserialize();
v8::Persistent<v8::Context> env = v8::Context::New();
@@ -319,7 +322,6 @@ DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
if (!Snapshot::IsEnabled()) {
v8::HandleScope scope;
-
Deserialize();
v8::Persistent<v8::Context> env = v8::Context::New();
@@ -337,7 +339,6 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
SerializeTwice) {
if (!Snapshot::IsEnabled()) {
v8::HandleScope scope;
-
Deserialize();
v8::Persistent<v8::Context> env = v8::Context::New();
@@ -361,11 +362,11 @@ TEST(PartialSerialization) {
// Make sure all builtin scripts are cached.
{ HandleScope scope;
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
- Bootstrapper::NativesSourceLookup(i);
+ Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
}
}
- Heap::CollectAllGarbage(true);
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
Object* raw_foo;
{
@@ -425,7 +426,7 @@ static void ReserveSpaceForPartialSnapshot(const char* file_name) {
#undef fscanf
#endif
fclose(fp);
- Heap::ReserveSpace(new_size,
+ HEAP->ReserveSpace(new_size,
pointer_size,
data_size,
code_size,
@@ -482,12 +483,12 @@ TEST(ContextSerialization) {
// Make sure all builtin scripts are cached.
{ HandleScope scope;
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
- Bootstrapper::NativesSourceLookup(i);
+ Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
}
}
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of env.
- Heap::CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(true);
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
@@ -561,7 +562,7 @@ TEST(LinearAllocation) {
for (int size = 1000; size < 5 * MB; size += size >> 1) {
int new_space_size = (size < new_space_max) ? size : new_space_max;
- Heap::ReserveSpace(
+ HEAP->ReserveSpace(
new_space_size,
size, // Old pointer space.
size, // Old data space.
@@ -584,7 +585,7 @@ TEST(LinearAllocation) {
i + kSmallFixedArraySize <= new_space_size;
i += kSmallFixedArraySize) {
Object* obj =
- Heap::AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked();
+ HEAP->AllocateFixedArray(kSmallFixedArrayLength)->ToObjectChecked();
if (new_last != NULL) {
CHECK(reinterpret_cast<char*>(obj) ==
reinterpret_cast<char*>(new_last) + kSmallFixedArraySize);
@@ -596,7 +597,7 @@ TEST(LinearAllocation) {
for (int i = 0;
i + kSmallFixedArraySize <= size;
i += kSmallFixedArraySize) {
- Object* obj = Heap::AllocateFixedArray(kSmallFixedArrayLength,
+ Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength,
TENURED)->ToObjectChecked();
int old_page_fullness = i % Page::kPageSize;
int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize;
@@ -614,7 +615,7 @@ TEST(LinearAllocation) {
Object* data_last = NULL;
for (int i = 0; i + kSmallStringSize <= size; i += kSmallStringSize) {
- Object* obj = Heap::AllocateRawAsciiString(kSmallStringLength,
+ Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength,
TENURED)->ToObjectChecked();
int old_page_fullness = i % Page::kPageSize;
int page_fullness = (i + kSmallStringSize) % Page::kPageSize;
@@ -632,7 +633,7 @@ TEST(LinearAllocation) {
Object* map_last = NULL;
for (int i = 0; i + kMapSize <= size; i += kMapSize) {
- Object* obj = Heap::AllocateMap(JS_OBJECT_TYPE,
+ Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE,
42 * kPointerSize)->ToObjectChecked();
int old_page_fullness = i % Page::kPageSize;
int page_fullness = (i + kMapSize) % Page::kPageSize;
@@ -654,7 +655,7 @@ TEST(LinearAllocation) {
AlwaysAllocateScope always;
int large_object_array_length =
(size - FixedArray::kHeaderSize) / kPointerSize;
- Object* obj = Heap::AllocateFixedArray(large_object_array_length,
+ Object* obj = HEAP->AllocateFixedArray(large_object_array_length,
TENURED)->ToObjectChecked();
CHECK(!obj->IsFailure());
}
diff --git a/deps/v8/test/cctest/test-sockets.cc b/deps/v8/test/cctest/test-sockets.cc
index 822a23fa9..4af55dbe9 100644
--- a/deps/v8/test/cctest/test-sockets.cc
+++ b/deps/v8/test/cctest/test-sockets.cc
@@ -10,8 +10,12 @@ using namespace ::v8::internal;
class SocketListenerThread : public Thread {
public:
- explicit SocketListenerThread(int port, int data_size)
- : port_(port), data_size_(data_size), server_(NULL), client_(NULL),
+ SocketListenerThread(int port, int data_size)
+ : Thread("SocketListenerThread"),
+ port_(port),
+ data_size_(data_size),
+ server_(NULL),
+ client_(NULL),
listening_(OS::CreateSemaphore(0)) {
data_ = new char[data_size_];
}
diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc
index 706c6bf9a..de0c41e2b 100644
--- a/deps/v8/test/cctest/test-spaces.cc
+++ b/deps/v8/test/cctest/test-spaces.cc
@@ -65,6 +65,8 @@ TEST(Page) {
Address page_start = RoundUp(start, Page::kPageSize);
Page* p = Page::FromAddress(page_start);
+ // Initialized Page has heap pointer, normally set by memory_allocator.
+ p->heap_ = HEAP;
CHECK(p->address() == page_start);
CHECK(p->is_valid());
@@ -90,37 +92,45 @@ TEST(Page) {
TEST(MemoryAllocator) {
- CHECK(Heap::ConfigureHeapDefault());
- CHECK(MemoryAllocator::Setup(Heap::MaxReserved(), Heap::MaxExecutableSize()));
-
- OldSpace faked_space(Heap::MaxReserved(), OLD_POINTER_SPACE, NOT_EXECUTABLE);
+ OS::Setup();
+ Isolate* isolate = Isolate::Current();
+ CHECK(HEAP->ConfigureHeapDefault());
+ CHECK(isolate->memory_allocator()->Setup(HEAP->MaxReserved(),
+ HEAP->MaxExecutableSize()));
+
+ OldSpace faked_space(HEAP,
+ HEAP->MaxReserved(),
+ OLD_POINTER_SPACE,
+ NOT_EXECUTABLE);
int total_pages = 0;
int requested = MemoryAllocator::kPagesPerChunk;
int allocated;
// If we request n pages, we should get n or n - 1.
Page* first_page =
- MemoryAllocator::AllocatePages(requested, &allocated, &faked_space);
+ isolate->memory_allocator()->AllocatePages(
+ requested, &allocated, &faked_space);
CHECK(first_page->is_valid());
CHECK(allocated == requested || allocated == requested - 1);
total_pages += allocated;
Page* last_page = first_page;
for (Page* p = first_page; p->is_valid(); p = p->next_page()) {
- CHECK(MemoryAllocator::IsPageInSpace(p, &faked_space));
+ CHECK(isolate->memory_allocator()->IsPageInSpace(p, &faked_space));
last_page = p;
}
// Again, we should get n or n - 1 pages.
Page* others =
- MemoryAllocator::AllocatePages(requested, &allocated, &faked_space);
+ isolate->memory_allocator()->AllocatePages(
+ requested, &allocated, &faked_space);
CHECK(others->is_valid());
CHECK(allocated == requested || allocated == requested - 1);
total_pages += allocated;
- MemoryAllocator::SetNextPage(last_page, others);
+ isolate->memory_allocator()->SetNextPage(last_page, others);
int page_count = 0;
for (Page* p = first_page; p->is_valid(); p = p->next_page()) {
- CHECK(MemoryAllocator::IsPageInSpace(p, &faked_space));
+ CHECK(isolate->memory_allocator()->IsPageInSpace(p, &faked_space));
page_count++;
}
CHECK(total_pages == page_count);
@@ -131,31 +141,34 @@ TEST(MemoryAllocator) {
// Freeing pages at the first chunk starting at or after the second page
// should free the entire second chunk. It will return the page it was passed
// (since the second page was in the first chunk).
- Page* free_return = MemoryAllocator::FreePages(second_page);
+ Page* free_return = isolate->memory_allocator()->FreePages(second_page);
CHECK(free_return == second_page);
- MemoryAllocator::SetNextPage(first_page, free_return);
+ isolate->memory_allocator()->SetNextPage(first_page, free_return);
// Freeing pages in the first chunk starting at the first page should free
// the first chunk and return an invalid page.
- Page* invalid_page = MemoryAllocator::FreePages(first_page);
+ Page* invalid_page = isolate->memory_allocator()->FreePages(first_page);
CHECK(!invalid_page->is_valid());
- MemoryAllocator::TearDown();
+ isolate->memory_allocator()->TearDown();
}
TEST(NewSpace) {
- CHECK(Heap::ConfigureHeapDefault());
- CHECK(MemoryAllocator::Setup(Heap::MaxReserved(), Heap::MaxExecutableSize()));
+ OS::Setup();
+ CHECK(HEAP->ConfigureHeapDefault());
+ CHECK(Isolate::Current()->memory_allocator()->Setup(
+ HEAP->MaxReserved(), HEAP->MaxExecutableSize()));
- NewSpace new_space;
+ NewSpace new_space(HEAP);
void* chunk =
- MemoryAllocator::ReserveInitialChunk(4 * Heap::ReservedSemiSpaceSize());
+ Isolate::Current()->memory_allocator()->ReserveInitialChunk(
+ 4 * HEAP->ReservedSemiSpaceSize());
CHECK(chunk != NULL);
Address start = RoundUp(static_cast<Address>(chunk),
- 2 * Heap::ReservedSemiSpaceSize());
- CHECK(new_space.Setup(start, 2 * Heap::ReservedSemiSpaceSize()));
+ 2 * HEAP->ReservedSemiSpaceSize());
+ CHECK(new_space.Setup(start, 2 * HEAP->ReservedSemiSpaceSize()));
CHECK(new_space.HasBeenSetup());
while (new_space.Available() >= Page::kMaxHeapObjectSize) {
@@ -165,24 +178,28 @@ TEST(NewSpace) {
}
new_space.TearDown();
- MemoryAllocator::TearDown();
+ Isolate::Current()->memory_allocator()->TearDown();
}
TEST(OldSpace) {
- CHECK(Heap::ConfigureHeapDefault());
- CHECK(MemoryAllocator::Setup(Heap::MaxReserved(), Heap::MaxExecutableSize()));
+ OS::Setup();
+ CHECK(HEAP->ConfigureHeapDefault());
+ CHECK(Isolate::Current()->memory_allocator()->Setup(
+ HEAP->MaxReserved(), HEAP->MaxExecutableSize()));
- OldSpace* s = new OldSpace(Heap::MaxOldGenerationSize(),
+ OldSpace* s = new OldSpace(HEAP,
+ HEAP->MaxOldGenerationSize(),
OLD_POINTER_SPACE,
NOT_EXECUTABLE);
CHECK(s != NULL);
void* chunk =
- MemoryAllocator::ReserveInitialChunk(4 * Heap::ReservedSemiSpaceSize());
+ Isolate::Current()->memory_allocator()->ReserveInitialChunk(
+ 4 * HEAP->ReservedSemiSpaceSize());
CHECK(chunk != NULL);
Address start = static_cast<Address>(chunk);
- size_t size = RoundUp(start, 2 * Heap::ReservedSemiSpaceSize()) - start;
+ size_t size = RoundUp(start, 2 * HEAP->ReservedSemiSpaceSize()) - start;
CHECK(s->Setup(start, size));
@@ -192,14 +209,15 @@ TEST(OldSpace) {
s->TearDown();
delete s;
- MemoryAllocator::TearDown();
+ Isolate::Current()->memory_allocator()->TearDown();
}
TEST(LargeObjectSpace) {
- CHECK(Heap::Setup(false));
+ OS::Setup();
+ CHECK(HEAP->Setup(false));
- LargeObjectSpace* lo = Heap::lo_space();
+ LargeObjectSpace* lo = HEAP->lo_space();
CHECK(lo != NULL);
Map* faked_map = reinterpret_cast<Map*>(HeapObject::FromAddress(0));
@@ -233,5 +251,5 @@ TEST(LargeObjectSpace) {
lo->TearDown();
delete lo;
- MemoryAllocator::TearDown();
+ Isolate::Current()->memory_allocator()->TearDown();
}
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 3f02b32b8..4d9b264e9 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -94,7 +94,7 @@ static void InitializeBuildingBlocks(
buf[j] = gen() % 65536;
}
building_blocks[i] =
- Factory::NewStringFromTwoByte(Vector<const uc16>(buf, len));
+ FACTORY->NewStringFromTwoByte(Vector<const uc16>(buf, len));
for (int j = 0; j < len; j++) {
CHECK_EQ(buf[j], building_blocks[i]->Get(j));
}
@@ -106,19 +106,19 @@ static void InitializeBuildingBlocks(
buf[j] = gen() % 128;
}
building_blocks[i] =
- Factory::NewStringFromAscii(Vector<const char>(buf, len));
+ FACTORY->NewStringFromAscii(Vector<const char>(buf, len));
for (int j = 0; j < len; j++) {
CHECK_EQ(buf[j], building_blocks[i]->Get(j));
}
break;
}
case 2: {
- uc16* buf = Zone::NewArray<uc16>(len);
+ uc16* buf = ZONE->NewArray<uc16>(len);
for (int j = 0; j < len; j++) {
buf[j] = gen() % 65536;
}
Resource* resource = new Resource(Vector<const uc16>(buf, len));
- building_blocks[i] = Factory::NewExternalStringFromTwoByte(resource);
+ building_blocks[i] = FACTORY->NewExternalStringFromTwoByte(resource);
for (int j = 0; j < len; j++) {
CHECK_EQ(buf[j], building_blocks[i]->Get(j));
}
@@ -130,7 +130,7 @@ static void InitializeBuildingBlocks(
buf[j] = gen() % 128;
}
building_blocks[i] =
- Factory::NewStringFromAscii(Vector<const char>(buf, len));
+ FACTORY->NewStringFromAscii(Vector<const char>(buf, len));
for (int j = 0; j < len; j++) {
CHECK_EQ(buf[j], building_blocks[i]->Get(j));
}
@@ -145,9 +145,9 @@ static void InitializeBuildingBlocks(
static Handle<String> ConstructLeft(
Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS],
int depth) {
- Handle<String> answer = Factory::NewStringFromAscii(CStrVector(""));
+ Handle<String> answer = FACTORY->NewStringFromAscii(CStrVector(""));
for (int i = 0; i < depth; i++) {
- answer = Factory::NewConsString(
+ answer = FACTORY->NewConsString(
answer,
building_blocks[i % NUMBER_OF_BUILDING_BLOCKS]);
}
@@ -158,9 +158,9 @@ static Handle<String> ConstructLeft(
static Handle<String> ConstructRight(
Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS],
int depth) {
- Handle<String> answer = Factory::NewStringFromAscii(CStrVector(""));
+ Handle<String> answer = FACTORY->NewStringFromAscii(CStrVector(""));
for (int i = depth - 1; i >= 0; i--) {
- answer = Factory::NewConsString(
+ answer = FACTORY->NewConsString(
building_blocks[i % NUMBER_OF_BUILDING_BLOCKS],
answer);
}
@@ -177,7 +177,7 @@ static Handle<String> ConstructBalancedHelper(
return building_blocks[from % NUMBER_OF_BUILDING_BLOCKS];
}
if (to - from == 2) {
- return Factory::NewConsString(
+ return FACTORY->NewConsString(
building_blocks[from % NUMBER_OF_BUILDING_BLOCKS],
building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS]);
}
@@ -185,7 +185,7 @@ static Handle<String> ConstructBalancedHelper(
ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2));
Handle<String> part2 =
ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to);
- return Factory::NewConsString(part1, part2);
+ return FACTORY->NewConsString(part1, part2);
}
@@ -233,7 +233,7 @@ TEST(Traverse) {
InitializeVM();
v8::HandleScope scope;
Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS];
- ZoneScope zone(DELETE_ON_EXIT);
+ ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
InitializeBuildingBlocks(building_blocks);
Handle<String> flat = ConstructBalanced(building_blocks);
FlattenString(flat);
@@ -286,12 +286,12 @@ TEST(DeepAscii) {
foo[i] = "foo "[i % 4];
}
Handle<String> string =
- Factory::NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH));
- Handle<String> foo_string = Factory::NewStringFromAscii(CStrVector("foo"));
+ FACTORY->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH));
+ Handle<String> foo_string = FACTORY->NewStringFromAscii(CStrVector("foo"));
for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) {
- string = Factory::NewConsString(string, foo_string);
+ string = FACTORY->NewConsString(string, foo_string);
}
- Handle<String> flat_string = Factory::NewConsString(string, foo_string);
+ Handle<String> flat_string = FACTORY->NewConsString(string, foo_string);
FlattenString(flat_string);
for (int i = 0; i < 500; i++) {
@@ -348,7 +348,7 @@ TEST(Utf8Conversion) {
TEST(ExternalShortStringAdd) {
- ZoneScope zone(DELETE_ON_EXIT);
+ ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
InitializeVM();
v8::HandleScope handle_scope;
@@ -365,7 +365,7 @@ TEST(ExternalShortStringAdd) {
// Generate short ascii and non-ascii external strings.
for (int i = 0; i <= kMaxLength; i++) {
- char* ascii = Zone::NewArray<char>(i + 1);
+ char* ascii = ZONE->NewArray<char>(i + 1);
for (int j = 0; j < i; j++) {
ascii[j] = 'a';
}
@@ -377,7 +377,7 @@ TEST(ExternalShortStringAdd) {
v8::String::NewExternal(ascii_resource);
ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string);
- uc16* non_ascii = Zone::NewArray<uc16>(i + 1);
+ uc16* non_ascii = ZONE->NewArray<uc16>(i + 1);
for (int j = 0; j < i; j++) {
non_ascii[j] = 0x1234;
}
@@ -439,7 +439,7 @@ TEST(CachedHashOverflow) {
// 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
- ZoneScope zone(DELETE_ON_EXIT);
+ ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
InitializeVM();
v8::HandleScope handle_scope;
@@ -459,10 +459,10 @@ TEST(CachedHashOverflow) {
Handle<Smi> fortytwo(Smi::FromInt(42));
Handle<Smi> thirtyseven(Smi::FromInt(37));
Handle<Object> results[] = {
- Factory::undefined_value(),
+ FACTORY->undefined_value(),
fortytwo,
- Factory::undefined_value(),
- Factory::undefined_value(),
+ FACTORY->undefined_value(),
+ FACTORY->undefined_value(),
thirtyseven,
fortytwo,
thirtyseven // Bug yielded 42 here.
diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc
index aed7466a0..1aa57e308 100644
--- a/deps/v8/test/cctest/test-thread-termination.cc
+++ b/deps/v8/test/cctest/test-thread-termination.cc
@@ -159,11 +159,18 @@ TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
class TerminatorThread : public v8::internal::Thread {
+ public:
+ explicit TerminatorThread(i::Isolate* isolate)
+ : Thread("TerminatorThread"),
+ isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { }
void Run() {
semaphore->Wait();
- CHECK(!v8::V8::IsExecutionTerminating());
- v8::V8::TerminateExecution();
+ CHECK(!v8::V8::IsExecutionTerminating(isolate_));
+ v8::V8::TerminateExecution(isolate_);
}
+
+ private:
+ v8::Isolate* isolate_;
};
@@ -171,7 +178,7 @@ class TerminatorThread : public v8::internal::Thread {
// from the side by another thread.
TEST(TerminateOnlyV8ThreadFromOtherThread) {
semaphore = v8::internal::OS::CreateSemaphore(0);
- TerminatorThread thread;
+ TerminatorThread thread(i::Isolate::Current());
thread.Start();
v8::HandleScope scope;
@@ -193,6 +200,7 @@ TEST(TerminateOnlyV8ThreadFromOtherThread) {
class LoopingThread : public v8::internal::Thread {
public:
+ LoopingThread() : Thread("LoopingThread") { }
void Run() {
v8::Locker locker;
v8::HandleScope scope;
@@ -216,29 +224,37 @@ class LoopingThread : public v8::internal::Thread {
};
-// Test that multiple threads using V8 can be terminated from another
-// thread when using Lockers and preemption.
-TEST(TerminateMultipleV8Threads) {
+// Test that multiple threads using default isolate can be terminated
+// from another thread when using Lockers and preemption.
+TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
{
v8::Locker locker;
v8::V8::Initialize();
v8::Locker::StartPreemption(1);
semaphore = v8::internal::OS::CreateSemaphore(0);
}
- LoopingThread thread1;
- thread1.Start();
- LoopingThread thread2;
- thread2.Start();
- // Wait until both threads have signaled the semaphore.
- semaphore->Wait();
- semaphore->Wait();
+ const int kThreads = 2;
+ i::List<LoopingThread*> threads(kThreads);
+ for (int i = 0; i < kThreads; i++) {
+ threads.Add(new LoopingThread());
+ }
+ for (int i = 0; i < kThreads; i++) {
+ threads[i]->Start();
+ }
+ // Wait until all threads have signaled the semaphore.
+ for (int i = 0; i < kThreads; i++) {
+ semaphore->Wait();
+ }
{
v8::Locker locker;
- v8::V8::TerminateExecution(thread1.GetV8ThreadId());
- v8::V8::TerminateExecution(thread2.GetV8ThreadId());
+ for (int i = 0; i < kThreads; i++) {
+ v8::V8::TerminateExecution(threads[i]->GetV8ThreadId());
+ }
+ }
+ for (int i = 0; i < kThreads; i++) {
+ threads[i]->Join();
+ delete threads[i];
}
- thread1.Join();
- thread2.Join();
delete semaphore;
semaphore = NULL;
diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc
index 0f48e248f..59d27ab7c 100644
--- a/deps/v8/test/cctest/test-threads.cc
+++ b/deps/v8/test/cctest/test-threads.cc
@@ -28,6 +28,7 @@
#include "v8.h"
#include "platform.h"
+#include "isolate.h"
#include "cctest.h"
@@ -64,6 +65,7 @@ static Turn turn = FILL_CACHE;
class ThreadA: public v8::internal::Thread {
public:
+ ThreadA() : Thread("ThreadA") { }
void Run() {
v8::Locker locker;
v8::HandleScope scope;
@@ -99,6 +101,7 @@ class ThreadA: public v8::internal::Thread {
class ThreadB: public v8::internal::Thread {
public:
+ ThreadB() : Thread("ThreadB") { }
void Run() {
do {
{
@@ -108,7 +111,7 @@ class ThreadB: public v8::internal::Thread {
v8::Context::Scope context_scope(v8::Context::New());
// Clear the caches by forcing major GC.
- v8::internal::Heap::CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(false);
turn = SECOND_TIME_FILL_CACHE;
break;
}
@@ -134,3 +137,55 @@ TEST(JSFunctionResultCachesInTwoThreads) {
CHECK_EQ(DONE, turn);
}
+
+class ThreadIdValidationThread : public v8::internal::Thread {
+ public:
+ ThreadIdValidationThread(i::Thread* thread_to_start,
+ i::List<i::ThreadId>* refs,
+ unsigned int thread_no,
+ i::Semaphore* semaphore)
+ : Thread("ThreadRefValidationThread"),
+ refs_(refs), thread_no_(thread_no), thread_to_start_(thread_to_start),
+ semaphore_(semaphore) {
+ }
+
+ void Run() {
+ i::ThreadId thread_id = i::ThreadId::Current();
+ for (int i = 0; i < thread_no_; i++) {
+ CHECK(!(*refs_)[i].Equals(thread_id));
+ }
+ CHECK(thread_id.IsValid());
+ (*refs_)[thread_no_] = thread_id;
+ if (thread_to_start_ != NULL) {
+ thread_to_start_->Start();
+ }
+ semaphore_->Signal();
+ }
+ private:
+ i::List<i::ThreadId>* refs_;
+ int thread_no_;
+ i::Thread* thread_to_start_;
+ i::Semaphore* semaphore_;
+};
+
+TEST(ThreadIdValidation) {
+ const int kNThreads = 100;
+ i::List<ThreadIdValidationThread*> threads(kNThreads);
+ i::List<i::ThreadId> refs(kNThreads);
+ i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
+ ThreadIdValidationThread* prev = NULL;
+ for (int i = kNThreads - 1; i >= 0; i--) {
+ ThreadIdValidationThread* newThread =
+ new ThreadIdValidationThread(prev, &refs, i, semaphore);
+ threads.Add(newThread);
+ prev = newThread;
+ refs.Add(i::ThreadId::Invalid());
+ }
+ prev->Start();
+ for (int i = 0; i < kNThreads; i++) {
+ semaphore->Wait();
+ }
+ for (int i = 0; i < kNThreads; i++) {
+ delete threads[i];
+ }
+}
diff --git a/deps/v8/test/cctest/test-type-info.cc b/deps/v8/test/cctest/test-type-info.cc
deleted file mode 100644
index 59dd83d1f..000000000
--- a/deps/v8/test/cctest/test-type-info.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.
-
-
-#include "cctest.h"
-#include "type-info.h"
-
-namespace v8 {
-namespace internal {
-
-TEST(ThreeBitRepresentation) {
- // Numeric types and unknown should fit into the short
- // representation.
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::Unknown().ThreeBitRepresentation()).IsUnknown());
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::Number().ThreeBitRepresentation()).IsNumber());
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::Integer32().ThreeBitRepresentation()).IsInteger32());
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::Smi().ThreeBitRepresentation()).IsSmi());
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::Double().ThreeBitRepresentation()).IsDouble());
-
- // Other types should map to unknown.
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::Primitive().ThreeBitRepresentation()).IsUnknown());
- CHECK(TypeInfo::ExpandedRepresentation(
- TypeInfo::String().ThreeBitRepresentation()).IsUnknown());
-}
-
-} } // namespace v8::internal
diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc
index b48dcb8b6..e13685830 100644
--- a/deps/v8/test/cctest/test-utils.cc
+++ b/deps/v8/test/cctest/test-utils.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -29,8 +29,9 @@
#include "v8.h"
-#include "platform.h"
#include "cctest.h"
+#include "platform.h"
+#include "utils-inl.h"
using namespace v8::internal;
@@ -89,8 +90,8 @@ void TestMemCopy(Vector<byte> src,
memset(dst.start(), 0xFF, dst.length());
byte* to = dst.start() + 32 + destination_alignment;
byte* from = src.start() + source_alignment;
- int length = kMinComplexMemCopy + length_alignment;
- MemCopy(to, from, static_cast<size_t>(length));
+ int length = OS::kMinComplexMemCopy + length_alignment;
+ OS::MemCopy(to, from, static_cast<size_t>(length));
printf("[%d,%d,%d]\n",
source_alignment, destination_alignment, length_alignment);
for (int i = 0; i < length; i++) {
@@ -103,8 +104,9 @@ void TestMemCopy(Vector<byte> src,
TEST(MemCopy) {
- V8::Initialize(NULL);
- const int N = kMinComplexMemCopy + 128;
+ v8::V8::Initialize();
+ OS::Setup();
+ const int N = OS::kMinComplexMemCopy + 128;
Vector<byte> buffer1 = Vector<byte>::New(N);
Vector<byte> buffer2 = Vector<byte>::New(N);
diff --git a/deps/v8/test/cctest/testcfg.py b/deps/v8/test/cctest/testcfg.py
index b15342eda..a137275ff 100644
--- a/deps/v8/test/cctest/testcfg.py
+++ b/deps/v8/test/cctest/testcfg.py
@@ -34,11 +34,12 @@ import utils
class CcTestCase(test.TestCase):
- def __init__(self, path, executable, mode, raw_name, dependency, context):
+ def __init__(self, path, executable, mode, raw_name, dependency, context, variant_flags):
super(CcTestCase, self).__init__(context, path, mode)
self.executable = executable
self.raw_name = raw_name
self.dependency = dependency
+ self.variant_flags = variant_flags
def GetLabel(self):
return "%s %s %s" % (self.mode, self.path[-2], self.path[-1])
@@ -49,6 +50,8 @@ class CcTestCase(test.TestCase):
def BuildCommand(self, name):
serialization_file = join('obj', 'test', self.mode, 'serdes')
serialization_file += '_' + self.GetName()
+ serialization_file = join(self.context.buildspace, serialization_file)
+ serialization_file += ''.join(self.variant_flags).replace('-', '_')
serialization_option = '--testing_serialization_file=' + serialization_file
result = [ self.executable, name, serialization_option ]
result += self.context.GetVmFlags(self, self.mode)
@@ -74,10 +77,11 @@ class CcTestConfiguration(test.TestConfiguration):
def GetBuildRequirements(self):
return ['cctests']
- def ListTests(self, current_path, path, mode):
+ def ListTests(self, current_path, path, mode, variant_flags):
executable = join('obj', 'test', mode, 'cctest')
if utils.IsWindows():
executable += '.exe'
+ executable = join(self.context.buildspace, executable)
output = test.Execute([executable, '--list'], self.context)
if output.exit_code != 0:
print output.stdout
@@ -91,7 +95,7 @@ class CcTestConfiguration(test.TestConfiguration):
if dependency != '':
dependency = relative_path[0] + '/' + dependency
if self.Contains(path, full_path):
- result.append(CcTestCase(full_path, executable, mode, raw_test, dependency, self.context))
+ result.append(CcTestCase(full_path, executable, mode, raw_test, dependency, self.context, variant_flags))
result.sort()
return result