summaryrefslogtreecommitdiff
path: root/deps/v8/test
diff options
context:
space:
mode:
authorTimothy J Fontaine <tjfontaine@gmail.com>2013-10-22 15:14:25 -0700
committerTimothy J Fontaine <tjfontaine@gmail.com>2013-10-23 09:17:31 -0700
commita53c763c16eeabb0901a05dbcf38a72fa96d2f26 (patch)
tree309bf250e1521cedf0e945d7a7629db511e64498 /deps/v8/test
parent54910044b33a6405c72ad085915a55c575c027fc (diff)
downloadnode-new-a53c763c16eeabb0901a05dbcf38a72fa96d2f26.tar.gz
v8: upgrade 3.21.18.3
Diffstat (limited to 'deps/v8/test')
-rw-r--r--deps/v8/test/cctest/cctest.cc14
-rw-r--r--deps/v8/test/cctest/cctest.gyp14
-rw-r--r--deps/v8/test/cctest/cctest.h16
-rw-r--r--deps/v8/test/cctest/cctest.status14
-rw-r--r--deps/v8/test/cctest/log-eq-of-logging-and-traversal.js8
-rw-r--r--deps/v8/test/cctest/test-accessors.cc120
-rw-r--r--deps/v8/test/cctest/test-alloc.cc22
-rw-r--r--deps/v8/test/cctest/test-api.cc844
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc71
-rw-r--r--deps/v8/test/cctest/test-assembler-x64.cc7
-rw-r--r--deps/v8/test/cctest/test-circular-queue.cc157
-rw-r--r--deps/v8/test/cctest/test-code-stubs-arm.cc185
-rw-r--r--deps/v8/test/cctest/test-code-stubs-ia32.cc53
-rw-r--r--deps/v8/test/cctest/test-code-stubs-x64.cc4
-rw-r--r--deps/v8/test/cctest/test-code-stubs.cc29
-rw-r--r--deps/v8/test/cctest/test-code-stubs.h5
-rw-r--r--deps/v8/test/cctest/test-compiler.cc52
-rw-r--r--deps/v8/test/cctest/test-condition-variable.cc304
-rw-r--r--deps/v8/test/cctest/test-cpu-ia32.cc40
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc69
-rw-r--r--deps/v8/test/cctest/test-cpu-x64.cc44
-rw-r--r--deps/v8/test/cctest/test-cpu.cc (renamed from deps/v8/test/cctest/test-lock.cc)68
-rw-r--r--deps/v8/test/cctest/test-debug.cc693
-rw-r--r--deps/v8/test/cctest/test-declarative-accessors.cc12
-rw-r--r--deps/v8/test/cctest/test-decls.cc2
-rw-r--r--deps/v8/test/cctest/test-deoptimization.cc34
-rw-r--r--deps/v8/test/cctest/test-dictionary.cc57
-rw-r--r--deps/v8/test/cctest/test-disasm-ia32.cc11
-rw-r--r--deps/v8/test/cctest/test-disasm-x64.cc5
-rw-r--r--deps/v8/test/cctest/test-global-handles.cc42
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc53
-rw-r--r--deps/v8/test/cctest/test-heap.cc93
-rw-r--r--deps/v8/test/cctest/test-lockers.cc13
-rw-r--r--deps/v8/test/cctest/test-log.cc105
-rw-r--r--deps/v8/test/cctest/test-mark-compact.cc68
-rw-r--r--deps/v8/test/cctest/test-mutex.cc118
-rw-r--r--deps/v8/test/cctest/test-object-observe.cc287
-rw-r--r--deps/v8/test/cctest/test-parsing.cc15
-rw-r--r--deps/v8/test/cctest/test-platform-linux.cc54
-rw-r--r--deps/v8/test/cctest/test-platform-nullos.cc105
-rw-r--r--deps/v8/test/cctest/test-platform-win32.cc2
-rw-r--r--deps/v8/test/cctest/test-platform.cc5
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc103
-rw-r--r--deps/v8/test/cctest/test-random-number-generator.cc92
-rw-r--r--deps/v8/test/cctest/test-random.cc30
-rw-r--r--deps/v8/test/cctest/test-semaphore.cc155
-rw-r--r--deps/v8/test/cctest/test-serialize.cc55
-rw-r--r--deps/v8/test/cctest/test-socket.cc (renamed from deps/v8/test/cctest/test-sockets.cc)29
-rw-r--r--deps/v8/test/cctest/test-spaces.cc4
-rw-r--r--deps/v8/test/cctest/test-strings.cc8
-rw-r--r--deps/v8/test/cctest/test-strtod.cc7
-rw-r--r--deps/v8/test/cctest/test-thread-termination.cc76
-rw-r--r--deps/v8/test/cctest/test-threads.cc2
-rw-r--r--deps/v8/test/cctest/test-time.cc144
-rw-r--r--deps/v8/test/cctest/test-unique.cc488
-rw-r--r--deps/v8/test/cctest/test-utils.cc1
-rw-r--r--deps/v8/test/cctest/test-weakmaps.cc2
-rw-r--r--deps/v8/test/cctest/test-weaksets.cc2
-rw-r--r--deps/v8/test/mjsunit/array-push-non-smi-value.js36
-rw-r--r--deps/v8/test/mjsunit/array-store-and-grow.js47
-rw-r--r--deps/v8/test/mjsunit/assert-opt-and-deopt.js6
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis.js141
-rw-r--r--deps/v8/test/mjsunit/compiler/increment-typefeedback.js39
-rw-r--r--deps/v8/test/mjsunit/compiler/optimized-for-in.js1
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-assert.js41
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-sar.js49
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-uint32.js39
-rw-r--r--deps/v8/test/mjsunit/compiler/osr-warm.js (renamed from deps/v8/test/mjsunit/regress/regress-crbug-298392.js)33
-rw-r--r--deps/v8/test/mjsunit/compiler/parallel-proto-change.js14
-rw-r--r--deps/v8/test/mjsunit/debug-script.js6
-rw-r--r--deps/v8/test/mjsunit/debug-step-4-in-frame.js132
-rw-r--r--deps/v8/test/mjsunit/debug-stepin-positions.js113
-rw-r--r--deps/v8/test/mjsunit/external-array-no-sse2.js34
-rw-r--r--deps/v8/test/mjsunit/external-array.js34
-rw-r--r--deps/v8/test/mjsunit/fast-literal.js42
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part1.js3
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part2.js4
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part3.js3
-rw-r--r--deps/v8/test/mjsunit/fuzz-natives-part4.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/object-observe.js58
-rw-r--r--deps/v8/test/mjsunit/lithium/MulI.js70
-rw-r--r--deps/v8/test/mjsunit/manual-parallel-recompile.js16
-rw-r--r--deps/v8/test/mjsunit/mjsunit.js2
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status3
-rw-r--r--deps/v8/test/mjsunit/parallel-initial-prototype-change.js8
-rw-r--r--deps/v8/test/mjsunit/parallel-invalidate-transition-map.js8
-rw-r--r--deps/v8/test/mjsunit/parallel-optimize-disabled.js8
-rw-r--r--deps/v8/test/mjsunit/regress/post-increment-close-context.js42
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2594.js104
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2829.js53
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2855.js57
-rw-r--r--deps/v8/test/mjsunit/regress/regress-convert-function-to-double.js36
-rw-r--r--deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js4
-rw-r--r--deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js16
-rw-r--r--deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js19
-rw-r--r--deps/v8/test/mjsunit/regress/regress-merge-descriptors.js92
-rw-r--r--deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js12
-rw-r--r--deps/v8/test/mjsunit/regress/regress-store-uncacheable.js40
-rw-r--r--deps/v8/test/mjsunit/regress/regress-x87.js (renamed from deps/v8/test/mjsunit/regress/regress-crbug-282736.js)47
-rw-r--r--deps/v8/test/mjsunit/smi-mul.js67
-rw-r--r--deps/v8/test/mjsunit/track-fields.js1
102 files changed, 5006 insertions, 1701 deletions
diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc
index a2caf0f3ba..616c6a3a6b 100644
--- a/deps/v8/test/cctest/cctest.cc
+++ b/deps/v8/test/cctest/cctest.cc
@@ -100,16 +100,22 @@ v8::Isolate* CcTest::default_isolate_;
class CcTestArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
virtual void* Allocate(size_t length) { return malloc(length); }
+ virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
virtual void Free(void* data, size_t length) { free(data); }
// TODO(dslomov): Remove when v8:2823 is fixed.
virtual void Free(void* data) { UNREACHABLE(); }
};
+static void SuggestTestHarness(int tests) {
+ if (tests == 0) return;
+ printf("Running multiple tests in sequence is deprecated and may cause "
+ "bogus failure. Consider using tools/run-tests.py instead.\n");
+}
+
+
int main(int argc, char* argv[]) {
v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
- v8::internal::FLAG_harmony_array_buffer = true;
- v8::internal::FLAG_harmony_typed_arrays = true;
CcTestArrayBufferAllocator array_buffer_allocator;
v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
@@ -138,8 +144,8 @@ int main(int argc, char* argv[]) {
if (test->enabled()
&& strcmp(test->file(), file) == 0
&& strcmp(test->name(), name) == 0) {
+ SuggestTestHarness(tests_run++);
test->Run();
- tests_run++;
}
test = test->prev();
}
@@ -152,8 +158,8 @@ int main(int argc, char* argv[]) {
if (test->enabled()
&& (strcmp(test->file(), file_or_name) == 0
|| strcmp(test->name(), file_or_name) == 0)) {
+ SuggestTestHarness(tests_run++);
test->Run();
- tests_run++;
}
test = test->prev();
}
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index 9df5c7bccc..ee7ffad6d3 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -55,7 +55,9 @@
'test-bignum-dtoa.cc',
'test-circular-queue.cc',
'test-compiler.cc',
+ 'test-condition-variable.cc',
'test-conversions.cc',
+ 'test-cpu.cc',
'test-cpu-profiler.cc',
'test-dataflow.cc',
'test-date.cc',
@@ -79,28 +81,32 @@
'test-heap-profiler.cc',
'test-list.cc',
'test-liveedit.cc',
- 'test-lock.cc',
'test-lockers.cc',
'test-log.cc',
'test-mark-compact.cc',
+ 'test-mutex.cc',
'test-object-observe.cc',
'test-parsing.cc',
'test-platform.cc',
'test-platform-tls.cc',
'test-profile-generator.cc',
'test-random.cc',
+ 'test-random-number-generator.cc',
'test-regexp.cc',
'test-reloc-info.cc',
+ 'test-semaphore.cc',
'test-serialize.cc',
- 'test-sockets.cc',
+ 'test-socket.cc',
'test-spaces.cc',
'test-strings.cc',
'test-symbols.cc',
'test-strtod.cc',
'test-thread-termination.cc',
'test-threads.cc',
+ 'test-time.cc',
'test-types.cc',
'test-unbound-queue.cc',
+ 'test-unique.cc',
'test-utils.cc',
'test-version.cc',
'test-weakmaps.cc',
@@ -113,6 +119,7 @@
'test-assembler-ia32.cc',
'test-code-stubs.cc',
'test-code-stubs-ia32.cc',
+ 'test-cpu-ia32.cc',
'test-disasm-ia32.cc',
'test-log-stack-tracer.cc'
],
@@ -122,6 +129,7 @@
'test-assembler-x64.cc',
'test-code-stubs.cc',
'test-code-stubs-x64.cc',
+ 'test-cpu-x64.cc',
'test-macro-assembler-x64.cc',
'test-log-stack-tracer.cc'
],
@@ -129,6 +137,8 @@
['v8_target_arch=="arm"', {
'sources': [
'test-assembler-arm.cc',
+ 'test-code-stubs.cc',
+ 'test-code-stubs-arm.cc',
'test-disasm-arm.cc'
],
}],
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index 193126a081..ceb97743eb 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -71,6 +71,10 @@ typedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags;
EXTENSION_LIST(DEFINE_EXTENSION_FLAG)
#undef DEFINE_EXTENSION_FLAG
+// Temporary macros for accessing current isolate and its subobjects.
+// They provide better readability, especially when used a lot in the code.
+#define HEAP (v8::internal::Isolate::Current()->heap())
+
class CcTest {
public:
typedef void (TestFunction)();
@@ -91,6 +95,10 @@ class CcTest {
static v8::Isolate* isolate() { return default_isolate_; }
+ static i::Isolate* i_isolate() {
+ return reinterpret_cast<i::Isolate*>(default_isolate_);
+ }
+
// Helper function to initialize the VM.
static void InitializeVM(CcTestExtensionFlags extensions = NO_EXTENSIONS);
@@ -144,10 +152,10 @@ class ApiTestFuzzer: public v8::internal::Thread {
explicit ApiTestFuzzer(int num)
: Thread("ApiTestFuzzer"),
test_number_(num),
- gate_(v8::internal::OS::CreateSemaphore(0)),
+ gate_(0),
active_(true) {
}
- ~ApiTestFuzzer() { delete gate_; }
+ ~ApiTestFuzzer() {}
static bool fuzzing_;
static int tests_being_run_;
@@ -155,11 +163,11 @@ class ApiTestFuzzer: public v8::internal::Thread {
static int active_tests_;
static bool NextThread();
int test_number_;
- v8::internal::Semaphore* gate_;
+ v8::internal::Semaphore gate_;
bool active_;
void ContextSwitch();
static int GetNextTestNumber();
- static v8::internal::Semaphore* all_tests_done_;
+ static v8::internal::Semaphore all_tests_done_;
};
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 0d3ff150c6..85661098b2 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -34,6 +34,10 @@ test-api/Bug*: FAIL
# BUG(382): Weird test. Can't guarantee that it never times out.
test-api/ApplyInterruption: PASS || TIMEOUT
+# TODO(mstarzinger): Fail gracefully on multiple V8::Dispose calls.
+test-api/InitializeAndDisposeOnce: SKIP
+test-api/InitializeAndDisposeMultiple: SKIP
+
# 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
@@ -52,6 +56,9 @@ test-weaksets/WeakSet_Shrinking: FAIL
# Boot up memory use is bloated in debug mode.
test-mark-compact/BootUpMemoryUse: PASS, PASS || FAIL if $mode == debug
+# Some CPU profiler tests are flaky.
+test-cpu-profiler/*: PASS || FLAKY
+
##############################################################################
[ $arch == arm ]
@@ -70,6 +77,8 @@ test-serialize/DeserializeFromSecondSerializationAndRunScript2: SKIP
test-serialize/DeserializeAndRunScript2: SKIP
test-serialize/DeserializeFromSecondSerialization: SKIP
+# BUG(2874): Threading problems.
+test-api/*: PASS || FLAKY
##############################################################################
[ $arch == mipsel ]
@@ -113,7 +122,10 @@ test-log/ProfLazyMode: SKIP
# Native Client doesn't support sockets.
test-debug/DebuggerAgent: SKIP
test-debug/DebuggerAgentProtocolOverflowHeader: SKIP
-test-sockets/Socket: SKIP
+test-socket/Socket: SKIP
# Profiling doesn't work on Native Client.
test-cpu-profiler/*: SKIP
+
+# Fails since 16322 (new test).
+test-code-stubs-arm/ConvertDToI: SKIP
diff --git a/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js b/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js
index 05643bfb8a..522a3726ea 100644
--- a/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js
+++ b/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js
@@ -39,7 +39,7 @@ function parseState(s) {
function LogProcessor() {
LogReader.call(this, {
'code-creation': {
- parsers: [null, parseInt, parseInt, null, 'var-args'],
+ parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'],
processor: this.processCodeCreation },
'code-move': { parsers: [parseInt, parseInt],
processor: this.processCodeMove },
@@ -55,8 +55,12 @@ function LogProcessor() {
LogProcessor.prototype.__proto__ = LogReader.prototype;
LogProcessor.prototype.processCodeCreation = function(
- type, start, size, name, maybe_func) {
+ type, kind, start, size, name, maybe_func) {
if (type != "LazyCompile" && type != "Script" && type != "Function") return;
+ // Scripts will compile into anonymous functions starting at 1:1. Adjust the
+ // name here so that it matches corrsponding function's name during the heap
+ // traversal.
+ if (type == "Script") name = " :1:1";
// Discard types to avoid discrepancies in "LazyCompile" vs. "Function".
type = "";
if (maybe_func.length) {
diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc
index 7d96ea64c2..2aaac922bf 100644
--- a/deps/v8/test/cctest/test-accessors.cc
+++ b/deps/v8/test/cctest/test-accessors.cc
@@ -41,7 +41,6 @@ using ::v8::Local;
using ::v8::String;
using ::v8::Script;
using ::v8::Function;
-using ::v8::AccessorInfo;
using ::v8::Extension;
static void handle_property(Local<String> name,
@@ -50,18 +49,51 @@ static void handle_property(Local<String> name,
info.GetReturnValue().Set(v8_num(900));
}
+static void handle_property_2(Local<String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ info.GetReturnValue().Set(v8_num(902));
+}
+
+
+static void handle_property(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ CHECK_EQ(0, info.Length());
+ info.GetReturnValue().Set(v8_num(907));
+}
+
THREADED_TEST(PropertyHandler) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property);
+ Local<v8::FunctionTemplate> getter_templ =
+ v8::FunctionTemplate::New(handle_property);
+ getter_templ->SetLength(0);
+ fun_templ->
+ InstanceTemplate()->SetAccessorProperty(v8_str("bar"), getter_templ);
+ fun_templ->InstanceTemplate()->
+ SetNativeDataProperty(v8_str("instance_foo"), handle_property);
+ fun_templ->SetNativeDataProperty(v8_str("object_foo"), handle_property_2);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("Fun"), fun);
- Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;");
+ Local<Script> getter;
+ Local<Script> setter;
+ // check function instance accessors
+ getter = v8_compile("var obj = new Fun(); obj.instance_foo;");
CHECK_EQ(900, getter->Run()->Int32Value());
- Local<Script> setter = v8_compile("obj.foo = 901;");
+ setter = v8_compile("obj.instance_foo = 901;");
CHECK_EQ(901, setter->Run()->Int32Value());
+ getter = v8_compile("obj.bar;");
+ CHECK_EQ(907, getter->Run()->Int32Value());
+ setter = v8_compile("obj.bar = 908;");
+ CHECK_EQ(908, setter->Run()->Int32Value());
+ // check function static accessors
+ getter = v8_compile("Fun.object_foo;");
+ CHECK_EQ(902, getter->Run()->Int32Value());
+ setter = v8_compile("Fun.object_foo = 903;");
+ CHECK_EQ(903, setter->Run()->Int32Value());
}
@@ -109,30 +141,53 @@ THREADED_TEST(GlobalVariableAccess) {
}
-static int x_register = 0;
+static int x_register[2] = {0, 0};
static v8::Handle<v8::Object> x_receiver;
static v8::Handle<v8::Object> x_holder;
-
-static void XGetter(Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+template<class Info>
+static void XGetter(const Info& info, int offset) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, info.GetIsolate());
CHECK_EQ(x_receiver, info.This());
+ info.GetReturnValue().Set(v8_num(x_register[offset]));
+}
+
+
+static void XGetter(Local<String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK_EQ(x_holder, info.Holder());
- info.GetReturnValue().Set(v8_num(x_register));
+ XGetter(info, 0);
}
-static void XSetter(Local<String> name,
- Local<Value> value,
- const v8::PropertyCallbackInfo<void>& info) {
+static void XGetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK_EQ(x_receiver, info.Holder());
+ XGetter(info, 1);
+}
+
+
+template<class Info>
+static void XSetter(Local<Value> value, const Info& info, int offset) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, info.GetIsolate());
CHECK_EQ(x_holder, info.This());
CHECK_EQ(x_holder, info.Holder());
- x_register = value->Int32Value();
+ x_register[offset] = value->Int32Value();
+}
+
+
+static void XSetter(Local<String> name,
+ Local<Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ XSetter(value, info, 0);
+}
+
+
+static void XSetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK_EQ(1, info.Length());
+ XSetter(info[0], info, 1);
}
@@ -140,7 +195,10 @@ THREADED_TEST(AccessorIC) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
- obj->SetAccessor(v8_str("x"), XGetter, XSetter);
+ obj->SetAccessor(v8_str("x0"), XGetter, XSetter);
+ obj->SetAccessorProperty(v8_str("x1"),
+ v8::FunctionTemplate::New(XGetter),
+ v8::FunctionTemplate::New(XSetter));
x_holder = obj->NewInstance();
context->Global()->Set(v8_str("holder"), x_holder);
x_receiver = v8::Object::New();
@@ -148,15 +206,23 @@ THREADED_TEST(AccessorIC) {
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun(
"obj.__proto__ = holder;"
"var result = [];"
+ "var key_0 = 'x0';"
+ "var key_1 = 'x1';"
"for (var i = 0; i < 10; i++) {"
- " holder.x = i;"
- " result.push(obj.x);"
+ " holder.x0 = i;"
+ " result.push(obj.x0);"
+ " holder.x1 = i;"
+ " result.push(obj.x1);"
+ " holder[key_0] = i;"
+ " result.push(obj[key_0]);"
+ " holder[key_1] = i;"
+ " result.push(obj[key_1]);"
"}"
"result"));
- CHECK_EQ(10, array->Length());
- for (int i = 0; i < 10; i++) {
+ CHECK_EQ(40, array->Length());
+ for (int i = 0; i < 40; i++) {
v8::Handle<Value> entry = array->Get(v8::Integer::New(i));
- CHECK_EQ(v8::Integer::New(i), entry);
+ CHECK_EQ(v8::Integer::New(i/4), entry);
}
}
@@ -422,7 +488,8 @@ THREADED_TEST(StackIteration) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
- i::StringStream::ClearMentionedObjectCache();
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
+ i::StringStream::ClearMentionedObjectCache(isolate);
obj->SetAccessor(v8_str("xxx"), StackCheck);
env->Global()->Set(v8_str("obj"), obj->NewInstance());
Script::Compile(String::New(
@@ -485,3 +552,18 @@ THREADED_TEST(JSONStringifyNamedInterceptorObject) {
v8::Handle<v8::String> expected = v8_str("{\"regress\":\"crbug-161028\"}");
CHECK(CompileRun("JSON.stringify(obj)")->Equals(expected));
}
+
+
+THREADED_TEST(CrossContextAccess) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Function> fun = v8::Function::New(isolate, handle_property);
+ LocalContext switch_context;
+ switch_context->Global()->Set(v8_str("fun"), fun);
+ v8::TryCatch try_catch;
+ CompileRun(
+ "var o = Object.create(null, { n: { get:fun } });"
+ "for (var i = 0; i < 10; i++) o.n;");
+ CHECK(!try_catch.HasCaught());
+}
diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc
index d316c8e49f..f4f13d0d83 100644
--- a/deps/v8/test/cctest/test-alloc.cc
+++ b/deps/v8/test/cctest/test-alloc.cc
@@ -90,7 +90,7 @@ static MaybeObject* AllocateAfterFailures() {
static Handle<Object> Test() {
- CALL_HEAP_FUNCTION(ISOLATE, AllocateAfterFailures(), Object);
+ CALL_HEAP_FUNCTION(Isolate::Current(), AllocateAfterFailures(), Object);
}
@@ -104,7 +104,7 @@ TEST(StressHandles) {
}
-static MaybeObject* TestAccessorGet(Object* object, void*) {
+static MaybeObject* TestAccessorGet(Isolate* isolate, Object* object, void*) {
return AllocateAfterFailures();
}
@@ -186,10 +186,9 @@ class Block {
TEST(CodeRange) {
const int code_range_size = 32*MB;
- OS::SetUp();
- Isolate::Current()->InitializeLoggingAndCounters();
- CodeRange* code_range = new CodeRange(Isolate::Current());
- code_range->SetUp(code_range_size);
+ CcTest::InitializeVM();
+ CodeRange code_range(reinterpret_cast<Isolate*>(CcTest::isolate()));
+ code_range.SetUp(code_range_size);
int current_allocated = 0;
int total_allocated = 0;
List<Block> blocks(1000);
@@ -205,9 +204,9 @@ TEST(CodeRange) {
(Page::kMaxNonCodeHeapObjectSize << (Pseudorandom() % 3)) +
Pseudorandom() % 5000 + 1;
size_t allocated = 0;
- Address base = code_range->AllocateRawMemory(requested,
- requested,
- &allocated);
+ Address base = code_range.AllocateRawMemory(requested,
+ requested,
+ &allocated);
CHECK(base != NULL);
blocks.Add(Block(base, static_cast<int>(allocated)));
current_allocated += static_cast<int>(allocated);
@@ -215,7 +214,7 @@ TEST(CodeRange) {
} else {
// Free a block.
int index = Pseudorandom() % blocks.length();
- code_range->FreeRawMemory(blocks[index].base, blocks[index].size);
+ code_range.FreeRawMemory(blocks[index].base, blocks[index].size);
current_allocated -= blocks[index].size;
if (index < blocks.length() - 1) {
blocks[index] = blocks.RemoveLast();
@@ -225,6 +224,5 @@ TEST(CodeRange) {
}
}
- code_range->TearDown();
- delete code_range;
+ code_range.TearDown();
}
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 55d376d154..f4e40cdd38 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -25,17 +25,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include <limits.h>
-
-#ifndef WIN32
-#include <signal.h> // kill
-#include <unistd.h> // getpid
-#endif // WIN32
+#include <climits>
+#include <csignal>
#include <string>
#include <map>
#include "v8.h"
+#if V8_OS_POSIX
+#include <unistd.h> // NOLINT
+#endif
+
#include "api.h"
#include "arguments.h"
#include "cctest.h"
@@ -53,8 +53,6 @@
static const bool kLogThreading = false;
-using ::v8::AccessorInfo;
-using ::v8::Arguments;
using ::v8::Boolean;
using ::v8::BooleanObject;
using ::v8::Context;
@@ -143,10 +141,13 @@ static void ExpectUndefined(const char* code) {
static int signature_callback_count;
+static Local<Value> signature_expected_receiver;
static void IncrementingSignatureCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
signature_callback_count++;
+ CHECK_EQ(signature_expected_receiver, args.Holder());
+ CHECK_EQ(signature_expected_receiver, args.This());
v8::Handle<v8::Array> result = v8::Array::New(args.Length());
for (int i = 0; i < args.Length(); i++)
result->Set(v8::Integer::New(i), args[i]);
@@ -165,6 +166,24 @@ static void SignatureCallback(
}
+// Tests that call v8::V8::Dispose() cannot be threaded.
+TEST(InitializeAndDisposeOnce) {
+ CHECK(v8::V8::Initialize());
+ CHECK(v8::V8::Dispose());
+}
+
+
+// Tests that call v8::V8::Dispose() cannot be threaded.
+TEST(InitializeAndDisposeMultiple) {
+ for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
+ for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
+ for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
+ // TODO(mstarzinger): This should fail gracefully instead of asserting.
+ // for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
+ for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
+}
+
+
THREADED_TEST(Handles) {
v8::HandleScope scope(v8::Isolate::GetCurrent());
Local<Context> local_env;
@@ -205,47 +224,98 @@ THREADED_TEST(IsolateOfContext) {
}
+static void TestSignature(const char* loop_js, Local<Value> receiver) {
+ i::ScopedVector<char> source(200);
+ i::OS::SNPrintF(source,
+ "for (var i = 0; i < 10; i++) {"
+ " %s"
+ "}",
+ loop_js);
+ signature_callback_count = 0;
+ signature_expected_receiver = receiver;
+ bool expected_to_throw = receiver.IsEmpty();
+ v8::TryCatch try_catch;
+ CompileRun(source.start());
+ CHECK_EQ(expected_to_throw, try_catch.HasCaught());
+ if (!expected_to_throw) {
+ CHECK_EQ(10, signature_callback_count);
+ } else {
+ CHECK_EQ(v8_str("TypeError: Illegal invocation"),
+ try_catch.Exception()->ToString());
+ }
+}
+
+
THREADED_TEST(ReceiverSignature) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
+ // Setup templates.
v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New();
v8::Handle<v8::Signature> sig = v8::Signature::New(fun);
- fun->PrototypeTemplate()->Set(
- v8_str("m"),
- v8::FunctionTemplate::New(IncrementingSignatureCallback,
- v8::Handle<Value>(),
- sig));
- env->Global()->Set(v8_str("Fun"), fun->GetFunction());
- signature_callback_count = 0;
- CompileRun(
- "var o = new Fun();"
- "o.m();");
- CHECK_EQ(1, signature_callback_count);
+ v8::Handle<v8::FunctionTemplate> callback_sig =
+ v8::FunctionTemplate::New(
+ IncrementingSignatureCallback, Local<Value>(), sig);
+ v8::Handle<v8::FunctionTemplate> callback =
+ v8::FunctionTemplate::New(IncrementingSignatureCallback);
v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New();
sub_fun->Inherit(fun);
- env->Global()->Set(v8_str("SubFun"), sub_fun->GetFunction());
- CompileRun(
- "var o = new SubFun();"
- "o.m();");
- CHECK_EQ(2, signature_callback_count);
-
- v8::TryCatch try_catch;
- CompileRun(
- "var o = { };"
- "o.m = Fun.prototype.m;"
- "o.m();");
- CHECK_EQ(2, signature_callback_count);
- CHECK(try_catch.HasCaught());
- try_catch.Reset();
v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New();
- sub_fun->Inherit(fun);
+ // Install properties.
+ v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate();
+ fun_proto->Set(v8_str("prop_sig"), callback_sig);
+ fun_proto->Set(v8_str("prop"), callback);
+ fun_proto->SetAccessorProperty(
+ v8_str("accessor_sig"), callback_sig, callback_sig);
+ fun_proto->SetAccessorProperty(v8_str("accessor"), callback, callback);
+ // Instantiate templates.
+ Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance();
+ Local<Value> sub_fun_instance = sub_fun->InstanceTemplate()->NewInstance();
+ // Setup global variables.
+ env->Global()->Set(v8_str("Fun"), fun->GetFunction());
env->Global()->Set(v8_str("UnrelFun"), unrel_fun->GetFunction());
+ env->Global()->Set(v8_str("fun_instance"), fun_instance);
+ env->Global()->Set(v8_str("sub_fun_instance"), sub_fun_instance);
CompileRun(
- "var o = new UnrelFun();"
- "o.m = Fun.prototype.m;"
- "o.m();");
- CHECK_EQ(2, signature_callback_count);
- CHECK(try_catch.HasCaught());
+ "var accessor_sig_key = 'accessor_sig';"
+ "var accessor_key = 'accessor';"
+ "var prop_sig_key = 'prop_sig';"
+ "var prop_key = 'prop';"
+ ""
+ "function copy_props(obj) {"
+ " var keys = [accessor_sig_key, accessor_key, prop_sig_key, prop_key];"
+ " var source = Fun.prototype;"
+ " for (var i in keys) {"
+ " var key = keys[i];"
+ " var desc = Object.getOwnPropertyDescriptor(source, key);"
+ " Object.defineProperty(obj, key, desc);"
+ " }"
+ "}"
+ ""
+ "var obj = {};"
+ "copy_props(obj);"
+ "var unrel = new UnrelFun();"
+ "copy_props(unrel);");
+ // Test with and without ICs
+ const char* test_objects[] = {
+ "fun_instance", "sub_fun_instance", "obj", "unrel" };
+ unsigned bad_signature_start_offset = 2;
+ for (unsigned i = 0; i < ARRAY_SIZE(test_objects); i++) {
+ i::ScopedVector<char> source(200);
+ i::OS::SNPrintF(
+ source, "var test_object = %s; test_object", test_objects[i]);
+ Local<Value> test_object = CompileRun(source.start());
+ TestSignature("test_object.prop();", test_object);
+ TestSignature("test_object.accessor;", test_object);
+ TestSignature("test_object[accessor_key];", test_object);
+ TestSignature("test_object.accessor = 1;", test_object);
+ TestSignature("test_object[accessor_key] = 1;", test_object);
+ if (i >= bad_signature_start_offset) test_object = Local<Value>();
+ TestSignature("test_object.prop_sig();", test_object);
+ TestSignature("test_object.accessor_sig;", test_object);
+ TestSignature("test_object[accessor_sig_key];", test_object);
+ TestSignature("test_object.accessor_sig = 1;", test_object);
+ TestSignature("test_object[accessor_sig_key] = 1;", test_object);
+ }
}
@@ -1360,7 +1430,7 @@ THREADED_TEST(BigSmiInteger) {
int32_t value = i::Smi::kMaxValue;
// We cannot add one to a Smi::kMaxValue without wrapping.
- if (i::kSmiValueSize < 32) {
+ if (i::SmiValuesAre31Bits()) {
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
@@ -1379,7 +1449,7 @@ THREADED_TEST(BigInteger) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
// We cannot add one to a Smi::kMaxValue without wrapping.
- if (i::kSmiValueSize < 32) {
+ if (i::SmiValuesAre31Bits()) {
// The casts allow this to compile, even if Smi::kMaxValue is 2^31-1.
// The code will not be run in that case, due to the "if" guard.
int32_t value =
@@ -1830,7 +1900,17 @@ void InterceptorGetter(Local<String> name,
void InterceptorSetter(Local<String> name,
Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- // Intercept accesses that set certain integer values.
+ // Intercept accesses that set certain integer values, for which the name does
+ // not start with 'accessor_'.
+ String::Utf8Value utf8(name);
+ char* name_str = *utf8;
+ char prefix[] = "accessor_";
+ int i;
+ for (i = 0; name_str[i] && prefix[i]; ++i) {
+ if (name_str[i] != prefix[i]) break;
+ }
+ if (!prefix[i]) return;
+
if (value->IsInt32() && value->Int32Value() < 10000) {
Handle<Object> self = info.This();
self->SetHiddenValue(name, value);
@@ -2682,9 +2762,6 @@ static void CheckInternalFieldsAreZero(v8::Handle<T> value) {
THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
- i::FLAG_harmony_array_buffer = true;
- i::FLAG_harmony_typed_arrays = true;
-
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
@@ -2721,9 +2798,6 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
THREADED_TEST(ArrayBuffer_JSInternalToExternal) {
- i::FLAG_harmony_array_buffer = true;
- i::FLAG_harmony_typed_arrays = true;
-
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
@@ -2766,9 +2840,6 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) {
THREADED_TEST(ArrayBuffer_External) {
- i::FLAG_harmony_array_buffer = true;
- i::FLAG_harmony_typed_arrays = true;
-
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
@@ -3119,7 +3190,7 @@ THREADED_TEST(ResettingGlobalHandle) {
v8::HandleScope scope(isolate);
CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6);
}
- global.Dispose(isolate);
+ global.Dispose();
CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1);
}
@@ -3175,19 +3246,52 @@ THREADED_TEST(GlobalHandleUpcast) {
v8::HandleScope scope(isolate);
v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
v8::Persistent<String> global_string(isolate, local);
-#ifdef V8_USE_UNSAFE_HANDLES
- v8::Persistent<Value> global_value =
- v8::Persistent<Value>::Cast(global_string);
-#else
v8::Persistent<Value>& global_value =
v8::Persistent<Value>::Cast(global_string);
-#endif
CHECK(v8::Local<v8::Value>::New(isolate, global_value)->IsString());
CHECK(global_string == v8::Persistent<String>::Cast(global_value));
global_string.Dispose();
}
+THREADED_TEST(HandleEquality) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Persistent<String> global1;
+ v8::Persistent<String> global2;
+ {
+ v8::HandleScope scope(isolate);
+ global1.Reset(isolate, v8_str("str"));
+ global2.Reset(isolate, v8_str("str2"));
+ }
+ CHECK_EQ(global1 == global1, true);
+ CHECK_EQ(global1 != global1, false);
+ {
+ v8::HandleScope scope(isolate);
+ Local<String> local1 = Local<String>::New(isolate, global1);
+ Local<String> local2 = Local<String>::New(isolate, global2);
+
+ CHECK_EQ(global1 == local1, true);
+ CHECK_EQ(global1 != local1, false);
+ CHECK_EQ(local1 == global1, true);
+ CHECK_EQ(local1 != global1, false);
+
+ CHECK_EQ(global1 == local2, false);
+ CHECK_EQ(global1 != local2, true);
+ CHECK_EQ(local2 == global1, false);
+ CHECK_EQ(local2 != global1, true);
+
+ CHECK_EQ(local1 == local2, false);
+ CHECK_EQ(local1 != local2, true);
+
+ Local<String> anotherLocal1 = Local<String>::New(isolate, global1);
+ CHECK_EQ(local1 == anotherLocal1, true);
+ CHECK_EQ(local1 != anotherLocal1, false);
+ }
+ global1.Dispose();
+ global2.Dispose();
+}
+
+
THREADED_TEST(LocalHandle) {
v8::HandleScope scope(v8::Isolate::GetCurrent());
v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
@@ -3215,7 +3319,7 @@ static void WeakPointerCallback(v8::Isolate* isolate,
WeakCallCounter* counter) {
CHECK_EQ(1234, counter->id());
counter->increment();
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -3288,8 +3392,8 @@ THREADED_TEST(ApiObjectGroups) {
root.MakeWeak(&counter, &WeakPointerCallback);
// But make children strong roots---all the objects (except for children)
// should be collectable now.
- g1c1.ClearWeak(iso);
- g2c1.ClearWeak(iso);
+ g1c1.ClearWeak();
+ g2c1.ClearWeak();
// Groups are deleted, rebuild groups.
{
@@ -3339,29 +3443,29 @@ THREADED_TEST(ApiObjectGroupsCycle) {
g1s2.Reset(iso, Object::New());
g1s1.MakeWeak(&counter, &WeakPointerCallback);
g1s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g1s1.IsWeak(iso));
- CHECK(g1s2.IsWeak(iso));
+ CHECK(g1s1.IsWeak());
+ CHECK(g1s2.IsWeak());
g2s1.Reset(iso, Object::New());
g2s2.Reset(iso, Object::New());
g2s1.MakeWeak(&counter, &WeakPointerCallback);
g2s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g2s1.IsWeak(iso));
- CHECK(g2s2.IsWeak(iso));
+ CHECK(g2s1.IsWeak());
+ CHECK(g2s2.IsWeak());
g3s1.Reset(iso, Object::New());
g3s2.Reset(iso, Object::New());
g3s1.MakeWeak(&counter, &WeakPointerCallback);
g3s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g3s1.IsWeak(iso));
- CHECK(g3s2.IsWeak(iso));
+ CHECK(g3s1.IsWeak());
+ CHECK(g3s2.IsWeak());
g4s1.Reset(iso, Object::New());
g4s2.Reset(iso, Object::New());
g4s1.MakeWeak(&counter, &WeakPointerCallback);
g4s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g4s1.IsWeak(iso));
- CHECK(g4s2.IsWeak(iso));
+ CHECK(g4s1.IsWeak());
+ CHECK(g4s2.IsWeak());
}
Persistent<Value> root(iso, g1s1); // make a root.
@@ -3463,19 +3567,19 @@ TEST(ApiObjectGroupsCycleForScavenger) {
// Make a root.
Persistent<Value> root(iso, g1s1);
- root.MarkPartiallyDependent(iso);
+ root.MarkPartiallyDependent();
// Connect groups. We're building the following cycle:
// G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
// groups.
{
HandleScope handle_scope(iso);
- g1s1.MarkPartiallyDependent(iso);
- g1s2.MarkPartiallyDependent(iso);
- g2s1.MarkPartiallyDependent(iso);
- g2s2.MarkPartiallyDependent(iso);
- g3s1.MarkPartiallyDependent(iso);
- g3s2.MarkPartiallyDependent(iso);
+ g1s1.MarkPartiallyDependent();
+ g1s2.MarkPartiallyDependent();
+ g2s1.MarkPartiallyDependent();
+ g2s2.MarkPartiallyDependent();
+ g3s1.MarkPartiallyDependent();
+ g3s2.MarkPartiallyDependent();
iso->SetObjectGroupId(g1s1, UniqueId(1));
iso->SetObjectGroupId(g1s2, UniqueId(1));
Local<Object>::New(iso, g1s1.As<Object>())->Set(
@@ -3499,18 +3603,17 @@ TEST(ApiObjectGroupsCycleForScavenger) {
// Weaken the root.
root.MakeWeak(&counter, &WeakPointerCallback);
- root.MarkPartiallyDependent(iso);
+ root.MarkPartiallyDependent();
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
// Groups are deleted, rebuild groups.
{
HandleScope handle_scope(iso);
- g1s1.MarkPartiallyDependent(isolate);
- g1s2.MarkPartiallyDependent(isolate);
- g2s1.MarkPartiallyDependent(isolate);
- g2s2.MarkPartiallyDependent(isolate);
- g3s1.MarkPartiallyDependent(isolate);
- g3s2.MarkPartiallyDependent(isolate);
+ g1s1.MarkPartiallyDependent();
+ g1s2.MarkPartiallyDependent();
+ g2s1.MarkPartiallyDependent();
+ g2s2.MarkPartiallyDependent();
+ g3s1.MarkPartiallyDependent();
+ g3s2.MarkPartiallyDependent();
iso->SetObjectGroupId(g1s1, UniqueId(1));
iso->SetObjectGroupId(g1s2, UniqueId(1));
Local<Object>::New(iso, g1s1.As<Object>())->Set(
@@ -4868,7 +4971,7 @@ THREADED_TEST(Equality) {
v8::Handle<v8::Object> obj = v8::Object::New();
v8::Persistent<v8::Object> alias(isolate, obj);
CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj));
- alias.Dispose(isolate);
+ alias.Dispose();
}
@@ -5183,7 +5286,7 @@ THREADED_TEST(SimplePropertyWrite) {
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue));
- xValue.Dispose(context->GetIsolate());
+ xValue.Dispose();
xValue.Clear();
}
}
@@ -5200,7 +5303,7 @@ THREADED_TEST(SetterOnly) {
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue));
- xValue.Dispose(context->GetIsolate());
+ xValue.Dispose();
xValue.Clear();
}
}
@@ -6575,7 +6678,7 @@ class Snorkel {
class Whammy {
public:
explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
- ~Whammy() { script_.Dispose(isolate_); }
+ ~Whammy() { script_.Dispose(); }
v8::Handle<Script> getScript() {
if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
return Local<Script>::New(isolate_, script_);
@@ -6593,7 +6696,7 @@ static void HandleWeakReference(v8::Isolate* isolate,
v8::Persistent<v8::Value>* obj,
Snorkel* snorkel) {
delete snorkel;
- obj->ClearWeak(isolate);
+ obj->ClearWeak();
}
void WhammyPropertyGetter(Local<String> name,
@@ -6649,7 +6752,7 @@ THREADED_TEST(WeakReference) {
static void DisposeAndSetFlag(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->Dispose(isolate);
+ obj->Dispose();
*(data) = true;
}
@@ -6672,10 +6775,10 @@ THREADED_TEST(IndependentWeakHandle) {
bool object_b_disposed = false;
object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag);
- CHECK(!object_b.IsIndependent(iso));
- object_a.MarkIndependent(iso);
- object_b.MarkIndependent(iso);
- CHECK(object_b.IsIndependent(iso));
+ CHECK(!object_b.IsIndependent());
+ object_a.MarkIndependent();
+ object_b.MarkIndependent();
+ CHECK(object_b.IsIndependent());
HEAP->PerformScavenge();
CHECK(object_a_disposed);
CHECK(object_b_disposed);
@@ -6695,7 +6798,7 @@ static void InvokeMarkSweep() {
static void ForceScavenge(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->Dispose(isolate);
+ obj->Dispose();
*(data) = true;
InvokeScavenge();
}
@@ -6704,7 +6807,7 @@ static void ForceScavenge(v8::Isolate* isolate,
static void ForceMarkSweep(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->Dispose(isolate);
+ obj->Dispose();
*(data) = true;
InvokeMarkSweep();
}
@@ -6733,7 +6836,7 @@ THREADED_TEST(GCFromWeakCallbacks) {
}
bool disposed = false;
object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]);
- object.MarkIndependent(isolate);
+ object.MarkIndependent();
invoke_gc[outer_gc]();
CHECK(disposed);
}
@@ -6744,7 +6847,7 @@ THREADED_TEST(GCFromWeakCallbacks) {
static void RevivingCallback(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->ClearWeak(isolate);
+ obj->ClearWeak();
*(data) = true;
}
@@ -6766,7 +6869,7 @@ THREADED_TEST(IndependentHandleRevival) {
}
bool revived = false;
object.MakeWeak(&revived, &RevivingCallback);
- object.MarkIndependent(isolate);
+ object.MarkIndependent();
HEAP->PerformScavenge();
CHECK(revived);
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
@@ -8228,11 +8331,19 @@ static bool IndexedAccessBlocker(Local<v8::Object> global,
}
-static int g_echo_value = -1;
+static int g_echo_value_1 = -1;
+static int g_echo_value_2 = -1;
+
+
static void EchoGetter(
Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(v8_num(g_echo_value));
+ info.GetReturnValue().Set(v8_num(g_echo_value_1));
+}
+
+
+static void EchoGetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ info.GetReturnValue().Set(v8_num(g_echo_value_2));
}
@@ -8240,7 +8351,14 @@ static void EchoSetter(Local<String> name,
Local<Value> value,
const v8::PropertyCallbackInfo<void>&) {
if (value->IsNumber())
- g_echo_value = value->Int32Value();
+ g_echo_value_1 = value->Int32Value();
+}
+
+
+static void EchoSetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Handle<v8::Value> value = info[0];
+ if (value->IsNumber())
+ g_echo_value_2 = value->Int32Value();
}
@@ -8258,6 +8376,12 @@ static void UnreachableSetter(Local<String>,
}
+static void UnreachableFunction(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(false); // This function should not be called..
+}
+
+
TEST(AccessControl) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
@@ -8273,12 +8397,27 @@ TEST(AccessControl) {
v8::Handle<Value>(),
v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE));
+
+ global_template->SetAccessorProperty(
+ v8_str("accessible_js_prop"),
+ v8::FunctionTemplate::New(EchoGetter),
+ v8::FunctionTemplate::New(EchoSetter),
+ v8::None,
+ 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,
v8::Handle<Value>(),
v8::DEFAULT);
+ global_template->SetAccessorProperty(
+ v8_str("blocked_js_prop"),
+ v8::FunctionTemplate::New(UnreachableFunction),
+ v8::FunctionTemplate::New(UnreachableFunction),
+ v8::None,
+ v8::DEFAULT);
+
// Create an environment
v8::Local<Context> context0 = Context::New(isolate, NULL, global_template);
context0->Enter();
@@ -8471,26 +8610,47 @@ TEST(AccessControl) {
value = CompileRun("other.accessible_prop = 3");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- CHECK_EQ(3, g_echo_value);
+ CHECK_EQ(3, g_echo_value_1);
+
+ // Access accessible js property
+ value = CompileRun("other.accessible_js_prop = 3");
+ CHECK(value->IsNumber());
+ CHECK_EQ(3, value->Int32Value());
+ CHECK_EQ(3, g_echo_value_2);
value = CompileRun("other.accessible_prop");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
+ value = CompileRun("other.accessible_js_prop");
+ CHECK(value->IsNumber());
+ CHECK_EQ(3, value->Int32Value());
+
value = CompileRun(
"Object.getOwnPropertyDescriptor(other, 'accessible_prop').value");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
+ value = CompileRun(
+ "Object.getOwnPropertyDescriptor(other, 'accessible_js_prop').get()");
+ CHECK(value->IsNumber());
+ CHECK_EQ(3, value->Int32Value());
+
value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')");
CHECK(value->IsTrue());
+ value = CompileRun("propertyIsEnumerable.call(other, 'accessible_js_prop')");
+ CHECK(value->IsTrue());
+
// Enumeration doesn't enumerate accessors from inaccessible objects in
// the prototype chain even if the accessors are in themselves accessible.
value =
CompileRun("(function(){var obj = {'__proto__':other};"
"for (var p in obj)"
- " if (p == 'accessible_prop' || p == 'blocked_prop') {"
+ " if (p == 'accessible_prop' ||"
+ " p == 'accessible_js_prop' ||"
+ " p == 'blocked_js_prop' ||"
+ " p == 'blocked_js_prop') {"
" return false;"
" }"
"return true;})()");
@@ -8562,7 +8722,7 @@ TEST(AccessControlES5) {
// Make sure that we can set the accessible accessors value using normal
// assignment.
CompileRun("other.accessible_prop = 42");
- CHECK_EQ(42, g_echo_value);
+ CHECK_EQ(42, g_echo_value_1);
v8::Handle<Value> value;
// We follow Safari in ignoring assignments to host object accessors.
@@ -9522,6 +9682,26 @@ THREADED_TEST(SetPrototypeThrows) {
}
+THREADED_TEST(FunctionRemovePrototype) {
+ LocalContext context;
+ v8::HandleScope handle_scope(context->GetIsolate());
+
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ t1->RemovePrototype();
+ Local<v8::Function> fun = t1->GetFunction();
+ context->Global()->Set(v8_str("fun"), fun);
+ CHECK(!CompileRun("'prototype' in fun")->BooleanValue());
+
+ v8::TryCatch try_catch;
+ CompileRun("new fun()");
+ CHECK(try_catch.HasCaught());
+
+ try_catch.Reset();
+ fun->NewInstance();
+ CHECK(try_catch.HasCaught());
+}
+
+
THREADED_TEST(GetterSetterExceptions) {
LocalContext context;
v8::HandleScope handle_scope(context->GetIsolate());
@@ -12133,8 +12313,7 @@ THREADED_TEST(ObjectGetConstructorName) {
bool ApiTestFuzzer::fuzzing_ = false;
-i::Semaphore* ApiTestFuzzer::all_tests_done_=
- i::OS::CreateSemaphore(0);
+i::Semaphore ApiTestFuzzer::all_tests_done_(0);
int ApiTestFuzzer::active_tests_;
int ApiTestFuzzer::tests_being_run_;
int ApiTestFuzzer::current_;
@@ -12165,14 +12344,14 @@ bool ApiTestFuzzer::NextThread() {
RegisterThreadedTest::nth(test_position)->name());
}
current_ = test_position;
- RegisterThreadedTest::nth(current_)->fuzzer_->gate_->Signal();
+ RegisterThreadedTest::nth(current_)->fuzzer_->gate_.Signal();
return true;
}
void ApiTestFuzzer::Run() {
// When it is our turn...
- gate_->Wait();
+ gate_.Wait();
{
// ... get the V8 lock and start running the test.
v8::Locker locker(CcTest::default_isolate());
@@ -12183,7 +12362,7 @@ void ApiTestFuzzer::Run() {
active_tests_--;
// If it was the last then signal that fact.
if (active_tests_ == 0) {
- all_tests_done_->Signal();
+ all_tests_done_.Signal();
} else {
// Otherwise select a new test and start that.
NextThread();
@@ -12220,7 +12399,7 @@ void ApiTestFuzzer::RunAllTests() {
current_ = -1;
NextThread();
// Wait till they are all done.
- all_tests_done_->Wait();
+ all_tests_done_.Wait();
}
@@ -12241,7 +12420,7 @@ void ApiTestFuzzer::ContextSwitch() {
// Now it can start.
v8::Unlocker unlocker(CcTest::default_isolate());
// Wait till someone starts us again.
- gate_->Wait();
+ gate_.Wait();
// And we're off.
}
}
@@ -12258,9 +12437,6 @@ void ApiTestFuzzer::TearDown() {
// Lets not be needlessly self-referential.
TEST(Threading1) {
- // TODO(mstarzinger): Disabled in GC stress mode for now, we should find the
- // correct timeout for this an re-enable this test again
- if (i::FLAG_stress_compaction) return;
ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
@@ -12489,6 +12665,75 @@ TEST(DontLeakGlobalObjects) {
}
}
+template<class T>
+struct CopyablePersistentTraits {
+ typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
+ static const bool kResetInDestructor = true;
+ template<class S, class M>
+ static V8_INLINE void Copy(const Persistent<S, M>& source,
+ CopyablePersistent* dest) {
+ // do nothing, just allow copy
+ }
+};
+
+
+TEST(CopyablePersistent) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ i::GlobalHandles* globals =
+ reinterpret_cast<i::Isolate*>(isolate)->global_handles();
+ int initial_handles = globals->global_handles_count();
+ {
+ v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > handle1;
+ {
+ v8::HandleScope scope(isolate);
+ handle1.Reset(isolate, v8::Object::New());
+ }
+ CHECK_EQ(initial_handles + 1, globals->global_handles_count());
+ v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > handle2;
+ handle2 = handle1;
+ CHECK(handle1 == handle2);
+ CHECK_EQ(initial_handles + 2, globals->global_handles_count());
+ v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> >
+ handle3(handle2);
+ CHECK(handle1 == handle3);
+ CHECK_EQ(initial_handles + 3, globals->global_handles_count());
+ }
+ // Verify autodispose
+ CHECK_EQ(initial_handles, globals->global_handles_count());
+}
+
+
+static void WeakApiCallback(
+ const v8::WeakCallbackData<v8::Object, Persistent<v8::Object> >& data) {
+ Local<Value> value = data.GetValue()->Get(v8_str("key"));
+ CHECK_EQ(231, static_cast<int32_t>(Local<v8::Integer>::Cast(value)->Value()));
+ data.GetParameter()->Reset();
+ delete data.GetParameter();
+}
+
+
+TEST(WeakCallbackApi) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ i::GlobalHandles* globals =
+ reinterpret_cast<i::Isolate*>(isolate)->global_handles();
+ int initial_handles = globals->global_handles_count();
+ {
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Object> obj = v8::Object::New();
+ obj->Set(v8_str("key"), v8::Integer::New(231, isolate));
+ v8::Persistent<v8::Object>* handle =
+ new v8::Persistent<v8::Object>(isolate, obj);
+ handle->SetWeak<v8::Object, v8::Persistent<v8::Object> >(handle,
+ WeakApiCallback);
+ }
+ reinterpret_cast<i::Isolate*>(isolate)->heap()->
+ CollectAllGarbage(i::Heap::kNoGCFlags);
+ // Verify disposed.
+ CHECK_EQ(initial_handles, globals->global_handles_count());
+}
+
v8::Persistent<v8::Object> some_object;
v8::Persistent<v8::Object> bad_handle;
@@ -12498,7 +12743,7 @@ void NewPersistentHandleCallback(v8::Isolate* isolate,
void*) {
v8::HandleScope scope(isolate);
bad_handle.Reset(isolate, some_object);
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -12518,7 +12763,7 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) {
// in reverse allocation order, so if second allocated handle is deleted,
// weak callback of the first handle would be able to 'reallocate' it.
handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback);
- handle2.Dispose(isolate);
+ handle2.Dispose();
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -12528,9 +12773,9 @@ v8::Persistent<v8::Object> to_be_disposed;
void DisposeAndForceGcCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
- to_be_disposed.Dispose(isolate);
+ to_be_disposed.Dispose();
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -12552,7 +12797,7 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
void DisposingCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
- handle->Dispose(isolate);
+ handle->Dispose();
}
void HandleCreatingCallback(v8::Isolate* isolate,
@@ -12560,7 +12805,7 @@ void HandleCreatingCallback(v8::Isolate* isolate,
void*) {
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object>(isolate, v8::Object::New());
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -12958,9 +13203,6 @@ TEST(SetFunctionEntryHook) {
// Experimental natives are compiled during snapshot deserialization.
// This test breaks because InstallGetter (function from snapshot that
// only gets called from experimental natives) is compiled with entry hooks.
- i::FLAG_harmony_typed_arrays = false;
- i::FLAG_harmony_array_buffer = false;
-
i::FLAG_allow_natives_syntax = true;
i::FLAG_use_inlining = false;
@@ -13159,7 +13401,7 @@ TEST(SetJitCodeEventHandler) {
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo"))))->code());
// Clear the compilation cache to get more wastage.
- ISOLATE->compilation_cache()->Clear();
+ reinterpret_cast<i::Isolate*>(isolate)->compilation_cache()->Clear();
}
// Force code movement.
@@ -13963,10 +14205,9 @@ THREADED_TEST(CrossContextNew) {
class RegExpInterruptTest {
public:
- RegExpInterruptTest() : block_(NULL) {}
- ~RegExpInterruptTest() { delete block_; }
+ RegExpInterruptTest() : block_(0) {}
+ ~RegExpInterruptTest() {}
void RunTest() {
- block_ = i::OS::CreateSemaphore(0);
gc_count_ = 0;
gc_during_regexp_ = 0;
regexp_success_ = false;
@@ -14001,7 +14242,7 @@ class RegExpInterruptTest {
};
void CollectGarbage() {
- block_->Wait();
+ block_.Wait();
while (gc_during_regexp_ < kRequiredGCs) {
{
v8::Locker lock(CcTest::default_isolate());
@@ -14015,7 +14256,7 @@ class RegExpInterruptTest {
}
void LongRunningRegExp() {
- block_->Signal(); // Enable garbage collection thread on next preemption.
+ block_.Signal(); // Enable garbage collection thread on next preemption.
int rounds = 0;
while (gc_during_regexp_ < kRequiredGCs) {
int gc_before = gc_count_;
@@ -14053,7 +14294,7 @@ class RegExpInterruptTest {
regexp_success_ = true;
}
- i::Semaphore* block_;
+ i::Semaphore block_;
int gc_count_;
int gc_during_regexp_;
bool regexp_success_;
@@ -14086,10 +14327,9 @@ TEST(RegExpInterruption) {
class ApplyInterruptTest {
public:
- ApplyInterruptTest() : block_(NULL) {}
- ~ApplyInterruptTest() { delete block_; }
+ ApplyInterruptTest() : block_(0) {}
+ ~ApplyInterruptTest() {}
void RunTest() {
- block_ = i::OS::CreateSemaphore(0);
gc_count_ = 0;
gc_during_apply_ = 0;
apply_success_ = false;
@@ -14124,7 +14364,7 @@ class ApplyInterruptTest {
};
void CollectGarbage() {
- block_->Wait();
+ block_.Wait();
while (gc_during_apply_ < kRequiredGCs) {
{
v8::Locker lock(CcTest::default_isolate());
@@ -14137,7 +14377,7 @@ class ApplyInterruptTest {
}
void LongRunningApply() {
- block_->Signal();
+ block_.Signal();
int rounds = 0;
while (gc_during_apply_ < kRequiredGCs) {
int gc_before = gc_count_;
@@ -14162,7 +14402,7 @@ class ApplyInterruptTest {
apply_success_ = true;
}
- i::Semaphore* block_;
+ i::Semaphore block_;
int gc_count_;
int gc_during_apply_;
bool apply_success_;
@@ -14375,12 +14615,12 @@ TEST(CompileExternalTwoByteSource) {
class RegExpStringModificationTest {
public:
RegExpStringModificationTest()
- : block_(i::OS::CreateSemaphore(0)),
+ : block_(0),
morphs_(0),
morphs_during_regexp_(0),
ascii_resource_(i::Vector<const char>("aaaaaaaaaaaaaab", 15)),
uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {}
- ~RegExpStringModificationTest() { delete block_; }
+ ~RegExpStringModificationTest() {}
void RunTest() {
i::Factory* factory = i::Isolate::Current()->factory();
@@ -14437,7 +14677,7 @@ class RegExpStringModificationTest {
};
void MorphString() {
- block_->Wait();
+ block_.Wait();
while (morphs_during_regexp_ < kRequiredModifications &&
morphs_ < kMaxModifications) {
{
@@ -14453,7 +14693,7 @@ class RegExpStringModificationTest {
}
void LongRunningRegExp() {
- block_->Signal(); // Enable morphing thread on next preemption.
+ block_.Signal(); // Enable morphing thread on next preemption.
while (morphs_during_regexp_ < kRequiredModifications &&
morphs_ < kMaxModifications) {
int morphs_before = morphs_;
@@ -14475,7 +14715,7 @@ class RegExpStringModificationTest {
}
i::uc16 two_byte_content_[15];
- i::Semaphore* block_;
+ i::Semaphore block_;
int morphs_;
int morphs_during_regexp_;
bool regexp_success_;
@@ -14902,10 +15142,19 @@ THREADED_TEST(Regress16276) {
CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value());
}
+static void CheckElementValue(i::Isolate* isolate,
+ int expected,
+ i::Handle<i::Object> obj,
+ int offset) {
+ i::Object* element = obj->GetElement(isolate, offset)->ToObjectChecked();
+ CHECK_EQ(expected, i::Smi::cast(element)->value());
+}
+
THREADED_TEST(PixelArray) {
LocalContext context;
- i::Factory* factory = i::Isolate::Current()->factory();
+ i::Isolate* isolate = i::Isolate::Current();
+ i::Factory* factory = isolate->factory();
v8::HandleScope scope(context->GetIsolate());
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
@@ -14931,7 +15180,7 @@ THREADED_TEST(PixelArray) {
// Set the elements to be the pixels.
// jsobj->set_elements(*pixels);
obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
- CHECK_EQ(1, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 1, jsobj, 1);
obj->Set(v8_str("field"), v8::Int32::New(1503));
context->Global()->Set(v8_str("pixels"), obj);
v8::Handle<v8::Value> result = CompileRun("pixels.field");
@@ -14988,40 +15237,33 @@ THREADED_TEST(PixelArray) {
i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
- CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 2, jsobj, 1);
*value.location() = i::Smi::FromInt(256);
no_failure =
i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
- CHECK_EQ(255,
- i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 255, jsobj, 1);
*value.location() = i::Smi::FromInt(-1);
no_failure =
i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 1);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" pixels[i] = (i * 65) - 109;"
"}"
"pixels[1] + pixels[6];");
CHECK_EQ(255, result->Int32Value());
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0)->ToObjectChecked())->value());
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
- CHECK_EQ(21,
- i::Smi::cast(jsobj->GetElement(2)->ToObjectChecked())->value());
- CHECK_EQ(86,
- i::Smi::cast(jsobj->GetElement(3)->ToObjectChecked())->value());
- CHECK_EQ(151,
- i::Smi::cast(jsobj->GetElement(4)->ToObjectChecked())->value());
- CHECK_EQ(216,
- i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
- CHECK_EQ(255,
- i::Smi::cast(jsobj->GetElement(6)->ToObjectChecked())->value());
- CHECK_EQ(255,
- i::Smi::cast(jsobj->GetElement(7)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 0);
+ CheckElementValue(isolate, 0, jsobj, 1);
+ CheckElementValue(isolate, 21, jsobj, 2);
+ CheckElementValue(isolate, 86, jsobj, 3);
+ CheckElementValue(isolate, 151, jsobj, 4);
+ CheckElementValue(isolate, 216, jsobj, 5);
+ CheckElementValue(isolate, 255, jsobj, 6);
+ CheckElementValue(isolate, 255, jsobj, 7);
result = CompileRun("var sum = 0;"
"for (var i = 0; i < 8; i++) {"
" sum += pixels[i];"
@@ -15034,50 +15276,49 @@ THREADED_TEST(PixelArray) {
"}"
"pixels[1] + pixels[6];");
CHECK_EQ(8, result->Int32Value());
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0)->ToObjectChecked())->value());
- CHECK_EQ(1, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
- CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(2)->ToObjectChecked())->value());
- CHECK_EQ(3, i::Smi::cast(jsobj->GetElement(3)->ToObjectChecked())->value());
- CHECK_EQ(4, i::Smi::cast(jsobj->GetElement(4)->ToObjectChecked())->value());
- CHECK_EQ(6, i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
- CHECK_EQ(7, i::Smi::cast(jsobj->GetElement(6)->ToObjectChecked())->value());
- CHECK_EQ(8, i::Smi::cast(jsobj->GetElement(7)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 0);
+ CheckElementValue(isolate, 1, jsobj, 1);
+ CheckElementValue(isolate, 2, jsobj, 2);
+ CheckElementValue(isolate, 3, jsobj, 3);
+ CheckElementValue(isolate, 4, jsobj, 4);
+ CheckElementValue(isolate, 6, jsobj, 5);
+ CheckElementValue(isolate, 7, jsobj, 6);
+ CheckElementValue(isolate, 8, jsobj, 7);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" pixels[7] = undefined;"
"}"
"pixels[7];");
CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(7)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 7);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" pixels[6] = '2.3';"
"}"
"pixels[6];");
CHECK_EQ(2, result->Int32Value());
- CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(6)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 2, jsobj, 6);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" pixels[5] = NaN;"
"}"
"pixels[5];");
CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 5);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" pixels[8] = Infinity;"
"}"
"pixels[8];");
CHECK_EQ(255, result->Int32Value());
- CHECK_EQ(255,
- i::Smi::cast(jsobj->GetElement(8)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 255, jsobj, 8);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" pixels[9] = -Infinity;"
"}"
"pixels[9];");
CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(9)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 9);
result = CompileRun("pixels[3] = 33;"
"delete pixels[3];"
@@ -15394,6 +15635,7 @@ static void ObjectWithExternalArrayTestHelper(
v8::ExternalArrayType array_type,
int64_t low, int64_t high) {
i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
+ i::Isolate* isolate = jsobj->GetIsolate();
obj->Set(v8_str("field"), v8::Int32::New(1503));
context->Global()->Set(v8_str("ext_array"), obj);
v8::Handle<v8::Value> result = CompileRun("ext_array.field");
@@ -15535,12 +15777,11 @@ static void ObjectWithExternalArrayTestHelper(
CHECK_EQ(0, result->Int32Value());
if (array_type == v8::kExternalDoubleArray ||
array_type == v8::kExternalFloatArray) {
- CHECK_EQ(
- static_cast<int>(i::OS::nan_value()),
- static_cast<int>(jsobj->GetElement(7)->ToObjectChecked()->Number()));
+ CHECK_EQ(static_cast<int>(i::OS::nan_value()),
+ static_cast<int>(
+ jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number()));
} else {
- CHECK_EQ(0, static_cast<int>(
- jsobj->GetElement(7)->ToObjectChecked()->Number()));
+ CheckElementValue(isolate, 0, jsobj, 7);
}
result = CompileRun("for (var i = 0; i < 8; i++) {"
@@ -15548,8 +15789,9 @@ static void ObjectWithExternalArrayTestHelper(
"}"
"ext_array[6];");
CHECK_EQ(2, result->Int32Value());
- CHECK_EQ(
- 2, static_cast<int>(jsobj->GetElement(6)->ToObjectChecked()->Number()));
+ CHECK_EQ(2,
+ static_cast<int>(
+ jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number()));
if (array_type != v8::kExternalFloatArray &&
array_type != v8::kExternalDoubleArray) {
@@ -15563,8 +15805,7 @@ static void ObjectWithExternalArrayTestHelper(
"}"
"ext_array[5];");
CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(0,
- i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 5);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" ext_array[i] = 5;"
@@ -15576,8 +15817,7 @@ static void ObjectWithExternalArrayTestHelper(
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());
+ CheckElementValue(isolate, expected_value, jsobj, 5);
result = CompileRun("for (var i = 0; i < 8; i++) {"
" ext_array[i] = 5;"
@@ -15587,8 +15827,7 @@ static void ObjectWithExternalArrayTestHelper(
"}"
"ext_array[5];");
CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(0,
- i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
+ CheckElementValue(isolate, 0, jsobj, 5);
// Check truncation behavior of integral arrays.
const char* unsigned_data =
@@ -15694,7 +15933,8 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
int64_t low,
int64_t high) {
LocalContext context;
- i::Factory* factory = i::Isolate::Current()->factory();
+ i::Isolate* isolate = i::Isolate::Current();
+ i::Factory* factory = isolate->factory();
v8::HandleScope scope(context->GetIsolate());
const int kElementCount = 40;
int element_size = ExternalArrayElementSize(array_type);
@@ -15722,8 +15962,9 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
obj->SetIndexedPropertiesToExternalArrayData(array_data,
array_type,
kElementCount);
- CHECK_EQ(
- 1, static_cast<int>(jsobj->GetElement(1)->ToObjectChecked()->Number()));
+ CHECK_EQ(1,
+ static_cast<int>(
+ jsobj->GetElement(isolate, 1)->ToObjectChecked()->Number()));
ObjectWithExternalArrayTestHelper<ExternalArrayClass, ElementType>(
context.local(), obj, kElementCount, array_type, low, high);
@@ -16157,8 +16398,6 @@ THREADED_TEST(DataView) {
#define IS_ARRAY_BUFFER_VIEW_TEST(View) \
THREADED_TEST(Is##View) { \
- i::FLAG_harmony_array_buffer = true; \
- i::FLAG_harmony_typed_arrays = true; \
LocalContext env; \
v8::Isolate* isolate = env->GetIsolate(); \
v8::HandleScope handle_scope(isolate); \
@@ -16569,6 +16808,42 @@ TEST(SourceURLInStackTrace) {
}
+static int scriptIdInStack[2];
+
+void AnalyzeScriptIdInStack(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::HandleScope scope(args.GetIsolate());
+ v8::Handle<v8::StackTrace> stackTrace =
+ v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kScriptId);
+ CHECK_EQ(2, stackTrace->GetFrameCount());
+ for (int i = 0; i < 2; i++) {
+ scriptIdInStack[i] = stackTrace->GetFrame(i)->GetScriptId();
+ }
+}
+
+
+TEST(ScriptIdInStackTrace) {
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("AnalyzeScriptIdInStack"),
+ v8::FunctionTemplate::New(AnalyzeScriptIdInStack));
+ LocalContext context(0, templ);
+
+ v8::Handle<v8::String> scriptSource = v8::String::New(
+ "function foo() {\n"
+ " AnalyzeScriptIdInStack();"
+ "}\n"
+ "foo();\n");
+ v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+ v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
+ script->Run();
+ for (int i = 0; i < 2; i++) {
+ CHECK(scriptIdInStack[i] != v8::Message::kNoScriptIdInfo);
+ CHECK_EQ(scriptIdInStack[i], script->GetId());
+ }
+}
+
+
void AnalyzeStackOfInlineScriptWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
@@ -18461,15 +18736,15 @@ TEST(PersistentHandleVisitor) {
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object> object(isolate, v8::Object::New());
- CHECK_EQ(0, object.WrapperClassId(isolate));
- object.SetWrapperClassId(isolate, 42);
- CHECK_EQ(42, object.WrapperClassId(isolate));
+ CHECK_EQ(0, object.WrapperClassId());
+ object.SetWrapperClassId(42);
+ CHECK_EQ(42, object.WrapperClassId());
Visitor42 visitor(&object);
v8::V8::VisitHandlesWithClassIds(&visitor);
CHECK_EQ(1, visitor.counter_);
- object.Dispose(isolate);
+ object.Dispose();
}
@@ -18478,10 +18753,10 @@ TEST(WrapperClassId) {
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object> object(isolate, v8::Object::New());
- CHECK_EQ(0, object.WrapperClassId(isolate));
- object.SetWrapperClassId(isolate, 65535);
- CHECK_EQ(65535, object.WrapperClassId(isolate));
- object.Dispose(isolate);
+ CHECK_EQ(0, object.WrapperClassId());
+ object.SetWrapperClassId(65535);
+ CHECK_EQ(65535, object.WrapperClassId());
+ object.Dispose();
}
@@ -18490,23 +18765,23 @@ TEST(PersistentHandleInNewSpaceVisitor) {
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object> object1(isolate, v8::Object::New());
- CHECK_EQ(0, object1.WrapperClassId(isolate));
- object1.SetWrapperClassId(isolate, 42);
- CHECK_EQ(42, object1.WrapperClassId(isolate));
+ CHECK_EQ(0, object1.WrapperClassId());
+ object1.SetWrapperClassId(42);
+ CHECK_EQ(42, object1.WrapperClassId());
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
v8::Persistent<v8::Object> object2(isolate, v8::Object::New());
- CHECK_EQ(0, object2.WrapperClassId(isolate));
- object2.SetWrapperClassId(isolate, 42);
- CHECK_EQ(42, object2.WrapperClassId(isolate));
+ CHECK_EQ(0, object2.WrapperClassId());
+ object2.SetWrapperClassId(42);
+ CHECK_EQ(42, object2.WrapperClassId());
Visitor42 visitor(&object2);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
CHECK_EQ(1, visitor.counter_);
- object1.Dispose(isolate);
- object2.Dispose(isolate);
+ object1.Dispose();
+ object2.Dispose();
}
@@ -19460,19 +19735,20 @@ TEST(StaticGetters) {
TEST(IsolateEmbedderData) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
CHECK_EQ(NULL, isolate->GetData());
- CHECK_EQ(NULL, ISOLATE->GetData());
+ CHECK_EQ(NULL, i_isolate->GetData());
static void* data1 = reinterpret_cast<void*>(0xacce55ed);
isolate->SetData(data1);
CHECK_EQ(data1, isolate->GetData());
- CHECK_EQ(data1, ISOLATE->GetData());
+ CHECK_EQ(data1, i_isolate->GetData());
static void* data2 = reinterpret_cast<void*>(0xdecea5ed);
- ISOLATE->SetData(data2);
+ i_isolate->SetData(data2);
CHECK_EQ(data2, isolate->GetData());
- CHECK_EQ(data2, ISOLATE->GetData());
- ISOLATE->TearDown();
+ CHECK_EQ(data2, i_isolate->GetData());
+ i_isolate->TearDown();
CHECK_EQ(data2, isolate->GetData());
- CHECK_EQ(data2, ISOLATE->GetData());
+ CHECK_EQ(data2, i_isolate->GetData());
}
@@ -19935,19 +20211,17 @@ THREADED_TEST(JSONParseNumber) {
}
-#ifndef WIN32
+#if V8_OS_POSIX
class ThreadInterruptTest {
public:
- ThreadInterruptTest() : sem_(NULL), sem_value_(0) { }
- ~ThreadInterruptTest() { delete sem_; }
+ ThreadInterruptTest() : sem_(0), sem_value_(0) { }
+ ~ThreadInterruptTest() {}
void RunTest() {
- sem_ = i::OS::CreateSemaphore(0);
-
InterruptThread i_thread(this);
i_thread.Start();
- sem_->Wait();
+ sem_.Wait();
CHECK_EQ(kExpectedValue, sem_value_);
}
@@ -19978,7 +20252,7 @@ class ThreadInterruptTest {
// Set value and signal semaphore
test_->sem_value_ = 1;
- test_->sem_->Signal();
+ test_->sem_.Signal();
}
static void SignalHandler(int signal) {
@@ -19988,7 +20262,7 @@ class ThreadInterruptTest {
ThreadInterruptTest* test_;
};
- i::Semaphore* sem_;
+ i::Semaphore sem_;
volatile int sem_value_;
};
@@ -20171,6 +20445,10 @@ TEST(AccessCheckThrows) {
CheckCorrectThrow("%GetLocalPropertyNames(other, true)");
CheckCorrectThrow("%DefineOrRedefineAccessorProperty("
"other, 'x', null, null, 1)");
+
+ // Reset the failed access check callback so it does not influence
+ // the other tests.
+ v8::V8::SetFailedAccessCheckCallbackFunction(NULL);
}
@@ -20190,4 +20468,122 @@ THREADED_TEST(Regress256330) {
}
-#endif // WIN32
+THREADED_TEST(CrankshaftInterceptorSetter) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ // Initialize fields to avoid transitions later.
+ "obj.age = 0;"
+ "obj.accessor_age = 42;"
+ "function setter(i) { this.accessor_age = i; };"
+ "function getter() { return this.accessor_age; };"
+ "function setAge(i) { obj.age = i; };"
+ "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
+ "setAge(1);"
+ "setAge(2);"
+ "setAge(3);"
+ "%OptimizeFunctionOnNextCall(setAge);"
+ "setAge(4);");
+ // All stores went through the interceptor.
+ ExpectInt32("obj.interceptor_age", 4);
+ ExpectInt32("obj.accessor_age", 42);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorGetter) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ // Initialize fields to avoid transitions later.
+ "obj.age = 1;"
+ "obj.accessor_age = 42;"
+ "function getter() { return this.accessor_age; };"
+ "function getAge() { return obj.interceptor_age; };"
+ "Object.defineProperty(obj, 'interceptor_age', { get:getter });"
+ "getAge();"
+ "getAge();"
+ "getAge();"
+ "%OptimizeFunctionOnNextCall(getAge);");
+ // Access through interceptor.
+ ExpectInt32("getAge()", 1);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorFieldRead) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "obj.__proto__.interceptor_age = 42;"
+ "obj.age = 100;"
+ "function getAge() { return obj.interceptor_age; };");
+ ExpectInt32("getAge();", 100);
+ ExpectInt32("getAge();", 100);
+ ExpectInt32("getAge();", 100);
+ CompileRun("%OptimizeFunctionOnNextCall(getAge);");
+ // Access through interceptor.
+ ExpectInt32("getAge();", 100);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorFieldWrite) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "obj.age = 100000;"
+ "function setAge(i) { obj.age = i };"
+ "setAge(100);"
+ "setAge(101);"
+ "setAge(102);"
+ "%OptimizeFunctionOnNextCall(setAge);"
+ "setAge(103);");
+ ExpectInt32("obj.age", 100000);
+ ExpectInt32("obj.interceptor_age", 103);
+}
+
+
+#endif // V8_OS_POSIX
+
+
+static Local<Value> function_new_expected_env;
+static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
+ CHECK_EQ(function_new_expected_env, info.Data());
+ info.GetReturnValue().Set(17);
+}
+
+
+THREADED_TEST(FunctionNew) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Object> data = v8::Object::New();
+ function_new_expected_env = data;
+ Local<Function> func = Function::New(isolate, FunctionNewCallback, data);
+ env->Global()->Set(v8_str("func"), func);
+ Local<Value> result = CompileRun("func();");
+ CHECK_EQ(v8::Integer::New(17, isolate), result);
+ // Verify function not cached
+ int serial_number =
+ i::Smi::cast(v8::Utils::OpenHandle(*func)
+ ->shared()->get_api_func_data()->serial_number())->value();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::Object* elm = i_isolate->native_context()->function_cache()
+ ->GetElementNoExceptionThrown(i_isolate, serial_number);
+ CHECK(elm->IsNull());
+}
+
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index cac162e018..1a4c1ae369 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -1439,4 +1439,75 @@ TEST(17) {
}
+TEST(code_relative_offset) {
+ // Test extracting the offset of a label from the beginning of the code
+ // in a register.
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ HandleScope scope(isolate);
+ // Initialize a code object that will contain the code.
+ Handle<Object> code_object(isolate->heap()->undefined_value(), isolate);
+
+ Assembler assm(isolate, NULL, 0);
+
+ Label start, target_away, target_faraway;
+
+ __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit());
+
+ // r3 is used as the address zero, the test will crash when we load it.
+ __ mov(r3, Operand::Zero());
+
+ // r5 will be a pointer to the start of the code.
+ __ mov(r5, Operand(code_object));
+ __ mov_label_offset(r4, &start);
+
+ __ mov_label_offset(r1, &target_faraway);
+ __ str(r1, MemOperand(sp, kPointerSize, NegPreIndex));
+
+ __ mov_label_offset(r1, &target_away);
+
+ // Jump straight to 'target_away' the first time and use the relative
+ // position the second time. This covers the case when extracting the
+ // position of a label which is linked.
+ __ mov(r2, Operand::Zero());
+ __ bind(&start);
+ __ cmp(r2, Operand::Zero());
+ __ b(eq, &target_away);
+ __ add(pc, r5, r1);
+ // Emit invalid instructions to push the label between 2^8 and 2^16
+ // instructions away. The test will crash if they are reached.
+ for (int i = 0; i < (1 << 10); i++) {
+ __ ldr(r3, MemOperand(r3));
+ }
+ __ bind(&target_away);
+ // This will be hit twice: r0 = r0 + 5 + 5.
+ __ add(r0, r0, Operand(5));
+
+ __ ldr(r1, MemOperand(sp, kPointerSize, PostIndex), ne);
+ __ add(pc, r5, r4, LeaveCC, ne);
+
+ __ mov(r2, Operand(1));
+ __ b(&start);
+ // Emit invalid instructions to push the label between 2^16 and 2^24
+ // instructions away. The test will crash if they are reached.
+ for (int i = 0; i < (1 << 21); i++) {
+ __ ldr(r3, MemOperand(r3));
+ }
+ __ bind(&target_faraway);
+ // r0 = r0 + 5 + 5 + 11
+ __ add(r0, r0, Operand(11));
+
+ __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit());
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(desc,
+ Code::ComputeFlags(Code::STUB), code_object);
+ CHECK(code->IsCode());
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 21, 0, 0, 0, 0));
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(42, res);
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc
index d5aaf4f212..f7d2311192 100644
--- a/deps/v8/test/cctest/test-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-assembler-x64.cc
@@ -90,7 +90,6 @@ 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,
@@ -113,7 +112,6 @@ 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,
@@ -146,7 +144,6 @@ 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,
@@ -169,7 +166,6 @@ 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,
@@ -198,7 +194,6 @@ 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,
@@ -233,7 +228,6 @@ 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,
@@ -263,7 +257,6 @@ 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,
diff --git a/deps/v8/test/cctest/test-circular-queue.cc b/deps/v8/test/cctest/test-circular-queue.cc
index 4d7856e276..c900be1a64 100644
--- a/deps/v8/test/cctest/test-circular-queue.cc
+++ b/deps/v8/test/cctest/test-circular-queue.cc
@@ -35,77 +35,76 @@ using i::SamplingCircularQueue;
TEST(SamplingCircularQueue) {
- typedef SamplingCircularQueue::Cell Record;
- const int kRecordsPerChunk = 4;
- SamplingCircularQueue scq(sizeof(Record),
- kRecordsPerChunk * sizeof(Record),
- 3);
+ typedef i::AtomicWord Record;
+ const int kMaxRecordsInQueue = 4;
+ SamplingCircularQueue<Record, kMaxRecordsInQueue> scq;
// Check that we are using non-reserved values.
// Fill up the first chunk.
- CHECK_EQ(NULL, scq.StartDequeue());
- for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.Enqueue());
+ CHECK_EQ(NULL, scq.Peek());
+ for (Record i = 1; i < 1 + kMaxRecordsInQueue; ++i) {
+ Record* rec = reinterpret_cast<Record*>(scq.StartEnqueue());
CHECK_NE(NULL, rec);
*rec = i;
- CHECK_EQ(NULL, scq.StartDequeue());
+ scq.FinishEnqueue();
}
- // Fill up the second chunk. Consumption must still be unavailable.
- CHECK_EQ(NULL, scq.StartDequeue());
- for (Record i = 10; i < 10 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.Enqueue());
+ // The queue is full, enqueue is not allowed.
+ CHECK_EQ(NULL, scq.StartEnqueue());
+
+ // Try to enqueue when the the queue is full. Consumption must be available.
+ CHECK_NE(NULL, scq.Peek());
+ for (int i = 0; i < 10; ++i) {
+ Record* rec = reinterpret_cast<Record*>(scq.StartEnqueue());
+ CHECK_EQ(NULL, rec);
+ CHECK_NE(NULL, scq.Peek());
+ }
+
+ // Consume all records.
+ for (Record i = 1; i < 1 + kMaxRecordsInQueue; ++i) {
+ Record* rec = reinterpret_cast<Record*>(scq.Peek());
CHECK_NE(NULL, rec);
- *rec = i;
- CHECK_EQ(NULL, scq.StartDequeue());
+ CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
+ CHECK_EQ(rec, reinterpret_cast<Record*>(scq.Peek()));
+ scq.Remove();
+ CHECK_NE(rec, reinterpret_cast<Record*>(scq.Peek()));
}
+ // The queue is empty.
+ CHECK_EQ(NULL, scq.Peek());
- Record* rec = reinterpret_cast<Record*>(scq.Enqueue());
- CHECK_NE(NULL, rec);
- *rec = 20;
- // Now as we started filling up the third chunk, consumption
- // must become possible.
- CHECK_NE(NULL, scq.StartDequeue());
- // Consume the first chunk.
- for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
+ CHECK_EQ(NULL, scq.Peek());
+ for (Record i = 0; i < kMaxRecordsInQueue / 2; ++i) {
+ Record* rec = reinterpret_cast<Record*>(scq.StartEnqueue());
CHECK_NE(NULL, rec);
- CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
- CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
- scq.FinishDequeue();
- CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
+ *rec = i;
+ scq.FinishEnqueue();
}
- // Now consumption must not be possible, as consumer now polls
- // the first chunk for emptinness.
- CHECK_EQ(NULL, scq.StartDequeue());
-
- scq.FlushResidualRecords();
- // From now, consumer no more polls ahead of the current chunk,
- // so it's possible to consume the second chunk.
- CHECK_NE(NULL, scq.StartDequeue());
- // Consume the second chunk
- for (Record i = 10; i < 10 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
+
+ // Consume all available kMaxRecordsInQueue / 2 records.
+ CHECK_NE(NULL, scq.Peek());
+ for (Record i = 0; i < kMaxRecordsInQueue / 2; ++i) {
+ Record* rec = reinterpret_cast<Record*>(scq.Peek());
CHECK_NE(NULL, rec);
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
- CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
- scq.FinishDequeue();
- CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
+ CHECK_EQ(rec, reinterpret_cast<Record*>(scq.Peek()));
+ scq.Remove();
+ CHECK_NE(rec, reinterpret_cast<Record*>(scq.Peek()));
}
- // Consumption must still be possible as the first cell of the
- // last chunk is not clean.
- CHECK_NE(NULL, scq.StartDequeue());
+
+ // The queue is empty.
+ CHECK_EQ(NULL, scq.Peek());
}
namespace {
+typedef i::AtomicWord Record;
+typedef SamplingCircularQueue<Record, 12> TestSampleQueue;
+
class ProducerThread: public i::Thread {
public:
- typedef SamplingCircularQueue::Cell Record;
-
- ProducerThread(SamplingCircularQueue* scq,
+ ProducerThread(TestSampleQueue* scq,
int records_per_chunk,
Record value,
i::Semaphore* finished)
@@ -117,16 +116,17 @@ class ProducerThread: public i::Thread {
virtual void Run() {
for (Record i = value_; i < value_ + records_per_chunk_; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq_->Enqueue());
+ Record* rec = reinterpret_cast<Record*>(scq_->StartEnqueue());
CHECK_NE(NULL, rec);
*rec = i;
+ scq_->FinishEnqueue();
}
finished_->Signal();
}
private:
- SamplingCircularQueue* scq_;
+ TestSampleQueue* scq_;
const int records_per_chunk_;
Record value_;
i::Semaphore* finished_;
@@ -140,58 +140,49 @@ TEST(SamplingCircularQueueMultithreading) {
// to the case of profiling under Linux, where signal handler that
// does sampling is called in the context of different VM threads.
- typedef ProducerThread::Record Record;
const int kRecordsPerChunk = 4;
- SamplingCircularQueue scq(sizeof(Record),
- kRecordsPerChunk * sizeof(Record),
- 3);
- i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
- // Don't poll ahead, making possible to check data in the buffer
- // immediately after enqueuing.
- scq.FlushResidualRecords();
+ TestSampleQueue scq;
+ i::Semaphore semaphore(0);
- // Check that we are using non-reserved values.
- ProducerThread producer1(&scq, kRecordsPerChunk, 1, semaphore);
- ProducerThread producer2(&scq, kRecordsPerChunk, 10, semaphore);
- ProducerThread producer3(&scq, kRecordsPerChunk, 20, semaphore);
+ ProducerThread producer1(&scq, kRecordsPerChunk, 1, &semaphore);
+ ProducerThread producer2(&scq, kRecordsPerChunk, 10, &semaphore);
+ ProducerThread producer3(&scq, kRecordsPerChunk, 20, &semaphore);
- CHECK_EQ(NULL, scq.StartDequeue());
+ CHECK_EQ(NULL, scq.Peek());
producer1.Start();
- semaphore->Wait();
+ semaphore.Wait();
for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
+ Record* rec = reinterpret_cast<Record*>(scq.Peek());
CHECK_NE(NULL, rec);
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
- CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
- scq.FinishDequeue();
- CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
+ CHECK_EQ(rec, reinterpret_cast<Record*>(scq.Peek()));
+ scq.Remove();
+ CHECK_NE(rec, reinterpret_cast<Record*>(scq.Peek()));
}
- CHECK_EQ(NULL, scq.StartDequeue());
+ CHECK_EQ(NULL, scq.Peek());
producer2.Start();
- semaphore->Wait();
+ semaphore.Wait();
for (Record i = 10; i < 10 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
+ Record* rec = reinterpret_cast<Record*>(scq.Peek());
CHECK_NE(NULL, rec);
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
- CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
- scq.FinishDequeue();
- CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
+ CHECK_EQ(rec, reinterpret_cast<Record*>(scq.Peek()));
+ scq.Remove();
+ CHECK_NE(rec, reinterpret_cast<Record*>(scq.Peek()));
}
- CHECK_EQ(NULL, scq.StartDequeue());
+ CHECK_EQ(NULL, scq.Peek());
producer3.Start();
- semaphore->Wait();
+ semaphore.Wait();
for (Record i = 20; i < 20 + kRecordsPerChunk; ++i) {
- Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
+ Record* rec = reinterpret_cast<Record*>(scq.Peek());
CHECK_NE(NULL, rec);
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
- CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
- scq.FinishDequeue();
- CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
+ CHECK_EQ(rec, reinterpret_cast<Record*>(scq.Peek()));
+ scq.Remove();
+ CHECK_NE(rec, reinterpret_cast<Record*>(scq.Peek()));
}
- CHECK_EQ(NULL, scq.StartDequeue());
-
- delete semaphore;
+ CHECK_EQ(NULL, scq.Peek());
}
diff --git a/deps/v8/test/cctest/test-code-stubs-arm.cc b/deps/v8/test/cctest/test-code-stubs-arm.cc
new file mode 100644
index 0000000000..c99433edad
--- /dev/null
+++ b/deps/v8/test/cctest/test-code-stubs-arm.cc
@@ -0,0 +1,185 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Rrdistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Rrdistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Rrdistributions 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 "cctest.h"
+#include "code-stubs.h"
+#include "test-code-stubs.h"
+#include "factory.h"
+#include "macro-assembler.h"
+#include "platform.h"
+#include "simulator.h"
+
+using namespace v8::internal;
+
+#define __ masm.
+
+ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
+ Register source_reg,
+ Register destination_reg,
+ bool inline_fastpath) {
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+ &actual_size,
+ true));
+ CHECK(buffer);
+ HandleScope handles(isolate);
+ MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size));
+ masm.set_allow_stub_calls(false);
+ DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath);
+
+ byte* start = stub.GetCode(isolate)->instruction_start();
+ Label done;
+
+ // Save callee save registers.
+ __ Push(r7, r6, r5, r4);
+ __ Push(lr);
+
+ // For softfp, move the input value into d0.
+ if (!masm.use_eabi_hardfloat()) {
+ __ vmov(d0, r0, r1);
+ }
+ // Push the double argument.
+ __ sub(sp, sp, Operand(kDoubleSize));
+ __ vstr(d0, sp, 0);
+ if (!source_reg.is(sp)) {
+ __ mov(source_reg, sp);
+ }
+
+ // Save registers make sure they don't get clobbered.
+ int source_reg_offset = kDoubleSize;
+ int reg_num = 0;
+ for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
+ Register reg = Register::from_code(reg_num);
+ if (!reg.is(destination_reg)) {
+ __ push(reg);
+ source_reg_offset += kPointerSize;
+ }
+ }
+
+ // Re-push the double argument.
+ __ sub(sp, sp, Operand(kDoubleSize));
+ __ vstr(d0, sp, 0);
+
+ // Call through to the actual stub
+ if (inline_fastpath) {
+ __ vldr(d0, MemOperand(source_reg));
+ __ TryInlineTruncateDoubleToI(destination_reg, d0, &done);
+ if (destination_reg.is(source_reg) && !source_reg.is(sp)) {
+ // Restore clobbered source_reg.
+ __ add(source_reg, sp, Operand(source_reg_offset));
+ }
+ }
+ __ Call(start, RelocInfo::EXTERNAL_REFERENCE);
+ __ bind(&done);
+
+ __ add(sp, sp, Operand(kDoubleSize));
+
+ // Make sure no registers have been unexpectedly clobbered
+ for (--reg_num; reg_num >= 0; --reg_num) {
+ Register reg = Register::from_code(reg_num);
+ if (!reg.is(destination_reg)) {
+ __ ldr(ip, MemOperand(sp, 0));
+ __ cmp(reg, ip);
+ __ Assert(eq, kRegisterWasClobbered);
+ __ add(sp, sp, Operand(kPointerSize));
+ }
+ }
+
+ __ add(sp, sp, Operand(kDoubleSize));
+
+ if (!destination_reg.is(r0))
+ __ mov(r0, destination_reg);
+
+ // Restore callee save registers.
+ __ Pop(lr);
+ __ Pop(r7, r6, r5, r4);
+
+ __ Ret(0);
+
+ CodeDesc desc;
+ masm.GetCode(&desc);
+ CPU::FlushICache(buffer, actual_size);
+ return (reinterpret_cast<ConvertDToIFunc>(
+ reinterpret_cast<intptr_t>(buffer)));
+}
+
+#undef __
+
+
+static Isolate* GetIsolateFrom(LocalContext* context) {
+ return reinterpret_cast<Isolate*>((*context)->GetIsolate());
+}
+
+
+int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
+ double from) {
+#ifdef USE_SIMULATOR
+ return reinterpret_cast<int32_t>(CALL_GENERATED_CODE(func, from, 0, 0, 0, 0));
+#else
+ return (*func)(from);
+#endif
+}
+
+
+TEST(ConvertDToI) {
+ CcTest::InitializeVM();
+ LocalContext context;
+ Isolate* isolate = GetIsolateFrom(&context);
+ HandleScope scope(isolate);
+
+#if DEBUG
+ // Verify that the tests actually work with the C version. In the release
+ // code, the compiler optimizes it away because it's all constant, but does it
+ // wrong, triggering an assert on gcc.
+ RunAllTruncationTests(&ConvertDToICVersion);
+#endif
+
+ Register source_registers[] = {sp, r0, r1, r2, r3, r4, r5, r6, r7};
+ Register dest_registers[] = {r0, r1, r2, r3, r4, r5, r6, r7};
+
+ for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) {
+ for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) {
+ RunAllTruncationTests(
+ RunGeneratedCodeCallWrapper,
+ MakeConvertDToIFuncTrampoline(isolate,
+ source_registers[s],
+ dest_registers[d],
+ false));
+ RunAllTruncationTests(
+ RunGeneratedCodeCallWrapper,
+ MakeConvertDToIFuncTrampoline(isolate,
+ source_registers[s],
+ dest_registers[d],
+ true));
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/test-code-stubs-ia32.cc b/deps/v8/test/cctest/test-code-stubs-ia32.cc
index a3c0b54e25..3f621758e3 100644
--- a/deps/v8/test/cctest/test-code-stubs-ia32.cc
+++ b/deps/v8/test/cctest/test-code-stubs-ia32.cc
@@ -136,46 +136,15 @@ TEST(ConvertDToI) {
RunAllTruncationTests(&ConvertDToICVersion);
#endif
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esp, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esp, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esp, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esp, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esp, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esp, esi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, eax, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, eax, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, eax, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, eax, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, eax, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, eax, esi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ebx, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ebx, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ebx, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ebx, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ebx, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ebx, esi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ecx, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ecx, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ecx, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ecx, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ecx, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, ecx, esi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edx, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edx, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edx, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edx, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edx, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edx, esi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esi, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esi, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esi, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esi, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esi, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, esi, esi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edi, eax));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edi, ebx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edi, ecx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edi, edx));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edi, edi));
- RunAllTruncationTests(MakeConvertDToIFuncTrampoline(isolate, edi, esi));
+ Register source_registers[] = {esp, eax, ebx, ecx, edx, edi, esi};
+ Register dest_registers[] = {eax, ebx, ecx, edx, edi, esi};
+
+ for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) {
+ for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) {
+ RunAllTruncationTests(
+ MakeConvertDToIFuncTrampoline(isolate,
+ source_registers[s],
+ dest_registers[d]));
+ }
+ }
}
diff --git a/deps/v8/test/cctest/test-code-stubs-x64.cc b/deps/v8/test/cctest/test-code-stubs-x64.cc
index 0bffb87fef..4af5b45d7c 100644
--- a/deps/v8/test/cctest/test-code-stubs-x64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-x64.cc
@@ -138,8 +138,8 @@ TEST(ConvertDToI) {
Register source_registers[] = {rsp, rax, rbx, rcx, rdx, rsi, rdi, r8, r9};
Register dest_registers[] = {rax, rbx, rcx, rdx, rsi, rdi, r8, r9};
- for (size_t s = 0; s < sizeof(*source_registers); s++) {
- for (size_t d = 0; d < sizeof(*dest_registers); d++) {
+ for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) {
+ for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) {
RunAllTruncationTests(
MakeConvertDToIFuncTrampoline(isolate,
source_registers[s],
diff --git a/deps/v8/test/cctest/test-code-stubs.cc b/deps/v8/test/cctest/test-code-stubs.cc
index 405069626b..db00e9ac5a 100644
--- a/deps/v8/test/cctest/test-code-stubs.cc
+++ b/deps/v8/test/cctest/test-code-stubs.cc
@@ -42,8 +42,9 @@ using namespace v8::internal;
int STDCALL ConvertDToICVersion(double d) {
- Address double_ptr = reinterpret_cast<Address>(&d);
- uint32_t exponent_bits = Memory::uint32_at(double_ptr + kDoubleSize / 2);
+ union { double d; uint32_t u[2]; } dbl;
+ dbl.d = d;
+ uint32_t exponent_bits = dbl.u[1];
int32_t shifted_mask = static_cast<int32_t>(Double::kExponentMask >> 32);
int32_t exponent = (((exponent_bits & shifted_mask) >>
(Double::kPhysicalSignificandSize - 32)) -
@@ -54,8 +55,7 @@ int STDCALL ConvertDToICVersion(double d) {
static_cast<uint32_t>(Double::kPhysicalSignificandSize);
if (unsigned_exponent >= max_exponent) {
if ((exponent - Double::kPhysicalSignificandSize) < 32) {
- result = Memory::uint32_at(double_ptr) <<
- (exponent - Double::kPhysicalSignificandSize);
+ result = dbl.u[0] << (exponent - Double::kPhysicalSignificandSize);
}
} else {
uint64_t big_result =
@@ -71,22 +71,37 @@ int STDCALL ConvertDToICVersion(double d) {
}
-void RunOneTruncationTestWithTest(ConvertDToIFunc func,
+void RunOneTruncationTestWithTest(ConvertDToICallWrapper callWrapper,
+ ConvertDToIFunc func,
double from,
double raw) {
uint64_t to = static_cast<int64_t>(raw);
- int result = (*func)(from);
+ int result = (*callWrapper)(func, from);
CHECK_EQ(static_cast<int>(to), result);
}
+int32_t DefaultCallWrapper(ConvertDToIFunc func,
+ double from) {
+ return (*func)(from);
+}
+
+
// #define NaN and Infinity so that it's possible to cut-and-paste these tests
// directly to a .js file and run them.
#define NaN (OS::nan_value())
#define Infinity (std::numeric_limits<double>::infinity())
-#define RunOneTruncationTest(p1, p2) RunOneTruncationTestWithTest(func, p1, p2)
+#define RunOneTruncationTest(p1, p2) \
+ RunOneTruncationTestWithTest(callWrapper, func, p1, p2)
+
void RunAllTruncationTests(ConvertDToIFunc func) {
+ RunAllTruncationTests(DefaultCallWrapper, func);
+}
+
+
+void RunAllTruncationTests(ConvertDToICallWrapper callWrapper,
+ ConvertDToIFunc func) {
RunOneTruncationTest(0, 0);
RunOneTruncationTest(0.5, 0);
RunOneTruncationTest(-0.5, 0);
diff --git a/deps/v8/test/cctest/test-code-stubs.h b/deps/v8/test/cctest/test-code-stubs.h
index eab8e63b2a..910e0d1701 100644
--- a/deps/v8/test/cctest/test-code-stubs.h
+++ b/deps/v8/test/cctest/test-code-stubs.h
@@ -41,8 +41,13 @@
typedef int32_t STDCALL ConvertDToIFuncType(double input);
typedef ConvertDToIFuncType* ConvertDToIFunc;
+typedef int32_t ConvertDToICallWrapperType(ConvertDToIFunc func, double from);
+typedef ConvertDToICallWrapperType* ConvertDToICallWrapper;
+
int STDCALL ConvertDToICVersion(double d);
void RunAllTruncationTests(ConvertDToIFunc func);
+void RunAllTruncationTests(ConvertDToICallWrapper callWrapper,
+ ConvertDToIFunc func);
#endif
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index b5ba46c4cb..7e87e10991 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -116,7 +116,7 @@ static Handle<JSFunction> Compile(const char* source) {
}
-static double Inc(int x) {
+static double Inc(Isolate* isolate, int x) {
const char* source = "result = %d + 1;";
EmbeddedVector<char, 512> buffer;
OS::SNPrintF(buffer, source, x);
@@ -125,8 +125,8 @@ static double Inc(int x) {
if (fun.is_null()) return -1;
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(isolate->context()->global_object());
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
}
@@ -135,19 +135,19 @@ static double Inc(int x) {
TEST(Inc) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- CHECK_EQ(4.0, Inc(3));
+ CHECK_EQ(4.0, Inc(CcTest::i_isolate(), 3));
}
-static double Add(int x, int y) {
+static double Add(Isolate* isolate, int x, int y) {
Handle<JSFunction> fun = Compile("result = x + y;");
if (fun.is_null()) return -1;
SetGlobalProperty("x", Smi::FromInt(x));
SetGlobalProperty("y", Smi::FromInt(y));
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(isolate->context()->global_object());
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
}
@@ -156,18 +156,18 @@ static double Add(int x, int y) {
TEST(Add) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- CHECK_EQ(5.0, Add(2, 3));
+ CHECK_EQ(5.0, Add(CcTest::i_isolate(), 2, 3));
}
-static double Abs(int x) {
+static double Abs(Isolate* isolate, int x) {
Handle<JSFunction> fun = Compile("if (x < 0) result = -x; else result = x;");
if (fun.is_null()) return -1;
SetGlobalProperty("x", Smi::FromInt(x));
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(isolate->context()->global_object());
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
}
@@ -176,19 +176,19 @@ static double Abs(int x) {
TEST(Abs) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- CHECK_EQ(3.0, Abs(-3));
+ CHECK_EQ(3.0, Abs(CcTest::i_isolate(), -3));
}
-static double Sum(int n) {
+static double Sum(Isolate* isolate, int n) {
Handle<JSFunction> fun =
Compile("s = 0; while (n > 0) { s += n; n -= 1; }; result = s;");
if (fun.is_null()) return -1;
SetGlobalProperty("n", Smi::FromInt(n));
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(isolate->context()->global_object());
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
return GetGlobalProperty("result")->ToObjectChecked()->Number();
}
@@ -197,7 +197,7 @@ static double Sum(int n) {
TEST(Sum) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- CHECK_EQ(5050.0, Sum(100));
+ CHECK_EQ(5050.0, Sum(CcTest::i_isolate(), 100));
}
@@ -208,8 +208,9 @@ TEST(Print) {
Handle<JSFunction> fun = Compile(source);
if (fun.is_null()) return;
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(CcTest::i_isolate()->context()->global_object());
+ Execution::Call(
+ CcTest::i_isolate(), fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
}
@@ -241,8 +242,9 @@ TEST(Stuff) {
Handle<JSFunction> fun = Compile(source);
CHECK(!fun.is_null());
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(CcTest::i_isolate()->context()->global_object());
+ Execution::Call(
+ CcTest::i_isolate(), fun, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
CHECK_EQ(511.0, GetGlobalProperty("r")->ToObjectChecked()->Number());
}
@@ -258,7 +260,7 @@ TEST(UncaughtThrow) {
bool has_pending_exception;
Isolate* isolate = fun->GetIsolate();
Handle<JSObject> global(isolate->context()->global_object());
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
CHECK(has_pending_exception);
CHECK_EQ(42.0, isolate->pending_exception()->ToObjectChecked()->Number());
}
@@ -282,8 +284,9 @@ TEST(C2JSFrames) {
// Run the generated code to populate the global object with 'foo'.
bool has_pending_exception;
- Handle<JSObject> global(Isolate::Current()->context()->global_object());
- Execution::Call(fun0, global, 0, NULL, &has_pending_exception);
+ Handle<JSObject> global(isolate->context()->global_object());
+ Execution::Call(
+ isolate, fun0, global, 0, NULL, &has_pending_exception);
CHECK(!has_pending_exception);
Object* foo_string = isolate->factory()->InternalizeOneByteString(
@@ -295,7 +298,8 @@ TEST(C2JSFrames) {
Handle<Object> argv[] = { isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("hello")) };
- Execution::Call(Handle<JSFunction>::cast(fun1),
+ Execution::Call(isolate,
+ Handle<JSFunction>::cast(fun1),
global,
ARRAY_SIZE(argv),
argv,
diff --git a/deps/v8/test/cctest/test-condition-variable.cc b/deps/v8/test/cctest/test-condition-variable.cc
new file mode 100644
index 0000000000..a7bd6500dc
--- /dev/null
+++ b/deps/v8/test/cctest/test-condition-variable.cc
@@ -0,0 +1,304 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "platform/condition-variable.h"
+#include "platform/time.h"
+
+using namespace ::v8::internal;
+
+
+TEST(WaitForAfterNofityOnSameThread) {
+ for (int n = 0; n < 10; ++n) {
+ Mutex mutex;
+ ConditionVariable cv;
+
+ LockGuard<Mutex> lock_guard(&mutex);
+
+ cv.NotifyOne();
+ CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+
+ cv.NotifyAll();
+ CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+ }
+}
+
+
+class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread {
+ public:
+ ThreadWithMutexAndConditionVariable()
+ : Thread("ThreadWithMutexAndConditionVariable"),
+ running_(false), finished_(false) {}
+ virtual ~ThreadWithMutexAndConditionVariable() {}
+
+ virtual void Run() V8_OVERRIDE {
+ LockGuard<Mutex> lock_guard(&mutex_);
+ running_ = true;
+ cv_.NotifyOne();
+ while (running_) {
+ cv_.Wait(&mutex_);
+ }
+ finished_ = true;
+ cv_.NotifyAll();
+ }
+
+ bool running_;
+ bool finished_;
+ ConditionVariable cv_;
+ Mutex mutex_;
+};
+
+
+TEST(MultipleThreadsWithSeparateConditionVariables) {
+ static const int kThreadCount = 128;
+ ThreadWithMutexAndConditionVariable threads[kThreadCount];
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(!threads[n].running_);
+ CHECK(!threads[n].finished_);
+ threads[n].Start();
+ // Wait for nth thread to start.
+ while (!threads[n].running_) {
+ threads[n].cv_.Wait(&threads[n].mutex_);
+ }
+ }
+
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(threads[n].running_);
+ CHECK(!threads[n].finished_);
+ }
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(threads[n].running_);
+ CHECK(!threads[n].finished_);
+ // Tell the nth thread to quit.
+ threads[n].running_ = false;
+ threads[n].cv_.NotifyOne();
+ }
+
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ // Wait for nth thread to quit.
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ while (!threads[n].finished_) {
+ threads[n].cv_.Wait(&threads[n].mutex_);
+ }
+ CHECK(!threads[n].running_);
+ CHECK(threads[n].finished_);
+ }
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].Join();
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(!threads[n].running_);
+ CHECK(threads[n].finished_);
+ }
+}
+
+
+class ThreadWithSharedMutexAndConditionVariable V8_FINAL : public Thread {
+ public:
+ ThreadWithSharedMutexAndConditionVariable()
+ : Thread("ThreadWithSharedMutexAndConditionVariable"),
+ running_(false), finished_(false), cv_(NULL), mutex_(NULL) {}
+ virtual ~ThreadWithSharedMutexAndConditionVariable() {}
+
+ virtual void Run() V8_OVERRIDE {
+ LockGuard<Mutex> lock_guard(mutex_);
+ running_ = true;
+ cv_->NotifyAll();
+ while (running_) {
+ cv_->Wait(mutex_);
+ }
+ finished_ = true;
+ cv_->NotifyAll();
+ }
+
+ bool running_;
+ bool finished_;
+ ConditionVariable* cv_;
+ Mutex* mutex_;
+};
+
+
+TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
+ static const int kThreadCount = 128;
+ ThreadWithSharedMutexAndConditionVariable threads[kThreadCount];
+ ConditionVariable cv;
+ Mutex mutex;
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].mutex_ = &mutex;
+ threads[n].cv_ = &cv;
+ }
+
+ // Start all threads.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = 0; n < kThreadCount; ++n) {
+ CHECK(!threads[n].running_);
+ CHECK(!threads[n].finished_);
+ threads[n].Start();
+ }
+ }
+
+ // Wait for all threads to start.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ while (!threads[n].running_) {
+ cv.Wait(&mutex);
+ }
+ }
+ }
+
+ // Make sure that all threads are running.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = 0; n < kThreadCount; ++n) {
+ CHECK(threads[n].running_);
+ CHECK(!threads[n].finished_);
+ }
+ }
+
+ // Tell all threads to quit.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ CHECK(threads[n].running_);
+ CHECK(!threads[n].finished_);
+ // Tell the nth thread to quit.
+ threads[n].running_ = false;
+ }
+ cv.NotifyAll();
+ }
+
+ // Wait for all threads to quit.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = 0; n < kThreadCount; ++n) {
+ while (!threads[n].finished_) {
+ cv.Wait(&mutex);
+ }
+ }
+ }
+
+ // Make sure all threads are finished.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ CHECK(!threads[n].running_);
+ CHECK(threads[n].finished_);
+ }
+ }
+
+ // Join all threads.
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].Join();
+ }
+}
+
+
+class LoopIncrementThread V8_FINAL : public Thread {
+ public:
+ LoopIncrementThread(int rem,
+ int* counter,
+ int limit,
+ int thread_count,
+ ConditionVariable* cv,
+ Mutex* mutex)
+ : Thread("LoopIncrementThread"), rem_(rem), counter_(counter),
+ limit_(limit), thread_count_(thread_count), cv_(cv), mutex_(mutex) {
+ CHECK_LT(rem, thread_count);
+ CHECK_EQ(0, limit % thread_count);
+ }
+
+ virtual void Run() V8_OVERRIDE {
+ int last_count = -1;
+ while (true) {
+ LockGuard<Mutex> lock_guard(mutex_);
+ int count = *counter_;
+ while (count % thread_count_ != rem_ && count < limit_) {
+ cv_->Wait(mutex_);
+ count = *counter_;
+ }
+ if (count >= limit_) break;
+ CHECK_EQ(*counter_, count);
+ if (last_count != -1) {
+ CHECK_EQ(last_count + (thread_count_ - 1), count);
+ }
+ count++;
+ *counter_ = count;
+ last_count = count;
+ cv_->NotifyAll();
+ }
+ }
+
+ private:
+ const int rem_;
+ int* counter_;
+ const int limit_;
+ const int thread_count_;
+ ConditionVariable* cv_;
+ Mutex* mutex_;
+};
+
+
+TEST(LoopIncrement) {
+ static const int kMaxThreadCount = 16;
+ Mutex mutex;
+ ConditionVariable cv;
+ for (int thread_count = 1; thread_count < kMaxThreadCount; ++thread_count) {
+ int limit = thread_count * 100;
+ int counter = 0;
+
+ // Setup the threads.
+ Thread** threads = new Thread*[thread_count];
+ for (int n = 0; n < thread_count; ++n) {
+ threads[n] = new LoopIncrementThread(
+ n, &counter, limit, thread_count, &cv, &mutex);
+ }
+
+ // Start all threads.
+ for (int n = thread_count - 1; n >= 0; --n) {
+ threads[n]->Start();
+ }
+
+ // Join and cleanup all threads.
+ for (int n = 0; n < thread_count; ++n) {
+ threads[n]->Join();
+ delete threads[n];
+ }
+ delete[] threads;
+
+ CHECK_EQ(limit, counter);
+ }
+}
diff --git a/deps/v8/test/cctest/test-cpu-ia32.cc b/deps/v8/test/cctest/test-cpu-ia32.cc
new file mode 100644
index 0000000000..245450bf92
--- /dev/null
+++ b/deps/v8/test/cctest/test-cpu-ia32.cc
@@ -0,0 +1,40 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "cpu.h"
+
+using namespace v8::internal;
+
+
+TEST(RequiredFeaturesX64) {
+ // Test for the features required by every x86 CPU in compat/legacy mode.
+ CPU cpu;
+ CHECK(cpu.has_sahf());
+}
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index 7b5fc2b0fe..4708f506d2 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -31,6 +31,7 @@
#include "cpu-profiler-inl.h"
#include "cctest.h"
#include "platform.h"
+#include "smart-pointers.h"
#include "utils.h"
#include "../include/v8-profiler.h"
using i::CodeEntry;
@@ -42,16 +43,19 @@ using i::ProfileGenerator;
using i::ProfileNode;
using i::ProfilerEventsProcessor;
using i::ScopedVector;
+using i::SmartPointer;
+using i::TimeDelta;
using i::Vector;
TEST(StartStop) {
- CpuProfilesCollection profiles;
+ i::Isolate* isolate = CcTest::i_isolate();
+ CpuProfilesCollection profiles(isolate->heap());
ProfileGenerator generator(&profiles);
- ProfilerEventsProcessor processor(&generator);
- processor.Start();
- processor.StopSynchronously();
- processor.Join();
+ SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
+ &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ processor->Start();
+ processor->StopSynchronously();
}
@@ -63,7 +67,7 @@ static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
i::Address frame1,
i::Address frame2 = NULL,
i::Address frame3 = NULL) {
- i::TickSample* sample = proc->TickSampleEvent();
+ i::TickSample* sample = proc->StartTickSample();
sample->pc = frame1;
sample->tos = frame1;
sample->frames_count = 0;
@@ -75,6 +79,7 @@ static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
sample->stack[1] = frame3;
sample->frames_count = 2;
}
+ proc->FinishTickSample();
}
namespace {
@@ -136,12 +141,13 @@ TEST(CodeEvents) {
i::Code* args3_code = CreateCode(&env);
i::Code* args4_code = CreateCode(&env);
- CpuProfilesCollection* profiles = new CpuProfilesCollection;
+ CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap());
profiles->StartProfiling("", 1, false);
ProfileGenerator generator(profiles);
- ProfilerEventsProcessor processor(&generator);
- processor.Start();
- CpuProfiler profiler(isolate, profiles, &generator, &processor);
+ SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
+ &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ processor->Start();
+ CpuProfiler profiler(isolate, profiles, &generator, *processor);
// Enqueue code creation events.
const char* aaa_str = "aaa";
@@ -156,10 +162,9 @@ TEST(CodeEvents) {
profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4);
// Enqueue a tick event to enable code events processing.
- EnqueueTickSampleEvent(&processor, aaa_code->address());
+ EnqueueTickSampleEvent(*processor, aaa_code->address());
- processor.StopSynchronously();
- processor.Join();
+ processor->StopSynchronously();
// Check the state of profile generator.
CodeEntry* aaa = generator.code_map()->FindEntry(aaa_code->address());
@@ -198,30 +203,30 @@ TEST(TickEvents) {
i::Code* frame2_code = CreateCode(&env);
i::Code* frame3_code = CreateCode(&env);
- CpuProfilesCollection* profiles = new CpuProfilesCollection;
+ CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap());
profiles->StartProfiling("", 1, false);
ProfileGenerator generator(profiles);
- ProfilerEventsProcessor processor(&generator);
- processor.Start();
- CpuProfiler profiler(isolate, profiles, &generator, &processor);
+ SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
+ &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ processor->Start();
+ CpuProfiler profiler(isolate, profiles, &generator, *processor);
profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb");
profiler.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5);
profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame3_code, "ddd");
- EnqueueTickSampleEvent(&processor, frame1_code->instruction_start());
+ EnqueueTickSampleEvent(*processor, frame1_code->instruction_start());
EnqueueTickSampleEvent(
- &processor,
+ *processor,
frame2_code->instruction_start() + frame2_code->ExecutableSize() / 2,
frame1_code->instruction_start() + frame2_code->ExecutableSize() / 2);
EnqueueTickSampleEvent(
- &processor,
+ *processor,
frame3_code->instruction_end() - 1,
frame2_code->instruction_end() - 1,
frame1_code->instruction_end() - 1);
- processor.StopSynchronously();
- processor.Join();
+ processor->StopSynchronously();
CpuProfile* profile = profiles->StopProfiling("");
CHECK_NE(NULL, profile);
@@ -267,25 +272,26 @@ TEST(Issue1398) {
i::Code* code = CreateCode(&env);
- CpuProfilesCollection* profiles = new CpuProfilesCollection;
+ CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap());
profiles->StartProfiling("", 1, false);
ProfileGenerator generator(profiles);
- ProfilerEventsProcessor processor(&generator);
- processor.Start();
- CpuProfiler profiler(isolate, profiles, &generator, &processor);
+ SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
+ &generator, NULL, TimeDelta::FromMicroseconds(100)));
+ processor->Start();
+ CpuProfiler profiler(isolate, profiles, &generator, *processor);
profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb");
- i::TickSample* sample = processor.TickSampleEvent();
+ i::TickSample* sample = processor->StartTickSample();
sample->pc = code->address();
sample->tos = 0;
sample->frames_count = i::TickSample::kMaxFramesCount;
for (int i = 0; i < sample->frames_count; ++i) {
sample->stack[i] = code->address();
}
+ processor->FinishTickSample();
- processor.StopSynchronously();
- processor.Join();
+ processor->StopSynchronously();
CpuProfile* profile = profiles->StopProfiling("");
CHECK_NE(NULL, profile);
@@ -415,13 +421,10 @@ TEST(ProfileStartEndTime) {
v8::HandleScope scope(env->GetIsolate());
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
- int64_t time_before_profiling = i::OS::Ticks();
v8::Local<v8::String> profile_name = v8::String::New("test");
cpu_profiler->StartCpuProfiling(profile_name);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
- CHECK(time_before_profiling <= profile->GetStartTime());
CHECK(profile->GetStartTime() <= profile->GetEndTime());
- CHECK(profile->GetEndTime() <= i::OS::Ticks());
}
@@ -1368,13 +1371,11 @@ TEST(IdleTime) {
const v8::CpuProfileNode* programNode =
GetChild(root, ProfileGenerator::kProgramEntryName);
CHECK_EQ(0, programNode->GetChildrenCount());
- CHECK_GE(programNode->GetSelfSamplesCount(), 3);
CHECK_GE(programNode->GetHitCount(), 3);
const v8::CpuProfileNode* idleNode =
GetChild(root, ProfileGenerator::kIdleEntryName);
CHECK_EQ(0, idleNode->GetChildrenCount());
- CHECK_GE(idleNode->GetSelfSamplesCount(), 3);
CHECK_GE(idleNode->GetHitCount(), 3);
cpu_profiler->DeleteAllCpuProfiles();
diff --git a/deps/v8/test/cctest/test-cpu-x64.cc b/deps/v8/test/cctest/test-cpu-x64.cc
new file mode 100644
index 0000000000..a2c45cf862
--- /dev/null
+++ b/deps/v8/test/cctest/test-cpu-x64.cc
@@ -0,0 +1,44 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "cpu.h"
+
+using namespace v8::internal;
+
+
+TEST(RequiredFeaturesX64) {
+ // Test for the features required by every x64 CPU.
+ CPU cpu;
+ CHECK(cpu.has_fpu());
+ CHECK(cpu.has_cmov());
+ CHECK(cpu.has_mmx());
+ CHECK(cpu.has_sse());
+ CHECK(cpu.has_sse2());
+}
diff --git a/deps/v8/test/cctest/test-lock.cc b/deps/v8/test/cctest/test-cpu.cc
index d4387d0f90..06966c68c8 100644
--- a/deps/v8/test/cctest/test-lock.cc
+++ b/deps/v8/test/cctest/test-cpu.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -24,66 +24,32 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Tests of the TokenLock class from lock.h
-
-#include <stdlib.h>
#include "v8.h"
-#include "platform.h"
#include "cctest.h"
+#include "cpu.h"
+using namespace v8::internal;
-using namespace ::v8::internal;
+TEST(FeatureImplications) {
+ // Test for features implied by other features.
+ CPU cpu;
-// Simple test of locking logic
-TEST(Simple) {
- Mutex* mutex = OS::CreateMutex();
- CHECK_EQ(0, mutex->Lock()); // acquire the lock with the right token
- CHECK_EQ(0, mutex->Unlock()); // can unlock with the right token
- delete mutex;
-}
+ // ia32 and x64 features
+ CHECK(!cpu.has_sse() || cpu.has_mmx());
+ CHECK(!cpu.has_sse2() || cpu.has_sse());
+ CHECK(!cpu.has_sse3() || cpu.has_sse2());
+ CHECK(!cpu.has_ssse3() || cpu.has_sse3());
+ CHECK(!cpu.has_sse41() || cpu.has_sse3());
+ CHECK(!cpu.has_sse42() || cpu.has_sse41());
-
-TEST(MultiLock) {
- Mutex* mutex = OS::CreateMutex();
- CHECK_EQ(0, mutex->Lock());
- CHECK_EQ(0, mutex->Unlock());
- delete mutex;
+ // arm features
+ CHECK(!cpu.has_vfp3_d32() || cpu.has_vfp3());
}
-TEST(ShallowLock) {
- Mutex* mutex = OS::CreateMutex();
- CHECK_EQ(0, mutex->Lock());
- CHECK_EQ(0, mutex->Unlock());
- CHECK_EQ(0, mutex->Lock());
- CHECK_EQ(0, mutex->Unlock());
- delete mutex;
-}
-
-
-TEST(SemaphoreTimeout) {
- bool ok;
- Semaphore* sem = OS::CreateSemaphore(0);
-
- // Semaphore not signalled - timeout.
- ok = sem->Wait(0);
- CHECK(!ok);
- ok = sem->Wait(100);
- CHECK(!ok);
- ok = sem->Wait(1000);
- CHECK(!ok);
-
- // Semaphore signalled - no timeout.
- sem->Signal();
- ok = sem->Wait(0);
- sem->Signal();
- ok = sem->Wait(100);
- sem->Signal();
- ok = sem->Wait(1000);
- CHECK(ok);
- delete sem;
+TEST(NumberOfProcessorsOnline) {
+ CHECK_GT(CPU::NumberOfProcessorsOnline(), 0);
}
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 484eb8e3fb..2540a3dfe5 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -37,12 +37,19 @@
#include "compilation-cache.h"
#include "debug.h"
#include "deoptimizer.h"
+#include "frames.h"
#include "platform.h"
+#include "platform/condition-variable.h"
+#include "platform/socket.h"
#include "stub-cache.h"
#include "utils.h"
#undef V8_DISABLE_DEPRECATIONS
+using ::v8::internal::Mutex;
+using ::v8::internal::LockGuard;
+using ::v8::internal::ConditionVariable;
+using ::v8::internal::Semaphore;
using ::v8::internal::EmbeddedVector;
using ::v8::internal::Object;
using ::v8::internal::OS;
@@ -54,6 +61,7 @@ using ::v8::internal::Debug;
using ::v8::internal::Debugger;
using ::v8::internal::CommandMessage;
using ::v8::internal::CommandMessageQueue;
+using ::v8::internal::StackFrame;
using ::v8::internal::StepAction;
using ::v8::internal::StepIn; // From StepAction enum
using ::v8::internal::StepNext; // From StepAction enum
@@ -384,7 +392,7 @@ static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) {
// Prepare to step to next break location.
static void PrepareStep(StepAction step_action) {
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
- debug->PrepareStep(step_action, 1);
+ debug->PrepareStep(step_action, 1, StackFrame::NO_ID);
}
@@ -661,10 +669,11 @@ int last_source_column = -1;
// Debug event handler which counts the break points which have been hit.
int break_point_hit_count = 0;
int break_point_hit_count_deoptimize = 0;
-static void DebugEventBreakPointHitCount(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakPointHitCount(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
+ v8::Handle<v8::Object> event_data = event_details.GetEventData();
v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
Debug* debug = isolate->debug();
// When hitting a debug event listener there must be a break set.
@@ -773,10 +782,11 @@ static void DebugEventCounterClear() {
uncaught_exception_hit_count = 0;
}
-static void DebugEventCounter(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventCounter(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
+ v8::Handle<v8::Object> event_data = event_details.GetEventData();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
@@ -835,10 +845,10 @@ const char* evaluate_check_source =
v8::Local<v8::Function> evaluate_check_function;
// The actual debug event described by the longer comment above.
-static void DebugEventEvaluate(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventEvaluate(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -862,10 +872,10 @@ static void DebugEventEvaluate(v8::DebugEvent event,
// This debug event listener removes a breakpoint in a function
int debug_event_remove_break_point = 0;
-static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventRemoveBreakPoint(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Value> data = event_details.GetCallbackData();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -881,10 +891,9 @@ static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
// Debug event handler which counts break points hit and performs a step
// afterwards.
StepAction step_action = StepIn; // Step action to perform when stepping.
-static void DebugEventStep(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventStep(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -908,10 +917,10 @@ static void DebugEventStep(v8::DebugEvent event,
const char* expected_step_sequence = NULL;
// The actual debug event described by the longer comment above.
-static void DebugEventStepSequence(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventStepSequence(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -939,10 +948,8 @@ static void DebugEventStepSequence(v8::DebugEvent event,
// Debug event handler which performs a garbage collection.
static void DebugEventBreakPointCollectGarbage(
- v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -965,10 +972,9 @@ static void DebugEventBreakPointCollectGarbage(
// Debug event handler which re-issues a debug break and calls the garbage
// collector to have the heap verified.
-static void DebugEventBreak(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreak(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -991,10 +997,10 @@ static void DebugEventBreak(v8::DebugEvent event,
// reached.
int max_break_point_hit_count = 0;
bool terminate_after_max_break_point_hit = false;
-static void DebugEventBreakMax(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakMax(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
v8::internal::Debug* debug = isolate->debug();
// When hitting a debug event listener there must be a break set.
@@ -1179,8 +1185,7 @@ TEST(BreakPointICStore) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -1201,7 +1206,7 @@ TEST(BreakPointICStore) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1211,8 +1216,7 @@ TEST(BreakPointICLoad) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("bar=1"))->Run();
v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run();
v8::Local<v8::Function> foo =
@@ -1234,7 +1238,7 @@ TEST(BreakPointICLoad) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1244,8 +1248,7 @@ TEST(BreakPointICCall) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run();
v8::Local<v8::Function> foo =
@@ -1267,7 +1270,7 @@ TEST(BreakPointICCall) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1277,8 +1280,7 @@ TEST(BreakPointICCallWithGC) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
v8::Script::Compile(v8::String::New("function bar(){return 1;}"))->Run();
v8::Script::Compile(v8::String::New("function foo(){return bar();}"))->Run();
v8::Local<v8::Function> foo =
@@ -1300,7 +1302,7 @@ TEST(BreakPointICCallWithGC) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1310,8 +1312,7 @@ TEST(BreakPointConstructCallWithGC) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
v8::Script::Compile(v8::String::New("function bar(){ this.x = 1;}"))->Run();
v8::Script::Compile(v8::String::New(
"function foo(){return new bar(1).x;}"))->Run();
@@ -1334,7 +1335,7 @@ TEST(BreakPointConstructCallWithGC) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1355,8 +1356,7 @@ TEST(BreakPointReturn) {
"frame_source_column");
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function foo(){}"))->Run();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -1381,7 +1381,7 @@ TEST(BreakPointReturn) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1404,8 +1404,7 @@ TEST(GCDuringBreakPointProcessing) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
v8::Local<v8::Function> foo;
// Test IC store break point with garbage collection.
@@ -1433,7 +1432,7 @@ TEST(GCDuringBreakPointProcessing) {
SetBreakPoint(foo, 0);
CallWithBreakPoints(env->Global(), foo, 1, 25);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1468,8 +1467,7 @@ TEST(BreakPointSurviveGC) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> foo;
// Test IC store break point with garbage collection.
@@ -1515,7 +1513,7 @@ TEST(BreakPointSurviveGC) {
CallAndGC(env->Global(), foo);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1527,8 +1525,7 @@ TEST(BreakPointThroughJavaScript) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run();
// 012345678901234567890
@@ -1566,7 +1563,7 @@ TEST(BreakPointThroughJavaScript) {
foo->Run();
CHECK_EQ(8, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1583,8 +1580,7 @@ TEST(ScriptBreakPointByNameThroughJavaScript) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -1668,7 +1664,7 @@ TEST(ScriptBreakPointByNameThroughJavaScript) {
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1687,8 +1683,7 @@ TEST(ScriptBreakPointByIdThroughJavaScript) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> source = v8::String::New(
"function f() {\n"
@@ -1776,7 +1771,7 @@ TEST(ScriptBreakPointByIdThroughJavaScript) {
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1796,8 +1791,7 @@ TEST(EnableDisableScriptBreakPoint) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -1841,7 +1835,7 @@ TEST(EnableDisableScriptBreakPoint) {
f->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1853,8 +1847,7 @@ TEST(ConditionalScriptBreakPoint) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"count = 0;\n"
@@ -1903,7 +1896,7 @@ TEST(ConditionalScriptBreakPoint) {
}
CHECK_EQ(5, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1915,8 +1908,7 @@ TEST(ScriptBreakPointIgnoreCount) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -1958,7 +1950,7 @@ TEST(ScriptBreakPointIgnoreCount) {
}
CHECK_EQ(5, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1970,8 +1962,7 @@ TEST(ScriptBreakPointReload) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script = v8::String::New(
@@ -2017,7 +2008,7 @@ TEST(ScriptBreakPointReload) {
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2029,8 +2020,7 @@ TEST(ScriptBreakPointMultiple) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script_f = v8::String::New(
@@ -2083,7 +2073,7 @@ TEST(ScriptBreakPointMultiple) {
g->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2095,8 +2085,7 @@ TEST(ScriptBreakPointLineOffset) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script = v8::String::New(
@@ -2139,7 +2128,7 @@ TEST(ScriptBreakPointLineOffset) {
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2155,8 +2144,7 @@ TEST(ScriptBreakPointLine) {
frame_function_name_source,
"frame_function_name");
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::Function> g;
@@ -2245,7 +2233,7 @@ TEST(ScriptBreakPointLine) {
v8::Script::Compile(script, &origin)->Run();
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2256,8 +2244,7 @@ TEST(ScriptBreakPointLineTopLevel) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -2290,7 +2277,7 @@ TEST(ScriptBreakPointLineTopLevel) {
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2302,8 +2289,7 @@ TEST(ScriptBreakPointTopLevelCrash) {
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script_source = v8::String::New(
"function f() {\n"
@@ -2323,7 +2309,7 @@ TEST(ScriptBreakPointTopLevelCrash) {
ClearBreakPointFromJS(sbp1);
ClearBreakPointFromJS(sbp2);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2339,7 +2325,7 @@ TEST(RemoveBreakPointInBreak) {
debug_event_remove_break_point = SetBreakPoint(foo, 0);
// Register the debug event listener pasing the function
- v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
+ v8::Debug::SetDebugEventListener2(DebugEventRemoveBreakPoint, foo);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -2349,7 +2335,7 @@ TEST(RemoveBreakPointInBreak) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2359,8 +2345,7 @@ TEST(DebuggerStatement) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function bar(){debugger}"))->Run();
v8::Script::Compile(v8::String::New(
"function foo(){debugger;debugger;}"))->Run();
@@ -2377,7 +2362,7 @@ TEST(DebuggerStatement) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2387,8 +2372,7 @@ TEST(DebuggerStatementBreakpoint) {
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function foo(){debugger;}"))->Run();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -2404,7 +2388,7 @@ TEST(DebuggerStatementBreakpoint) {
CHECK_EQ(2, break_point_hit_count);
ClearBreakPoint(bp);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2421,7 +2405,7 @@ TEST(DebugEvaluate) {
evaluate_check_source,
"evaluate_check");
// Register the debug event listener
- v8::Debug::SetDebugEventListener(DebugEventEvaluate);
+ v8::Debug::SetDebugEventListener2(DebugEventEvaluate);
// Different expected vaules of x and a when in a break point (u = undefined,
// d = Hello, world!).
@@ -2521,7 +2505,7 @@ TEST(DebugEvaluate) {
};
bar->Call(env->Global(), 2, argv_bar_3);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2702,17 +2686,12 @@ struct DebugProcessDebugMessagesData {
DebugProcessDebugMessagesData process_debug_messages_data;
static void DebugProcessDebugMessagesHandler(
- const uint16_t* message,
- int length,
- v8::Debug::ClientData* client_data) {
-
- const int kBufferSize = 100000;
- char print_buffer[kBufferSize];
- Utf16ToAscii(message, length, print_buffer, kBufferSize);
-
+ const v8::Debug::Message& message) {
+ v8::Handle<v8::String> json = message.GetJSON();
+ v8::String::AsciiValue ascii(json);
EvaluateResult* array_item = process_debug_messages_data.current();
- bool res = GetEvaluateStringResult(print_buffer,
+ bool res = GetEvaluateStringResult(*ascii,
array_item->buffer,
EvaluateResult::kBufferSize);
if (res) {
@@ -2724,7 +2703,7 @@ static void DebugProcessDebugMessagesHandler(
// Test that the evaluation of expressions works even from ProcessDebugMessages
// i.e. with empty stack.
TEST(DebugEvaluateWithoutStack) {
- v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler);
+ v8::Debug::SetMessageHandler2(DebugProcessDebugMessagesHandler);
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -2778,8 +2757,8 @@ TEST(DebugEvaluateWithoutStack) {
0);
CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
- v8::Debug::SetMessageHandler(NULL);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2800,7 +2779,7 @@ TEST(DebugStepLinear) {
SetBreakPoint(foo, 3);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -2809,11 +2788,11 @@ TEST(DebugStepLinear) {
// With stepping all break locations are hit.
CHECK_EQ(4, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
SetBreakPoint(foo, 3);
break_point_hit_count = 0;
@@ -2822,7 +2801,7 @@ TEST(DebugStepLinear) {
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2833,7 +2812,7 @@ TEST(DebugStepKeyedLoadLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of keyed load. The statement 'y=1'
// is there to have more than one breakable statement in the loop, TODO(315).
@@ -2870,7 +2849,7 @@ TEST(DebugStepKeyedLoadLoop) {
// With stepping all break locations are hit.
CHECK_EQ(34, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2881,7 +2860,7 @@ TEST(DebugStepKeyedStoreLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of keyed store. The statement 'y=1'
// is there to have more than one breakable statement in the loop, TODO(315).
@@ -2917,7 +2896,7 @@ TEST(DebugStepKeyedStoreLoop) {
// With stepping all break locations are hit.
CHECK_EQ(33, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2928,7 +2907,7 @@ TEST(DebugStepNamedLoadLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of named load.
v8::Local<v8::Function> foo = CompileFunction(
@@ -2961,7 +2940,7 @@ TEST(DebugStepNamedLoadLoop) {
// With stepping all break locations are hit.
CHECK_EQ(54, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2971,7 +2950,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of named store.
v8::Local<v8::Function> foo = CompileFunction(
@@ -2996,7 +2975,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
// With stepping all expected break locations are hit.
CHECK_EQ(expected, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3013,7 +2992,7 @@ TEST(DebugStepLinearMixedICs) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping.
v8::Local<v8::Function> foo = CompileFunction(&env,
@@ -3036,11 +3015,11 @@ TEST(DebugStepLinearMixedICs) {
// With stepping all break locations are hit.
CHECK_EQ(11, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
SetBreakPoint(foo, 0);
break_point_hit_count = 0;
@@ -3049,7 +3028,7 @@ TEST(DebugStepLinearMixedICs) {
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3059,7 +3038,7 @@ TEST(DebugStepDeclarations) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3082,7 +3061,7 @@ TEST(DebugStepDeclarations) {
CHECK_EQ(6, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3092,7 +3071,7 @@ TEST(DebugStepLocals) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3115,7 +3094,7 @@ TEST(DebugStepLocals) {
CHECK_EQ(6, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3125,7 +3104,7 @@ TEST(DebugStepIf) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3158,7 +3137,7 @@ TEST(DebugStepIf) {
CHECK_EQ(5, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3168,7 +3147,7 @@ TEST(DebugStepSwitch) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3214,7 +3193,7 @@ TEST(DebugStepSwitch) {
CHECK_EQ(7, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3224,7 +3203,7 @@ TEST(DebugStepWhile) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3254,7 +3233,7 @@ TEST(DebugStepWhile) {
CHECK_EQ(202, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3264,7 +3243,7 @@ TEST(DebugStepDoWhile) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3294,7 +3273,7 @@ TEST(DebugStepDoWhile) {
CHECK_EQ(202, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3304,7 +3283,7 @@ TEST(DebugStepFor) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3335,7 +3314,7 @@ TEST(DebugStepFor) {
CHECK_EQ(203, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3345,7 +3324,7 @@ TEST(DebugStepForContinue) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3386,7 +3365,7 @@ TEST(DebugStepForContinue) {
CHECK_EQ(456, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3396,7 +3375,7 @@ TEST(DebugStepForBreak) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3438,7 +3417,7 @@ TEST(DebugStepForBreak) {
CHECK_EQ(504, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3448,7 +3427,7 @@ TEST(DebugStepForIn) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3486,7 +3465,7 @@ TEST(DebugStepForIn) {
CHECK_EQ(8, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3496,7 +3475,7 @@ TEST(DebugStepWith) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3517,7 +3496,7 @@ TEST(DebugStepWith) {
CHECK_EQ(4, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3527,7 +3506,7 @@ TEST(DebugConditional) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3553,7 +3532,7 @@ TEST(DebugConditional) {
CHECK_EQ(5, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3568,7 +3547,7 @@ TEST(StepInOutSimple) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3604,7 +3583,7 @@ TEST(StepInOutSimple) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3619,7 +3598,7 @@ TEST(StepInOutTree) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3656,7 +3635,7 @@ TEST(StepInOutTree) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded(true);
}
@@ -3671,7 +3650,7 @@ TEST(StepInOutBranch) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3691,7 +3670,7 @@ TEST(StepInOutBranch) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3708,7 +3687,7 @@ TEST(DebugStepNatives) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -3717,11 +3696,11 @@ TEST(DebugStepNatives) {
// With stepping all break locations are hit.
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3729,7 +3708,7 @@ TEST(DebugStepNatives) {
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3747,7 +3726,7 @@ TEST(DebugStepFunctionApply) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -3756,11 +3735,11 @@ TEST(DebugStepFunctionApply) {
// With stepping all break locations are hit.
CHECK_EQ(7, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3768,7 +3747,7 @@ TEST(DebugStepFunctionApply) {
// Without stepping only the debugger statement is hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3792,7 +3771,7 @@ TEST(DebugStepFunctionCall) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
// Check stepping where the if condition in bar is false.
@@ -3807,11 +3786,11 @@ TEST(DebugStepFunctionCall) {
foo->Call(env->Global(), argc, argv);
CHECK_EQ(8, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3819,7 +3798,7 @@ TEST(DebugStepFunctionCall) {
// Without stepping only the debugger statement is hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3831,7 +3810,7 @@ TEST(PauseInScript) {
env.ExposeDebug();
// Register a debug event listener which counts.
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Create a script that returns a function.
const char* src = "(function (evt) {})";
@@ -3850,7 +3829,7 @@ TEST(PauseInScript) {
CHECK_EQ(1, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3878,7 +3857,7 @@ TEST(BreakOnException) {
CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
v8::V8::AddMessageListener(MessageCallbackCount);
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Initial state should be no break on exceptions.
DebugEventCounterClear();
@@ -3996,7 +3975,7 @@ TEST(BreakOnException) {
CHECK_EQ(1, uncaught_exception_hit_count);
CHECK_EQ(1, message_callback_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
v8::V8::RemoveMessageListeners(MessageCallbackCount);
}
@@ -4018,7 +3997,7 @@ TEST(BreakOnCompileException) {
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
v8::V8::AddMessageListener(MessageCallbackCount);
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
DebugEventCounterClear();
MessageCallbackCountClear();
@@ -4072,7 +4051,7 @@ TEST(StepWithException) {
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create functions for testing stepping.
const char* src = "function a() { n(); }; "
@@ -4144,7 +4123,7 @@ TEST(StepWithException) {
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4158,7 +4137,7 @@ TEST(DebugBreak) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventBreak);
+ v8::Debug::SetDebugEventListener2(DebugEventBreak);
// Create a function for testing stepping.
const char* src = "function f0() {}"
@@ -4198,7 +4177,7 @@ TEST(DebugBreak) {
CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4210,7 +4189,7 @@ TEST(DisableBreak) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Create a function for testing stepping.
const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}";
@@ -4226,7 +4205,8 @@ TEST(DisableBreak) {
{
v8::Debug::DebugBreak();
- v8::internal::DisableBreak disable_break(true);
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
+ v8::internal::DisableBreak disable_break(isolate, true);
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
}
@@ -4235,7 +4215,7 @@ TEST(DisableBreak) {
CHECK_EQ(2, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4251,7 +4231,7 @@ TEST(NoBreakWhenBootstrapping) {
v8::HandleScope scope(isolate);
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Set the debug break flag.
v8::Debug::DebugBreak();
@@ -4270,7 +4250,7 @@ TEST(NoBreakWhenBootstrapping) {
CHECK_EQ(0, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4695,82 +4675,62 @@ TEST(NoHiddenProperties) {
// Support classes
-// Provides synchronization between k threads, where k is an input to the
-// constructor. The Wait() call blocks a thread until it is called for the
-// k'th time, then all calls return. Each ThreadBarrier object can only
-// be used once.
-class ThreadBarrier {
+// Provides synchronization between N threads, where N is a template parameter.
+// The Wait() call blocks a thread until it is called for the Nth time, then all
+// calls return. Each ThreadBarrier object can only be used once.
+template <int N>
+class ThreadBarrier V8_FINAL {
public:
- explicit ThreadBarrier(int num_threads);
- ~ThreadBarrier();
- void Wait();
- private:
- int num_threads_;
- int num_blocked_;
- v8::internal::Mutex* lock_;
- v8::internal::Semaphore* sem_;
- bool invalid_;
-};
+ ThreadBarrier() : num_blocked_(0) {}
-ThreadBarrier::ThreadBarrier(int num_threads)
- : num_threads_(num_threads), num_blocked_(0) {
- lock_ = OS::CreateMutex();
- sem_ = OS::CreateSemaphore(0);
- invalid_ = false; // A barrier may only be used once. Then it is invalid.
-}
+ ~ThreadBarrier() {
+ LockGuard<Mutex> lock_guard(&mutex_);
+ if (num_blocked_ != 0) {
+ CHECK_EQ(N, num_blocked_);
+ }
+ }
+ void Wait() {
+ LockGuard<Mutex> lock_guard(&mutex_);
+ CHECK_LT(num_blocked_, N);
+ num_blocked_++;
+ if (N == num_blocked_) {
+ // Signal and unblock all waiting threads.
+ cv_.NotifyAll();
+ printf("BARRIER\n\n");
+ fflush(stdout);
+ } else { // Wait for the semaphore.
+ while (num_blocked_ < N) {
+ cv_.Wait(&mutex_);
+ }
+ }
+ CHECK_EQ(N, num_blocked_);
+ }
-// Do not call, due to race condition with Wait().
-// Could be resolved with Pthread condition variables.
-ThreadBarrier::~ThreadBarrier() {
- lock_->Lock();
- delete lock_;
- delete sem_;
-}
+ private:
+ ConditionVariable cv_;
+ Mutex mutex_;
+ int num_blocked_;
+ STATIC_CHECK(N > 0);
-void ThreadBarrier::Wait() {
- lock_->Lock();
- CHECK(!invalid_);
- if (num_blocked_ == num_threads_ - 1) {
- // Signal and unblock all waiting threads.
- for (int i = 0; i < num_threads_ - 1; ++i) {
- sem_->Signal();
- }
- invalid_ = true;
- printf("BARRIER\n\n");
- fflush(stdout);
- lock_->Unlock();
- } else { // Wait for the semaphore.
- ++num_blocked_;
- lock_->Unlock(); // Potential race condition with destructor because
- sem_->Wait(); // these two lines are not atomic.
- }
-}
+ DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
+};
// A set containing enough barriers and semaphores for any of the tests.
class Barriers {
public:
- Barriers();
- void Initialize();
- ThreadBarrier barrier_1;
- ThreadBarrier barrier_2;
- ThreadBarrier barrier_3;
- ThreadBarrier barrier_4;
- ThreadBarrier barrier_5;
- v8::internal::Semaphore* semaphore_1;
- v8::internal::Semaphore* semaphore_2;
+ Barriers() : semaphore_1(0), semaphore_2(0) {}
+ ThreadBarrier<2> barrier_1;
+ ThreadBarrier<2> barrier_2;
+ ThreadBarrier<2> barrier_3;
+ ThreadBarrier<2> barrier_4;
+ ThreadBarrier<2> barrier_5;
+ v8::internal::Semaphore semaphore_1;
+ v8::internal::Semaphore semaphore_2;
};
-Barriers::Barriers() : barrier_1(2), barrier_2(2),
- barrier_3(2), barrier_4(2), barrier_5(2) {}
-
-void Barriers::Initialize() {
- semaphore_1 = OS::CreateSemaphore(0);
- semaphore_2 = OS::CreateSemaphore(0);
-}
-
// We match parts of the message to decide if it is a break message.
bool IsBreakEventMessage(char *message) {
@@ -4875,19 +4835,19 @@ class MessageQueueDebuggerThread : public v8::internal::Thread {
void Run();
};
-static void MessageHandler(const uint16_t* message, int length,
- v8::Debug::ClientData* client_data) {
- static char print_buffer[1000];
- Utf16ToAscii(message, length, print_buffer);
- if (IsBreakEventMessage(print_buffer)) {
+
+static void MessageHandler(const v8::Debug::Message& message) {
+ v8::Handle<v8::String> json = message.GetJSON();
+ v8::String::AsciiValue ascii(json);
+ if (IsBreakEventMessage(*ascii)) {
// Lets test script wait until break occurs to send commands.
// Signals when a break is reported.
- message_queue_barriers.semaphore_2->Signal();
+ message_queue_barriers.semaphore_2.Signal();
}
// Allow message handler to block on a semaphore, to test queueing of
// messages while blocked.
- message_queue_barriers.semaphore_1->Wait();
+ message_queue_barriers.semaphore_1.Wait();
}
@@ -4922,7 +4882,7 @@ void MessageQueueDebuggerThread::Run() {
/* Interleaved sequence of actions by the two threads:*/
// Main thread compiles and runs source_1
- message_queue_barriers.semaphore_1->Signal();
+ message_queue_barriers.semaphore_1.Signal();
message_queue_barriers.barrier_1.Wait();
// Post 6 commands, filling the command queue and making it expand.
// These calls return immediately, but the commands stay on the queue
@@ -4943,15 +4903,15 @@ void MessageQueueDebuggerThread::Run() {
// All the commands added so far will fail to execute as long as call stack
// is empty on beforeCompile event.
for (int i = 0; i < 6 ; ++i) {
- message_queue_barriers.semaphore_1->Signal();
+ message_queue_barriers.semaphore_1.Signal();
}
message_queue_barriers.barrier_3.Wait();
// Main thread compiles and runs source_3.
// Don't stop in the afterCompile handler.
- message_queue_barriers.semaphore_1->Signal();
+ message_queue_barriers.semaphore_1.Signal();
// source_3 includes a debugger statement, which causes a break event.
// Wait on break event from hitting "debugger" statement
- message_queue_barriers.semaphore_2->Wait();
+ message_queue_barriers.semaphore_2.Wait();
// These should execute after the "debugger" statement in source_2
v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1));
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2));
@@ -4959,15 +4919,15 @@ void MessageQueueDebuggerThread::Run() {
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2));
// Run after 2 break events, 4 responses.
for (int i = 0; i < 6 ; ++i) {
- message_queue_barriers.semaphore_1->Signal();
+ message_queue_barriers.semaphore_1.Signal();
}
// Wait on break event after a single step executes.
- message_queue_barriers.semaphore_2->Wait();
+ message_queue_barriers.semaphore_2.Wait();
v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1));
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2));
// Run after 2 responses.
for (int i = 0; i < 2 ; ++i) {
- message_queue_barriers.semaphore_1->Signal();
+ message_queue_barriers.semaphore_1.Signal();
}
// Main thread continues running source_3 to end, waits for this thread.
}
@@ -4980,8 +4940,7 @@ TEST(MessageQueues) {
// Create a V8 environment
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- message_queue_barriers.Initialize();
- v8::Debug::SetMessageHandler(MessageHandler);
+ v8::Debug::SetMessageHandler2(MessageHandler);
message_queue_debugger_thread.Start();
const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
@@ -5216,8 +5175,6 @@ TEST(ThreadedDebugging) {
V8Thread v8_thread;
// Create a V8 environment
- threaded_debugging_barriers.Initialize();
-
v8_thread.Start();
debugger_thread.Start();
@@ -5263,10 +5220,10 @@ static void BreakpointsMessageHandler(const v8::Debug::Message& message) {
if (IsBreakEventMessage(print_buffer)) {
break_event_breakpoint_id =
GetBreakpointIdFromBreakEventMessage(print_buffer);
- breakpoints_barriers->semaphore_1->Signal();
+ breakpoints_barriers->semaphore_1.Signal();
} else if (IsEvaluateResponseMessage(print_buffer)) {
evaluate_int_result = GetEvaluateIntResult(print_buffer);
- breakpoints_barriers->semaphore_1->Signal();
+ breakpoints_barriers->semaphore_1.Signal();
}
}
@@ -5375,42 +5332,42 @@ void BreakpointsDebuggerThread::Run() {
breakpoints_barriers->barrier_2.Wait();
// V8 thread starts compiling source_2.
// Automatic break happens, to run queued commands
- // breakpoints_barriers->semaphore_1->Wait();
+ // breakpoints_barriers->semaphore_1.Wait();
// Commands 1 through 3 run, thread continues.
// v8 thread runs source_2 to breakpoint in cat().
// message callback receives break event.
- breakpoints_barriers->semaphore_1->Wait();
+ breakpoints_barriers->semaphore_1.Wait();
// Must have hit breakpoint #1.
CHECK_EQ(1, break_event_breakpoint_id);
// 4:Evaluate dog() (which has a breakpoint).
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer));
// V8 thread hits breakpoint in dog().
- breakpoints_barriers->semaphore_1->Wait(); // wait for break event
+ breakpoints_barriers->semaphore_1.Wait(); // wait for break event
// Must have hit breakpoint #2.
CHECK_EQ(2, break_event_breakpoint_id);
// 5:Evaluate (x + 1).
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer));
// Evaluate (x + 1) finishes.
- breakpoints_barriers->semaphore_1->Wait();
+ breakpoints_barriers->semaphore_1.Wait();
// Must have result 108.
CHECK_EQ(108, evaluate_int_result);
// 6:Continue evaluation of dog().
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer));
// Evaluate dog() finishes.
- breakpoints_barriers->semaphore_1->Wait();
+ breakpoints_barriers->semaphore_1.Wait();
// Must have result 107.
CHECK_EQ(107, evaluate_int_result);
// 7:Continue evaluation of source_2, finish cat(17), hit breakpoint
// in cat(19).
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer));
// Message callback gets break event.
- breakpoints_barriers->semaphore_1->Wait(); // wait for break event
+ breakpoints_barriers->semaphore_1.Wait(); // wait for break event
// Must have hit breakpoint #1.
CHECK_EQ(1, break_event_breakpoint_id);
// 8: Evaluate dog() with breaks disabled.
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer));
// Evaluate dog() finishes.
- breakpoints_barriers->semaphore_1->Wait();
+ breakpoints_barriers->semaphore_1.Wait();
// Must have result 116.
CHECK_EQ(116, evaluate_int_result);
// 9: Continue evaluation of source2, reach end.
@@ -5426,7 +5383,6 @@ void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
// Create a V8 environment
Barriers stack_allocated_breakpoints_barriers;
- stack_allocated_breakpoints_barriers.Initialize();
breakpoints_barriers = &stack_allocated_breakpoints_barriers;
breakpoints_v8_thread.Start();
@@ -5447,15 +5403,13 @@ TEST(RecursiveBreakpointsGlobal) {
}
-static void DummyDebugEventListener(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DummyDebugEventListener(
+ const v8::Debug::EventDetails& event_details) {
}
TEST(SetDebugEventListenerOnUninitializedVM) {
- v8::Debug::SetDebugEventListener(DummyDebugEventListener);
+ v8::Debug::SetDebugEventListener2(DummyDebugEventListener);
}
@@ -5646,8 +5600,7 @@ TEST(DebuggerUnload) {
// Set a debug event listener.
break_point_hit_count = 0;
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
{
v8::HandleScope scope(env->GetIsolate());
// Create a couple of functions for the test.
@@ -5672,7 +5625,7 @@ TEST(DebuggerUnload) {
// Remove the debug event listener without clearing breakpoints. Do this
// outside a handle scope.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded(true);
// Now set a debug message handler.
@@ -5750,7 +5703,7 @@ TEST(DebuggerClearMessageHandler) {
// Clear debug message handler.
message_handler_hit_count = 0;
- v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetMessageHandler2(NULL);
// Run code to throw a unhandled exception. This should end up in the message
// handler.
@@ -5769,7 +5722,7 @@ static void MessageHandlerClearingMessageHandler(
message_handler_hit_count++;
// Clear debug message handler.
- v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetMessageHandler2(NULL);
}
@@ -5822,7 +5775,7 @@ static void HostDispatchMessageHandler(const v8::Debug::Message& message) {
static void HostDispatchDispatchHandler() {
- host_dispatch_barriers->semaphore_1->Signal();
+ host_dispatch_barriers->semaphore_1.Signal();
}
@@ -5874,7 +5827,7 @@ void HostDispatchDebuggerThread::Run() {
// v8 thread starts compiling source_2.
// Break happens, to run queued commands and host dispatches.
// Wait for host dispatch to be processed.
- host_dispatch_barriers->semaphore_1->Wait();
+ host_dispatch_barriers->semaphore_1.Wait();
// 2: Continue evaluation
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
}
@@ -5887,7 +5840,6 @@ TEST(DebuggerHostDispatch) {
// Create a V8 environment
Barriers stack_allocated_host_dispatch_barriers;
- stack_allocated_host_dispatch_barriers.Initialize();
host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
host_dispatch_v8_thread.Start();
@@ -5921,7 +5873,7 @@ Barriers* debug_message_dispatch_barriers;
static void DebugMessageHandler() {
- debug_message_dispatch_barriers->semaphore_1->Signal();
+ debug_message_dispatch_barriers->semaphore_1.Signal();
}
@@ -5935,7 +5887,7 @@ void DebugMessageDispatchV8Thread::Run() {
CompileRun("var y = 1 + 2;\n");
debug_message_dispatch_barriers->barrier_1.Wait();
- debug_message_dispatch_barriers->semaphore_1->Wait();
+ debug_message_dispatch_barriers->semaphore_1.Wait();
debug_message_dispatch_barriers->barrier_2.Wait();
}
@@ -5955,7 +5907,6 @@ TEST(DebuggerDebugMessageDispatch) {
// Create a V8 environment
Barriers stack_allocated_debug_message_dispatch_barriers;
- stack_allocated_debug_message_dispatch_barriers.Initialize();
debug_message_dispatch_barriers =
&stack_allocated_debug_message_dispatch_barriers;
@@ -5983,9 +5934,6 @@ TEST(DebuggerAgent) {
bool ok;
- // Initialize the socket library.
- i::Socket::SetUp();
-
// Test starting and stopping the agent without any client connection.
debugger->StartAgent("test", kPort1);
debugger->StopAgent();
@@ -5994,7 +5942,7 @@ TEST(DebuggerAgent) {
ok = debugger->StartAgent("test", kPort2);
CHECK(ok);
debugger->WaitForAgent();
- i::Socket* client = i::OS::CreateSocket();
+ i::Socket* client = new i::Socket;
ok = client->Connect("localhost", port2_str);
CHECK(ok);
// It is important to wait for a message from the agent. Otherwise,
@@ -6008,8 +5956,9 @@ TEST(DebuggerAgent) {
// Test starting and stopping the agent with the required port already
// occoupied.
- i::Socket* server = i::OS::CreateSocket();
- server->Bind(kPort3);
+ i::Socket* server = new i::Socket;
+ ok = server->Bind(kPort3);
+ CHECK(ok);
debugger->StartAgent("test", kPort3);
debugger->StopAgent();
@@ -6025,17 +5974,16 @@ class DebuggerAgentProtocolServerThread : public i::Thread {
port_(port),
server_(NULL),
client_(NULL),
- listening_(OS::CreateSemaphore(0)) {
+ listening_(0) {
}
~DebuggerAgentProtocolServerThread() {
// Close both sockets.
delete client_;
delete server_;
- delete listening_;
}
void Run();
- void WaitForListening() { listening_->Wait(); }
+ void WaitForListening() { listening_.Wait(); }
char* body() { return *body_; }
private:
@@ -6043,7 +5991,7 @@ class DebuggerAgentProtocolServerThread : public i::Thread {
i::SmartArrayPointer<char> body_;
i::Socket* server_; // Server socket used for bind/accept.
i::Socket* client_; // Single client connection used by the test.
- i::Semaphore* listening_; // Signalled when the server is in listen mode.
+ i::Semaphore listening_; // Signalled when the server is in listen mode.
};
@@ -6051,7 +5999,7 @@ void DebuggerAgentProtocolServerThread::Run() {
bool ok;
// Create the server socket and bind it to the requested port.
- server_ = i::OS::CreateSocket();
+ server_ = new i::Socket;
CHECK(server_ != NULL);
ok = server_->Bind(port_);
CHECK(ok);
@@ -6059,7 +6007,7 @@ void DebuggerAgentProtocolServerThread::Run() {
// Listen for new connections.
ok = server_->Listen(1);
CHECK(ok);
- listening_->Signal();
+ listening_.Signal();
// Accept a connection.
client_ = server_->Accept();
@@ -6081,9 +6029,6 @@ TEST(DebuggerAgentProtocolOverflowHeader) {
char port_str[kPortBufferLen];
OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
- // Initialize the socket library.
- i::Socket::SetUp();
-
// Create a socket server to receive a debugger agent message.
DebuggerAgentProtocolServerThread* server =
new DebuggerAgentProtocolServerThread(kPort);
@@ -6091,7 +6036,7 @@ TEST(DebuggerAgentProtocolOverflowHeader) {
server->WaitForListening();
// Connect.
- i::Socket* client = i::OS::CreateSocket();
+ i::Socket* client = new i::Socket;
CHECK(client != NULL);
bool ok = client->Connect(kLocalhost, port_str);
CHECK(ok);
@@ -6108,7 +6053,8 @@ TEST(DebuggerAgentProtocolOverflowHeader) {
buffer[kBufferSize - 3] = '0';
buffer[kBufferSize - 2] = '\r';
buffer[kBufferSize - 1] = '\n';
- client->Send(buffer, kBufferSize);
+ int result = client->Send(buffer, kBufferSize);
+ CHECK_EQ(kBufferSize, result);
// Short key and long value: X:XXXX....XXXX\r\n.
buffer[0] = 'X';
@@ -6118,13 +6064,16 @@ TEST(DebuggerAgentProtocolOverflowHeader) {
}
buffer[kBufferSize - 2] = '\r';
buffer[kBufferSize - 1] = '\n';
- client->Send(buffer, kBufferSize);
+ result = client->Send(buffer, kBufferSize);
+ CHECK_EQ(kBufferSize, result);
// Add empty body to request.
const char* content_length_zero_header = "Content-Length:0\r\n";
- client->Send(content_length_zero_header,
- StrLength(content_length_zero_header));
- client->Send("\r\n", 2);
+ int length = StrLength(content_length_zero_header);
+ result = client->Send(content_length_zero_header, length);
+ CHECK_EQ(length, result);
+ result = client->Send("\r\n", 2);
+ CHECK_EQ(2, result);
// Wait until data is received.
server->Join();
@@ -6203,8 +6152,7 @@ TEST(ScriptNameAndData) {
compiled_script_data_source,
"compiled_script_data");
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
// Test function source.
v8::Local<v8::String> script = v8::String::New(
@@ -6391,10 +6339,9 @@ TEST(DebugBreakInMessageHandler) {
// Debug event handler which gets the function on the top frame and schedules a
// break a number of times.
static void DebugEventDebugBreak(
- v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
break_point_hit_count++;
@@ -6445,7 +6392,7 @@ TEST(RegExpDebugBreak) {
v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv);
CHECK_EQ(12, result->Int32Value());
- v8::Debug::SetDebugEventListener(DebugEventDebugBreak);
+ v8::Debug::SetDebugEventListener2(DebugEventDebugBreak);
v8::Debug::DebugBreak();
result = f->Call(env->Global(), argc, argv);
@@ -6576,10 +6523,9 @@ TEST(NestedBreakEventContextData) {
// Debug event listener which counts the script collected events.
int script_collected_count = 0;
-static void DebugEventScriptCollectedEvent(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventScriptCollectedEvent(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
// Count the number of breaks.
if (event == v8::ScriptCollected) {
script_collected_count++;
@@ -6603,8 +6549,7 @@ TEST(ScriptCollectedEvent) {
HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
script_collected_count = 0;
- v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent);
{
v8::Script::Compile(v8::String::New("eval('a=1')"))->Run();
v8::Script::Compile(v8::String::New("eval('a=2')"))->Run();
@@ -6616,7 +6561,7 @@ TEST(ScriptCollectedEvent) {
CHECK_EQ(2, script_collected_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -6676,7 +6621,7 @@ TEST(ScriptCollectedEventContext) {
v8::Local<v8::Context>::New(isolate, context);
local_context->Exit();
}
- context.Dispose(isolate);
+ context.Dispose();
// Do garbage collection to collect the script above which is no longer
// referenced.
@@ -7017,7 +6962,7 @@ TEST(DebugBreakFunctionApply) {
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
// Set the debug break flag before calling the code using function.apply.
v8::Debug::DebugBreak();
@@ -7031,7 +6976,7 @@ TEST(DebugBreakFunctionApply) {
// When keeping the debug break several break will happen.
CHECK_GT(break_point_hit_count, 1);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -7060,10 +7005,9 @@ static void NamedGetterWithCallingContextCheck(
// an object with property 'a' == 1. If the property has custom accessor
// this handler will eventually invoke it.
static void DebugEventGetAtgumentPropertyValue(
- v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
break_point_hit_count++;
CHECK(debugger_context == v8::Context::GetCurrent());
@@ -7100,7 +7044,7 @@ TEST(CallingContextIsNotDebugContext) {
named->NewInstance());
// Register the debug event listener
- v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue);
+ v8::Debug::SetDebugEventListener2(DebugEventGetAtgumentPropertyValue);
// Create a function that invokes debugger.
v8::Local<v8::Function> foo = CompileFunction(
@@ -7113,7 +7057,7 @@ TEST(CallingContextIsNotDebugContext) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
debugee_context = v8::Handle<v8::Context>();
debugger_context = v8::Handle<v8::Context>();
CheckDebuggerUnloaded();
@@ -7146,7 +7090,7 @@ TEST(DebugEventContext) {
v8::Context::Scope context_scope(expected_context);
v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run();
expected_context.Clear();
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
expected_context_data = v8::Handle<v8::Value>();
CheckDebuggerUnloaded();
}
@@ -7213,16 +7157,16 @@ TEST(DebugEventBreakData) {
CHECK_EQ(TestClientData::constructor_call_counter,
TestClientData::destructor_call_counter);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
static bool debug_event_break_deoptimize_done = false;
-static void DebugEventBreakDeoptimize(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakDeoptimize(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
if (!frame_function_name.IsEmpty()) {
// Get the name of the function.
@@ -7265,8 +7209,7 @@ TEST(DeoptimizeDuringDebugBreak) {
// This tests lazy deoptimization bailout for the stack check, as the first
// time in function bar when using debug break and no break points will be at
// the initial stack check.
- v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakDeoptimize);
// Compile and run function bar which will optimize it for some flag settings.
v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run();
@@ -7277,14 +7220,14 @@ TEST(DeoptimizeDuringDebugBreak) {
CHECK(debug_event_break_deoptimize_done);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
}
-static void DebugEventBreakWithOptimizedStack(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakWithOptimizedStack(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
if (!frame_function_name.IsEmpty()) {
for (int i = 0; i < 2; i++) {
@@ -7329,8 +7272,7 @@ static void DebugEventBreakWithOptimizedStack(v8::DebugEvent event,
static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakWithOptimizedStack);
v8::Debug::DebugBreak();
}
@@ -7413,7 +7355,7 @@ TEST(DebugBreakLoop) {
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
// Create a function for getting the frame count when hitting the break.
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
@@ -7447,17 +7389,16 @@ TEST(DebugBreakLoop) {
TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}");
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
v8::Local<v8::Script> inline_script;
-static void DebugBreakInlineListener(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugBreakInlineListener(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
if (event != v8::Break) return;
int expected_frame_count = 4;
@@ -7484,7 +7425,7 @@ static void DebugBreakInlineListener(v8::DebugEvent event,
CHECK_EQ(expected_line_number[i],
i::GetScriptLineNumber(source_script, result->Int32Value()));
}
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
v8::V8::TerminateExecution();
}
@@ -7507,16 +7448,15 @@ TEST(DebugBreakInline) {
"g(false); \n"
"%OptimizeFunctionOnNextCall(g); \n"
"g(true);";
- v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+ v8::Debug::SetDebugEventListener2(DebugBreakInlineListener);
inline_script = v8::Script::Compile(v8::String::New(source));
inline_script->Run();
}
-static void DebugEventStepNext(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventStepNext(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
if (event == v8::Break) {
PrepareStep(StepNext);
}
@@ -7541,7 +7481,7 @@ TEST(Regress131642) {
// on the stack.
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventStepNext);
+ v8::Debug::SetDebugEventListener2(DebugEventStepNext);
// We step through the first script. It exits through an exception. We run
// this inside a new frame to record a different FP than the second script
@@ -7553,7 +7493,7 @@ TEST(Regress131642) {
const char* script_2 = "[0].forEach(function() { });";
CompileRun(script_2);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
}
@@ -7561,10 +7501,7 @@ TEST(Regress131642) {
int CountNativeContexts();
-static void NopListener(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void NopListener(const v8::Debug::EventDetails& event_details) {
}
@@ -7573,15 +7510,15 @@ TEST(DebuggerCreatesContextIffActive) {
v8::HandleScope scope(env->GetIsolate());
CHECK_EQ(1, CountNativeContexts());
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CompileRun("debugger;");
CHECK_EQ(1, CountNativeContexts());
- v8::Debug::SetDebugEventListener(NopListener);
+ v8::Debug::SetDebugEventListener2(NopListener);
CompileRun("debugger;");
CHECK_EQ(2, CountNativeContexts());
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
}
diff --git a/deps/v8/test/cctest/test-declarative-accessors.cc b/deps/v8/test/cctest/test-declarative-accessors.cc
index 2d2f5cd23b..fa5a0452fd 100644
--- a/deps/v8/test/cctest/test-declarative-accessors.cc
+++ b/deps/v8/test/cctest/test-declarative-accessors.cc
@@ -38,11 +38,11 @@ class HandleArray : public Malloced {
public:
static const unsigned kArraySize = 200;
explicit HandleArray() {}
- ~HandleArray() { Reset(v8::Isolate::GetCurrent()); }
- void Reset(v8::Isolate* isolate) {
+ ~HandleArray() { Reset(); }
+ void Reset() {
for (unsigned i = 0; i < kArraySize; i++) {
if (handles_[i].IsEmpty()) continue;
- handles_[i].Dispose(isolate);
+ handles_[i].Dispose();
handles_[i].Clear();
}
}
@@ -101,7 +101,7 @@ static v8::Local<v8::ObjectTemplate> CreateConstructor(
// Setup object template.
if (descriptor_name != NULL && !descriptor.IsEmpty()) {
bool added_accessor =
- obj_template->SetAccessor(v8_str(descriptor_name), descriptor);
+ obj_template->SetDeclaredAccessor(v8_str(descriptor_name), descriptor);
CHECK(added_accessor);
}
obj_template->SetInternalFieldCount((internal_field+1)*2 + 7);
@@ -124,9 +124,9 @@ static void VerifyRead(v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
context->Global()->Get(v8_str("accessible")));
obj->SetAlignedPointerInInternalField(internal_field, internal_object);
bool added_accessor;
- added_accessor = obj->SetAccessor(v8_str("y"), descriptor);
+ added_accessor = obj->SetDeclaredAccessor(v8_str("y"), descriptor);
CHECK(added_accessor);
- added_accessor = obj->SetAccessor(v8_str("13"), descriptor);
+ added_accessor = obj->SetDeclaredAccessor(v8_str("13"), descriptor);
CHECK(added_accessor);
// Test access from template getter.
v8::Local<v8::Value> value;
diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index 0f6bb8fff7..18f142061b 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -56,7 +56,7 @@ class DeclarationContext {
HandleScope scope(isolate);
Local<Context> context = Local<Context>::New(isolate, context_);
context->Exit();
- context_.Dispose(isolate);
+ context_.Dispose();
}
}
diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc
index c164193ee5..83a6354b2f 100644
--- a/deps/v8/test/cctest/test-deoptimization.cc
+++ b/deps/v8/test/cctest/test-deoptimization.cc
@@ -77,27 +77,27 @@ class AlwaysOptimizeAllowNativesSyntaxNoInlining {
// Utility class to set --allow-natives-syntax and --nouse-inlining when
// constructed and return to their default state when destroyed.
-class AllowNativesSyntaxNoInliningNoParallel {
+class AllowNativesSyntaxNoInliningNoConcurrent {
public:
- AllowNativesSyntaxNoInliningNoParallel()
+ AllowNativesSyntaxNoInliningNoConcurrent()
: allow_natives_syntax_(i::FLAG_allow_natives_syntax),
use_inlining_(i::FLAG_use_inlining),
- parallel_recompilation_(i::FLAG_parallel_recompilation) {
+ concurrent_recompilation_(i::FLAG_concurrent_recompilation) {
i::FLAG_allow_natives_syntax = true;
i::FLAG_use_inlining = false;
- i::FLAG_parallel_recompilation = false;
+ i::FLAG_concurrent_recompilation = false;
}
- ~AllowNativesSyntaxNoInliningNoParallel() {
+ ~AllowNativesSyntaxNoInliningNoConcurrent() {
i::FLAG_allow_natives_syntax = allow_natives_syntax_;
i::FLAG_use_inlining = use_inlining_;
- i::FLAG_parallel_recompilation = parallel_recompilation_;
+ i::FLAG_concurrent_recompilation = concurrent_recompilation_;
}
private:
bool allow_natives_syntax_;
bool use_inlining_;
- bool parallel_recompilation_;
+ bool concurrent_recompilation_;
};
@@ -347,7 +347,7 @@ TEST(DeoptimizeBinaryOperationADDString) {
const char* f_source = "function f(x, y) { return x + y; };";
{
- AllowNativesSyntaxNoInliningNoParallel options;
+ AllowNativesSyntaxNoInliningNoConcurrent options;
// Compile function f and collect to type feedback to insert binary op stub
// call in the optimized code.
i::FLAG_prepare_always_opt = true;
@@ -367,7 +367,7 @@ TEST(DeoptimizeBinaryOperationADDString) {
i::FLAG_always_opt = true;
CompileRun(f_source);
CompileRun("f('a+', new X());");
- CHECK(!i::V8::UseCrankshaft() ||
+ CHECK(!i::Isolate::Current()->use_crankshaft() ||
GetJSFunction(env->Global(), "f")->IsOptimized());
// Call f and force deoptimization while processing the binary operation.
@@ -405,7 +405,7 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
binary_op);
char* f_source = f_source_buffer.start();
- AllowNativesSyntaxNoInliningNoParallel options;
+ AllowNativesSyntaxNoInliningNoConcurrent options;
// Compile function f and collect to type feedback to insert binary op stub
// call in the optimized code.
i::FLAG_prepare_always_opt = true;
@@ -419,7 +419,7 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
i::FLAG_always_opt = true;
CompileRun(f_source);
CompileRun("f(7, new X());");
- CHECK(!i::V8::UseCrankshaft() ||
+ CHECK(!i::Isolate::Current()->use_crankshaft() ||
GetJSFunction((*env)->Global(), "f")->IsOptimized());
// Call f and force deoptimization while processing the binary operation.
@@ -497,7 +497,7 @@ TEST(DeoptimizeCompare) {
const char* f_source = "function f(x, y) { return x < y; };";
{
- AllowNativesSyntaxNoInliningNoParallel options;
+ AllowNativesSyntaxNoInliningNoConcurrent options;
// Compile function f and collect to type feedback to insert compare ic
// call in the optimized code.
i::FLAG_prepare_always_opt = true;
@@ -517,7 +517,7 @@ TEST(DeoptimizeCompare) {
i::FLAG_always_opt = true;
CompileRun(f_source);
CompileRun("f('a', new X());");
- CHECK(!i::V8::UseCrankshaft() ||
+ CHECK(!i::Isolate::Current()->use_crankshaft() ||
GetJSFunction(env->Global(), "f")->IsOptimized());
// Call f and force deoptimization while processing the comparison.
@@ -544,7 +544,7 @@ TEST(DeoptimizeLoadICStoreIC) {
const char* g2_source = "function g2(x, y) { x[y] = 1; };";
{
- AllowNativesSyntaxNoInliningNoParallel options;
+ AllowNativesSyntaxNoInliningNoConcurrent options;
// Compile functions and collect to type feedback to insert ic
// calls in the optimized code.
i::FLAG_prepare_always_opt = true;
@@ -587,7 +587,7 @@ TEST(DeoptimizeLoadICStoreIC) {
CompileRun("g1(new X());");
CompileRun("f2(new X(), 'z');");
CompileRun("g2(new X(), 'z');");
- if (i::V8::UseCrankshaft()) {
+ if (i::Isolate::Current()->use_crankshaft()) {
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
@@ -624,7 +624,7 @@ TEST(DeoptimizeLoadICStoreICNested) {
const char* g2_source = "function g2(x, y) { x[y] = 1; };";
{
- AllowNativesSyntaxNoInliningNoParallel options;
+ AllowNativesSyntaxNoInliningNoConcurrent options;
// Compile functions and collect to type feedback to insert ic
// calls in the optimized code.
i::FLAG_prepare_always_opt = true;
@@ -671,7 +671,7 @@ TEST(DeoptimizeLoadICStoreICNested) {
CompileRun("g1(new X());");
CompileRun("f2(new X(), 'z');");
CompileRun("g2(new X(), 'z');");
- if (i::V8::UseCrankshaft()) {
+ if (i::Isolate::Current()->use_crankshaft()) {
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc
index 2bdf235524..b9e8b1ec06 100644
--- a/deps/v8/test/cctest/test-dictionary.cc
+++ b/deps/v8/test/cctest/test-dictionary.cc
@@ -72,7 +72,7 @@ TEST(ObjectHashTable) {
// Keys should map back to their respective values and also should get
// an identity hash code generated.
for (int i = 0; i < 100; i++) {
- Handle<JSObject> key = factory->NewJSArray(7);
+ Handle<JSReceiver> key = factory->NewJSArray(7);
Handle<JSObject> value = factory->NewJSArray(11);
table = PutIntoObjectHashTable(table, key, value);
CHECK_EQ(table->NumberOfElements(), i + 1);
@@ -84,7 +84,7 @@ TEST(ObjectHashTable) {
// Keys never added to the map which already have an identity hash
// code should not be found.
for (int i = 0; i < 100; i++) {
- Handle<JSObject> key = factory->NewJSArray(7);
+ Handle<JSReceiver> key = factory->NewJSArray(7);
CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
@@ -94,13 +94,64 @@ TEST(ObjectHashTable) {
// Keys that don't have an identity hash should not be found and also
// should not get an identity hash code generated.
for (int i = 0; i < 100; i++) {
- Handle<JSObject> key = factory->NewJSArray(7);
+ Handle<JSReceiver> key = factory->NewJSArray(7);
CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value());
}
}
+class ObjectHashTableTest: public ObjectHashTable {
+ public:
+ void insert(int entry, int key, int value) {
+ set(EntryToIndex(entry), Smi::FromInt(key));
+ set(EntryToIndex(entry) + 1, Smi::FromInt(value));
+ }
+
+ int lookup(int key) {
+ return Smi::cast(Lookup(Smi::FromInt(key)))->value();
+ }
+
+ int capacity() {
+ return Capacity();
+ }
+};
+
+
+TEST(HashTableRehash) {
+ LocalContext context;
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+ // Test almost filled table.
+ {
+ Handle<ObjectHashTable> table = factory->NewObjectHashTable(100);
+ ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table);
+ int capacity = t->capacity();
+ for (int i = 0; i < capacity - 1; i++) {
+ t->insert(i, i * i, i);
+ }
+ t->Rehash(Smi::FromInt(0));
+ for (int i = 0; i < capacity - 1; i++) {
+ CHECK_EQ(i, t->lookup(i * i));
+ }
+ }
+ // Test half-filled table.
+ {
+ Handle<ObjectHashTable> table = factory->NewObjectHashTable(100);
+ ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table);
+ int capacity = t->capacity();
+ for (int i = 0; i < capacity / 2; i++) {
+ t->insert(i, i * i, i);
+ }
+ t->Rehash(Smi::FromInt(0));
+ for (int i = 0; i < capacity / 2; i++) {
+ CHECK_EQ(i, t->lookup(i * i));
+ }
+ }
+}
+
+
#ifdef DEBUG
TEST(ObjectHashSetCausesGC) {
i::FLAG_stress_compaction = false;
diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc
index 14447b2c45..1b6af47233 100644
--- a/deps/v8/test/cctest/test-disasm-ia32.cc
+++ b/deps/v8/test/cctest/test-disasm-ia32.cc
@@ -99,16 +99,7 @@ TEST(DisasmIa320) {
__ or_(edx, 3);
__ xor_(edx, 3);
__ nop();
- {
- CHECK(CpuFeatures::IsSupported(CPUID));
- CpuFeatureScope fscope(&assm, CPUID);
- __ cpuid();
- }
- {
- CHECK(CpuFeatures::IsSupported(RDTSC));
- CpuFeatureScope fscope(&assm, RDTSC);
- __ rdtsc();
- }
+ __ cpuid();
__ movsx_b(edx, ecx);
__ movsx_w(edx, ecx);
__ movzx_b(edx, ecx);
diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc
index 1c7f416392..1ff9fd336b 100644
--- a/deps/v8/test/cctest/test-disasm-x64.cc
+++ b/deps/v8/test/cctest/test-disasm-x64.cc
@@ -95,11 +95,6 @@ TEST(DisasmX64) {
CpuFeatures::Scope fscope(CPUID);
__ cpuid();
}
- {
- CHECK(CpuFeatures::IsSupported(RDTSC));
- CpuFeatures::Scope fscope(RDTSC);
- __ rdtsc();
- }
__ movsxbq(rdx, Operand(rcx, 0));
__ movsxwq(rdx, Operand(rcx, 0));
__ movzxbl(rdx, Operand(rcx, 0));
diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc
index 0b652db37b..1d33a8c86b 100644
--- a/deps/v8/test/cctest/test-global-handles.cc
+++ b/deps/v8/test/cctest/test-global-handles.cc
@@ -321,24 +321,26 @@ TEST(EternalHandles) {
CcTest::InitializeVM();
Isolate* isolate = Isolate::Current();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
- EternalHandles* eternals = isolate->eternal_handles();
+ EternalHandles* eternal_handles = isolate->eternal_handles();
// Create a number of handles that will not be on a block boundary
const int kArrayLength = 2048-1;
int indices[kArrayLength];
+ v8::Eternal<v8::Value> eternals[kArrayLength];
- CHECK_EQ(0, eternals->NumberOfHandles());
+ CHECK_EQ(0, eternal_handles->NumberOfHandles());
for (int i = 0; i < kArrayLength; i++) {
+ indices[i] = -1;
HandleScope scope(isolate);
v8::Local<v8::Object> object = v8::Object::New();
object->Set(i, v8::Integer::New(i, v8_isolate));
- if (i % 2 == 0) {
- // Create with internal api
- indices[i] = eternals->Create(isolate, *v8::Utils::OpenHandle(*object));
- } else {
- // Create with external api
- indices[i] = object.Eternalize(v8_isolate);
- }
+ // Create with internal api
+ eternal_handles->Create(
+ isolate, *v8::Utils::OpenHandle(*object), &indices[i]);
+ // Create with external api
+ CHECK(eternals[i].IsEmpty());
+ eternals[i].Set(v8_isolate, object);
+ CHECK(!eternals[i].IsEmpty());
}
isolate->heap()->CollectAllAvailableGarbage();
@@ -346,21 +348,31 @@ TEST(EternalHandles) {
for (int i = 0; i < kArrayLength; i++) {
for (int j = 0; j < 2; j++) {
HandleScope scope(isolate);
- v8::Local<v8::Object> object;
+ v8::Local<v8::Value> local;
if (j == 0) {
// Test internal api
- v8::Local<v8::Value> local =
- v8::Utils::ToLocal(eternals->Get(indices[i]));
- object = v8::Handle<v8::Object>::Cast(local);
+ local = v8::Utils::ToLocal(eternal_handles->Get(indices[i]));
} else {
// Test external api
- object = v8::Local<v8::Object>::GetEternal(v8_isolate, indices[i]);
+ local = eternals[i].Get(v8_isolate);
}
+ v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast(local);
v8::Local<v8::Value> value = object->Get(i);
CHECK(value->IsInt32());
CHECK_EQ(i, value->Int32Value());
}
}
- CHECK_EQ(kArrayLength, eternals->NumberOfHandles());
+ CHECK_EQ(2*kArrayLength, eternal_handles->NumberOfHandles());
+
+ // Create an eternal via the constructor
+ {
+ HandleScope scope(isolate);
+ v8::Local<v8::Object> object = v8::Object::New();
+ v8::Eternal<v8::Object> eternal(v8_isolate, object);
+ CHECK(!eternal.IsEmpty());
+ CHECK(object == eternal.Get(v8_isolate));
+ }
+
+ CHECK_EQ(2*kArrayLength + 1, eternal_handles->NumberOfHandles());
}
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index e30fcc00c9..0cf9cdaedf 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -404,12 +404,57 @@ TEST(HeapSnapshotSlicedString) {
const v8::HeapGraphNode* child_string =
GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string");
CHECK_NE(NULL, child_string);
+ CHECK_EQ(v8::HeapGraphNode::kSlicedString, child_string->GetType());
const v8::HeapGraphNode* parent =
GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent");
CHECK_EQ(parent_string, parent);
+ heap_profiler->DeleteAllHeapSnapshots();
}
+TEST(HeapSnapshotConsString) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ global_template->SetInternalFieldCount(1);
+ LocalContext env(NULL, global_template);
+ v8::Handle<v8::Object> global_proxy = env->Global();
+ v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>();
+ CHECK_EQ(1, global->InternalFieldCount());
+
+ i::Factory* factory = i::Isolate::Current()->factory();
+ i::Handle<i::String> first =
+ factory->NewStringFromAscii(i::CStrVector("0123456789"));
+ i::Handle<i::String> second =
+ factory->NewStringFromAscii(i::CStrVector("0123456789"));
+ i::Handle<i::String> cons_string = factory->NewConsString(first, second);
+
+ global->SetInternalField(0, v8::ToApiHandle<v8::String>(cons_string));
+
+ v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
+ const v8::HeapSnapshot* snapshot =
+ heap_profiler->TakeHeapSnapshot(v8_str("cons_strings"));
+ CHECK(ValidateSnapshot(snapshot));
+ const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot);
+
+ const v8::HeapGraphNode* string_node =
+ GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0");
+ CHECK_NE(NULL, string_node);
+ CHECK_EQ(v8::HeapGraphNode::kConsString, string_node->GetType());
+
+ const v8::HeapGraphNode* first_node =
+ GetProperty(string_node, v8::HeapGraphEdge::kInternal, "first");
+ CHECK_EQ(v8::HeapGraphNode::kString, first_node->GetType());
+
+ const v8::HeapGraphNode* second_node =
+ GetProperty(string_node, v8::HeapGraphEdge::kInternal, "second");
+ CHECK_EQ(v8::HeapGraphNode::kString, second_node->GetType());
+
+ heap_profiler->DeleteAllHeapSnapshots();
+}
+
+
+
TEST(HeapSnapshotInternalReferences) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
@@ -1201,11 +1246,11 @@ TEST(HeapSnapshotRetainedObjectInfo) {
heap_profiler->SetWrapperClassInfoProvider(
2, TestRetainedObjectInfo::WrapperInfoCallback);
v8::Persistent<v8::String> p_AAA(isolate, v8_str("AAA"));
- p_AAA.SetWrapperClassId(isolate, 1);
+ p_AAA.SetWrapperClassId(1);
v8::Persistent<v8::String> p_BBB(isolate, v8_str("BBB"));
- p_BBB.SetWrapperClassId(isolate, 1);
+ p_BBB.SetWrapperClassId(1);
v8::Persistent<v8::String> p_CCC(isolate, v8_str("CCC"));
- p_CCC.SetWrapperClassId(isolate, 2);
+ p_CCC.SetWrapperClassId(2);
CHECK_EQ(0, TestRetainedObjectInfo::instances.length());
const v8::HeapSnapshot* snapshot =
heap_profiler->TakeHeapSnapshot(v8_str("retained"));
@@ -1711,7 +1756,7 @@ bool HasWeakGlobalHandle() {
static void PersistentHandleCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 1813470838..9d74011fde 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -82,16 +82,18 @@ TEST(HeapMaps) {
static void CheckOddball(Isolate* isolate, Object* obj, const char* string) {
CHECK(obj->IsOddball());
bool exc;
+ Handle<Object> handle(obj, isolate);
Object* print_string =
- *Execution::ToString(Handle<Object>(obj, isolate), &exc);
+ *Execution::ToString(isolate, handle, &exc);
CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string)));
}
static void CheckSmi(Isolate* isolate, int value, const char* string) {
bool exc;
+ Handle<Object> handle(Smi::FromInt(value), isolate);
Object* print_string =
- *Execution::ToString(Handle<Object>(Smi::FromInt(value), isolate), &exc);
+ *Execution::ToString(isolate, handle, &exc);
CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string)));
}
@@ -100,8 +102,9 @@ static void CheckNumber(Isolate* isolate, double value, const char* string) {
Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked();
CHECK(obj->IsNumber());
bool exc;
+ Handle<Object> handle(obj, isolate);
Object* print_string =
- *Execution::ToString(Handle<Object>(obj, isolate), &exc);
+ *Execution::ToString(isolate, handle, &exc);
CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string)));
}
@@ -398,7 +401,7 @@ static void TestWeakGlobalHandleCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void* id) {
if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true;
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -765,7 +768,7 @@ TEST(JSArray) {
// array[length] = name.
array->SetElement(0, *name, NONE, kNonStrictMode)->ToObjectChecked();
CHECK_EQ(Smi::FromInt(1), array->length());
- CHECK_EQ(array->GetElement(0), *name);
+ CHECK_EQ(array->GetElement(isolate, 0), *name);
// Set array length with larger than smi value.
Handle<Object> length =
@@ -782,8 +785,8 @@ TEST(JSArray) {
uint32_t new_int_length = 0;
CHECK(array->length()->ToArrayIndex(&new_int_length));
CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
- CHECK_EQ(array->GetElement(int_length), *name);
- CHECK_EQ(array->GetElement(0), *name);
+ CHECK_EQ(array->GetElement(isolate, int_length), *name);
+ CHECK_EQ(array->GetElement(isolate, 0), *name);
}
@@ -814,8 +817,8 @@ TEST(JSObjectCopy) {
Handle<JSObject> clone = Copy(obj);
CHECK(!clone.is_identical_to(obj));
- CHECK_EQ(obj->GetElement(0), clone->GetElement(0));
- CHECK_EQ(obj->GetElement(1), clone->GetElement(1));
+ CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 0));
+ CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 1));
CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first));
CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second));
@@ -829,8 +832,8 @@ TEST(JSObjectCopy) {
clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked();
clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked();
- CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
- CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
+ CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 0));
+ CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 1));
CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first));
CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second));
@@ -1332,7 +1335,7 @@ TEST(TestInternalWeakLists) {
isolate->compilation_cache()->Clear();
heap->CollectAllGarbage(Heap::kNoGCFlags);
- bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
+ bool opt = (FLAG_always_opt && isolate->use_crankshaft());
CHECK_EQ(i + 1, CountNativeContexts());
@@ -1476,7 +1479,7 @@ TEST(TestInternalWeakListsTraverseWithGC) {
CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1));
}
- bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
+ bool opt = (FLAG_always_opt && isolate->use_crankshaft());
// Compile a number of functions the length of the weak list of optimized
// functions both with and without GCs while iterating the list.
@@ -1720,12 +1723,12 @@ TEST(LeakNativeContextViaMap) {
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
- ctx1p.Dispose(isolate);
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1766,12 +1769,12 @@ TEST(LeakNativeContextViaFunction) {
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
- ctx1p.Dispose(ctx1->GetIsolate());
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1810,12 +1813,12 @@ TEST(LeakNativeContextViaMapKeyed) {
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
- ctx1p.Dispose(ctx1->GetIsolate());
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1858,12 +1861,12 @@ TEST(LeakNativeContextViaMapProto) {
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
- ctx1p.Dispose(isolate);
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1876,7 +1879,7 @@ TEST(InstanceOfStubWriteBarrier) {
#endif
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft()) return;
+ if (!i::Isolate::Current()->use_crankshaft()) return;
if (i::FLAG_force_marking_deque_overflows) return;
v8::HandleScope outer_scope(v8::Isolate::GetCurrent());
@@ -1993,7 +1996,7 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
#endif
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft()) return;
+ if (!i::Isolate::Current()->use_crankshaft()) return;
v8::HandleScope outer_scope(v8::Isolate::GetCurrent());
{
@@ -2050,7 +2053,7 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
#endif
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft()) return;
+ if (!i::Isolate::Current()->use_crankshaft()) return;
v8::HandleScope outer_scope(CcTest::isolate());
{
@@ -2089,7 +2092,7 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
TEST(OptimizedAllocationAlwaysInNewSpace) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
@@ -2118,7 +2121,7 @@ TEST(OptimizedAllocationAlwaysInNewSpace) {
TEST(OptimizedPretenuringAllocationFolding) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2154,7 +2157,7 @@ TEST(OptimizedPretenuringAllocationFolding) {
TEST(OptimizedPretenuringAllocationFoldingBlocks) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2190,7 +2193,7 @@ TEST(OptimizedPretenuringAllocationFoldingBlocks) {
TEST(OptimizedPretenuringObjectArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2215,7 +2218,7 @@ TEST(OptimizedPretenuringObjectArrayLiterals) {
TEST(OptimizedPretenuringMixedInObjectProperties) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2246,7 +2249,7 @@ TEST(OptimizedPretenuringMixedInObjectProperties) {
TEST(OptimizedPretenuringDoubleArrayProperties) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2271,7 +2274,7 @@ TEST(OptimizedPretenuringDoubleArrayProperties) {
TEST(OptimizedPretenuringdoubleArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2296,7 +2299,7 @@ TEST(OptimizedPretenuringdoubleArrayLiterals) {
TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2330,7 +2333,7 @@ TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
TEST(OptimizedPretenuringNestedObjectLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2364,7 +2367,7 @@ TEST(OptimizedPretenuringNestedObjectLiterals) {
TEST(OptimizedPretenuringNestedDoubleLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2401,7 +2404,7 @@ TEST(OptimizedPretenuringNestedDoubleLiterals) {
TEST(OptimizedAllocationArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
@@ -2428,7 +2431,7 @@ TEST(OptimizedPretenuringCallNew) {
i::FLAG_allow_natives_syntax = true;
i::FLAG_pretenuring_call_new = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2691,9 +2694,7 @@ TEST(Regress2211) {
// In the first iteration, set hidden value first and identity hash second.
// In the second iteration, reverse the order.
if (i == 0) obj->SetHiddenValue(v8_str("key string"), value);
- MaybeObject* maybe_obj = internal_obj->SetIdentityHash(hash,
- ALLOW_CREATION);
- CHECK(!maybe_obj->IsFailure());
+ JSObject::SetIdentityHash(internal_obj, hash);
if (i == 1) obj->SetHiddenValue(v8_str("key string"), value);
// Check values.
@@ -2898,7 +2899,7 @@ void ReleaseStackTraceDataTest(const char* source, const char* accessor) {
// to check whether the data is being released since the external string
// resource's callback is fired when the external string is GC'ed.
FLAG_use_ic = false; // ICs retain objects.
- FLAG_parallel_recompilation = false;
+ FLAG_concurrent_recompilation = false;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
SourceResource* resource = new SourceResource(i::StrDup(source));
@@ -3140,16 +3141,6 @@ TEST(Regress169209) {
i::FLAG_allow_natives_syntax = true;
i::FLAG_flush_code_incrementally = true;
- // Experimental natives are compiled during snapshot deserialization.
- // This test breaks because heap layout changes in a way that closure
- // is visited before shared function info.
- i::FLAG_harmony_typed_arrays = false;
- i::FLAG_harmony_array_buffer = false;
-
- // Disable loading the i18n extension which breaks the assumptions of this
- // test about the heap layout.
- i::FLAG_enable_i18n = false;
-
CcTest::InitializeVM();
Isolate* isolate = Isolate::Current();
Heap* heap = isolate->heap();
@@ -3427,7 +3418,7 @@ TEST(DeferredHandles) {
CcTest::InitializeVM();
Isolate* isolate = Isolate::Current();
Heap* heap = isolate->heap();
- v8::HandleScope scope;
+ v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
v8::ImplementationUtilities::HandleScopeData* data =
isolate->handle_scope_data();
Handle<Object> init(heap->empty_string(), isolate);
diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc
index a8e870e671..a143d583fd 100644
--- a/deps/v8/test/cctest/test-lockers.cc
+++ b/deps/v8/test/cctest/test-lockers.cc
@@ -41,7 +41,6 @@
#include "parser.h"
#include "unicode-inl.h"
-using ::v8::AccessorInfo;
using ::v8::Context;
using ::v8::Extension;
using ::v8::Function;
@@ -130,20 +129,18 @@ class JoinableThread {
public:
explicit JoinableThread(const char* name)
: name_(name),
- semaphore_(i::OS::CreateSemaphore(0)),
+ semaphore_(0),
thread_(this) {
}
- virtual ~JoinableThread() {
- delete semaphore_;
- }
+ virtual ~JoinableThread() {}
void Start() {
thread_.Start();
}
void Join() {
- semaphore_->Wait();
+ semaphore_.Wait();
}
virtual void Run() = 0;
@@ -158,7 +155,7 @@ class JoinableThread {
virtual void Run() {
joinable_thread_->Run();
- joinable_thread_->semaphore_->Signal();
+ joinable_thread_->semaphore_.Signal();
}
private:
@@ -166,7 +163,7 @@ class JoinableThread {
};
const char* name_;
- i::Semaphore* semaphore_;
+ i::Semaphore semaphore_;
ThreadWithSemaphore thread_;
friend class ThreadWithSemaphore;
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index 8bcb5f7d29..f752c36ccb 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -27,7 +27,6 @@
//
// Tests of logging functions from log.h
-#define V8_DISABLE_DEPRECATIONS 1
#ifdef __linux__
#include <pthread.h>
#include <signal.h>
@@ -44,7 +43,6 @@
#include "v8utils.h"
#include "cctest.h"
#include "vm-state-inl.h"
-#undef V8_DISABLE_DEPRECATIONS
using v8::internal::Address;
using v8::internal::EmbeddedVector;
@@ -56,13 +54,12 @@ namespace {
class ScopedLoggerInitializer {
public:
- explicit ScopedLoggerInitializer(bool prof_lazy)
+ ScopedLoggerInitializer()
: saved_log_(i::FLAG_log),
- saved_prof_lazy_(i::FLAG_prof_lazy),
saved_prof_(i::FLAG_prof),
temp_file_(NULL),
// Need to run this prior to creating the scope.
- trick_to_run_init_flags_(init_flags_(prof_lazy)),
+ trick_to_run_init_flags_(init_flags_()),
scope_(v8::Isolate::GetCurrent()),
env_(v8::Context::New(v8::Isolate::GetCurrent())),
logger_(i::Isolate::Current()->logger()) {
@@ -73,7 +70,6 @@ class ScopedLoggerInitializer {
env_->Exit();
logger_->TearDown();
if (temp_file_ != NULL) fclose(temp_file_);
- i::FLAG_prof_lazy = saved_prof_lazy_;
i::FLAG_prof = saved_prof_;
i::FLAG_log = saved_log_;
}
@@ -91,16 +87,14 @@ class ScopedLoggerInitializer {
}
private:
- static bool init_flags_(bool prof_lazy) {
+ static bool init_flags_() {
i::FLAG_log = true;
i::FLAG_prof = true;
- i::FLAG_prof_lazy = prof_lazy;
i::FLAG_logfile = i::Log::kLogToTemporaryFile;
- return prof_lazy;
+ return false;
}
const bool saved_log_;
- const bool saved_prof_lazy_;
const bool saved_prof_;
FILE* temp_file_;
const bool trick_to_run_init_flags_;
@@ -124,70 +118,6 @@ static const char* StrNStr(const char* s1, const char* s2, int n) {
}
-TEST(ProfLazyMode) {
- ScopedLoggerInitializer initialize_logger(true);
- Logger* logger = initialize_logger.logger();
-
- if (!i::V8::UseCrankshaft()) return;
-
- logger->StringEvent("test-start", "");
- CompileRun("var a = (function(x) { return x + 1; })(10);");
- logger->StringEvent("test-profiler-start", "");
- v8::V8::ResumeProfiler();
- CompileRun(
- "var b = (function(x) { return x + 2; })(10);\n"
- "var c = (function(x) { return x + 3; })(10);\n"
- "var d = (function(x) { return x + 4; })(10);\n"
- "var e = (function(x) { return x + 5; })(10);");
- v8::V8::PauseProfiler();
- logger->StringEvent("test-profiler-stop", "");
- CompileRun("var f = (function(x) { return x + 6; })(10);");
- // Check that profiling can be resumed again.
- logger->StringEvent("test-profiler-start-2", "");
- v8::V8::ResumeProfiler();
- CompileRun(
- "var g = (function(x) { return x + 7; })(10);\n"
- "var h = (function(x) { return x + 8; })(10);\n"
- "var i = (function(x) { return x + 9; })(10);\n"
- "var j = (function(x) { return x + 10; })(10);");
- v8::V8::PauseProfiler();
- logger->StringEvent("test-profiler-stop-2", "");
- logger->StringEvent("test-stop", "");
-
- bool exists = false;
- i::Vector<const char> log(
- i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
- CHECK(exists);
-
- const char* test_start_position =
- StrNStr(log.start(), "test-start,", log.length());
- CHECK_NE(NULL, test_start_position);
- const char* test_profiler_start_position =
- StrNStr(log.start(), "test-profiler-start,", log.length());
- CHECK_NE(NULL, test_profiler_start_position);
- CHECK_GT(test_profiler_start_position, test_start_position);
- const char* test_profiler_stop_position =
- StrNStr(log.start(), "test-profiler-stop,", log.length());
- CHECK_NE(NULL, test_profiler_stop_position);
- CHECK_GT(test_profiler_stop_position, test_profiler_start_position);
- const char* test_profiler_start_2_position =
- StrNStr(log.start(), "test-profiler-start-2,", log.length());
- CHECK_NE(NULL, test_profiler_start_2_position);
- CHECK_GT(test_profiler_start_2_position, test_profiler_stop_position);
-
- // Nothing must be logged until profiling is resumed.
- CHECK_EQ(NULL, StrNStr(test_start_position,
- "code-creation,",
- static_cast<int>(test_profiler_start_position -
- test_start_position)));
- // Nothing must be logged while profiling is suspended.
- CHECK_EQ(NULL, StrNStr(test_profiler_stop_position,
- "code-creation,",
- static_cast<int>(test_profiler_start_2_position -
- test_profiler_stop_position)));
-}
-
-
// BUG(913). Need to implement support for profiling multiple VM threads.
#if 0
@@ -197,7 +127,7 @@ class LoopingThread : public v8::internal::Thread {
public:
explicit LoopingThread(v8::internal::Isolate* isolate)
: v8::internal::Thread(isolate),
- semaphore_(v8::internal::OS::CreateSemaphore(0)),
+ semaphore_(new v8::internal::Semaphore(0)),
run_(true) {
}
@@ -283,7 +213,7 @@ class TestSampler : public v8::internal::Sampler {
public:
explicit TestSampler(v8::internal::Isolate* isolate)
: Sampler(isolate, 0, true, true),
- semaphore_(v8::internal::OS::CreateSemaphore(0)),
+ semaphore_(new v8::internal::Semaphore(0)),
was_sample_stack_called_(false) {
}
@@ -396,7 +326,7 @@ static void ObjMethod1(const v8::FunctionCallbackInfo<v8::Value>& args) {
TEST(LogCallbacks) {
- ScopedLoggerInitializer initialize_logger(false);
+ ScopedLoggerInitializer initialize_logger;
Logger* logger = initialize_logger.logger();
v8::Local<v8::FunctionTemplate> obj =
@@ -445,7 +375,7 @@ static void Prop2Getter(v8::Local<v8::String> property,
TEST(LogAccessorCallbacks) {
- ScopedLoggerInitializer initialize_logger(false);
+ ScopedLoggerInitializer initialize_logger;
Logger* logger = initialize_logger.logger();
v8::Local<v8::FunctionTemplate> obj =
@@ -486,18 +416,6 @@ TEST(LogAccessorCallbacks) {
}
-TEST(IsLoggingPreserved) {
- ScopedLoggerInitializer initialize_logger(false);
- Logger* logger = initialize_logger.logger();
-
- CHECK(logger->is_logging());
- logger->ResumeProfiler();
- CHECK(logger->is_logging());
- logger->PauseProfiler();
- CHECK(logger->is_logging());
-}
-
-
typedef i::NativesCollection<i::TEST> TestSources;
@@ -509,12 +427,9 @@ TEST(EquivalenceOfLoggingAndTraversal) {
// it launches a new cctest instance for every test. To be sure that launching
// cctest manually also works, please be sure that no tests below
// are using V8.
- //
- // P.S. No, V8 can't be re-initialized after disposal, see include/v8.h.
- CHECK(!i::V8::IsRunning());
// Start with profiling to capture all code events from the beginning.
- ScopedLoggerInitializer initialize_logger(false);
+ ScopedLoggerInitializer initialize_logger;
Logger* logger = initialize_logger.logger();
// Compile and run a function that creates other functions.
@@ -523,7 +438,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
" obj.test =\n"
" (function a(j) { return function b() { return j; } })(100);\n"
"})(this);");
- v8::V8::PauseProfiler();
+ logger->StopProfiler();
HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
logger->StringEvent("test-logging-done", "");
diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc
index 0d8c00d2e1..33d9230e01 100644
--- a/deps/v8/test/cctest/test-mark-compact.cc
+++ b/deps/v8/test/cctest/test-mark-compact.cc
@@ -147,86 +147,88 @@ TEST(NoPromotion) {
TEST(MarkCompactCollector) {
+ FLAG_incremental_marking = false;
CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Heap* heap = isolate->heap();
v8::HandleScope sc(CcTest::isolate());
+
// call mark-compact when heap is empty
- HEAP->CollectGarbage(OLD_POINTER_SPACE);
+ heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 1");
// 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, "trigger 2");
- 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, "trigger 3");
+ mapp = heap->AllocateMap(JS_OBJECT_TYPE,
JSObject::kHeaderSize)->ToObjectChecked();
// allocate a garbage
String* func_name = String::cast(
- HEAP->InternalizeUtf8String("theFunction")->ToObjectChecked());
+ heap->InternalizeUtf8String("theFunction")->ToObjectChecked());
SharedFunctionInfo* function_share = SharedFunctionInfo::cast(
- HEAP->AllocateSharedFunctionInfo(func_name)->ToObjectChecked());
+ heap->AllocateSharedFunctionInfo(func_name)->ToObjectChecked());
JSFunction* function = JSFunction::cast(
- HEAP->AllocateFunction(*Isolate::Current()->function_map(),
+ heap->AllocateFunction(*isolate->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);
- Isolate::Current()->context()->global_object()->SetProperty(
+ isolate->context()->global_object()->SetProperty(
func_name, function, NONE, kNonStrictMode)->ToObjectChecked();
JSObject* obj = JSObject::cast(
- HEAP->AllocateJSObject(function)->ToObjectChecked());
- HEAP->CollectGarbage(OLD_POINTER_SPACE);
+ heap->AllocateJSObject(function)->ToObjectChecked());
+ heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 4");
func_name = String::cast(
- HEAP->InternalizeUtf8String("theFunction")->ToObjectChecked());
- CHECK(Isolate::Current()->context()->global_object()->
- HasLocalProperty(func_name));
- Object* func_value = Isolate::Current()->context()->global_object()->
+ heap->InternalizeUtf8String("theFunction")->ToObjectChecked());
+ CHECK(isolate->context()->global_object()->HasLocalProperty(func_name));
+ Object* func_value = isolate->context()->global_object()->
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->InternalizeUtf8String("theObject")->ToObjectChecked());
- Isolate::Current()->context()->global_object()->SetProperty(
+ String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
+ isolate->context()->global_object()->SetProperty(
obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked();
String* prop_name =
- String::cast(HEAP->InternalizeUtf8String("theSlot")->ToObjectChecked());
+ String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked());
obj->SetProperty(prop_name,
Smi::FromInt(23),
NONE,
kNonStrictMode)->ToObjectChecked();
- HEAP->CollectGarbage(OLD_POINTER_SPACE);
+ heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 5");
obj_name =
- String::cast(HEAP->InternalizeUtf8String("theObject")->ToObjectChecked());
- CHECK(Isolate::Current()->context()->global_object()->
- HasLocalProperty(obj_name));
- CHECK(Isolate::Current()->context()->global_object()->
+ String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
+ CHECK(isolate->context()->global_object()->HasLocalProperty(obj_name));
+ CHECK(isolate->context()->global_object()->
GetProperty(obj_name)->ToObjectChecked()->IsJSObject());
- obj = JSObject::cast(Isolate::Current()->context()->global_object()->
+ obj = JSObject::cast(isolate->context()->global_object()->
GetProperty(obj_name)->ToObjectChecked());
prop_name =
- String::cast(HEAP->InternalizeUtf8String("theSlot")->ToObjectChecked());
+ String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked());
CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23));
}
@@ -305,7 +307,7 @@ static void WeakPointerCallback(v8::Isolate* isolate,
void* id) {
ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -541,7 +543,7 @@ TEST(BootUpMemoryUse) {
intptr_t initial_memory = MemoryInUse();
// Avoid flakiness.
FLAG_crankshaft = false;
- FLAG_parallel_recompilation = false;
+ FLAG_concurrent_recompilation = false;
// Only Linux has the proc filesystem and only if it is mapped. If it's not
// there we just skip the test.
@@ -570,7 +572,7 @@ intptr_t ShortLivingIsolate() {
v8::Isolate* isolate = v8::Isolate::New();
{ v8::Isolate::Scope isolate_scope(isolate);
v8::Locker lock(isolate);
- v8::HandleScope handle_scope;
+ v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
CHECK(!context.IsEmpty());
}
diff --git a/deps/v8/test/cctest/test-mutex.cc b/deps/v8/test/cctest/test-mutex.cc
new file mode 100644
index 0000000000..cdc829f156
--- /dev/null
+++ b/deps/v8/test/cctest/test-mutex.cc
@@ -0,0 +1,118 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <cstdlib>
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "platform/mutex.h"
+
+using namespace ::v8::internal;
+
+
+TEST(LockGuardMutex) {
+ Mutex mutex;
+ { LockGuard<Mutex> lock_guard(&mutex);
+ }
+ { LockGuard<Mutex> lock_guard(&mutex);
+ }
+}
+
+
+TEST(LockGuardRecursiveMutex) {
+ RecursiveMutex recursive_mutex;
+ { LockGuard<RecursiveMutex> lock_guard(&recursive_mutex);
+ }
+ { LockGuard<RecursiveMutex> lock_guard1(&recursive_mutex);
+ LockGuard<RecursiveMutex> lock_guard2(&recursive_mutex);
+ }
+}
+
+
+TEST(LockGuardLazyMutex) {
+ LazyMutex lazy_mutex = LAZY_MUTEX_INITIALIZER;
+ { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer());
+ }
+ { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer());
+ }
+}
+
+
+TEST(LockGuardLazyRecursiveMutex) {
+ LazyRecursiveMutex lazy_recursive_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER;
+ { LockGuard<RecursiveMutex> lock_guard(lazy_recursive_mutex.Pointer());
+ }
+ { LockGuard<RecursiveMutex> lock_guard1(lazy_recursive_mutex.Pointer());
+ LockGuard<RecursiveMutex> lock_guard2(lazy_recursive_mutex.Pointer());
+ }
+}
+
+
+TEST(MultipleMutexes) {
+ Mutex mutex1;
+ Mutex mutex2;
+ Mutex mutex3;
+ // Order 1
+ mutex1.Lock();
+ mutex2.Lock();
+ mutex3.Lock();
+ mutex1.Unlock();
+ mutex2.Unlock();
+ mutex3.Unlock();
+ // Order 2
+ mutex1.Lock();
+ mutex2.Lock();
+ mutex3.Lock();
+ mutex3.Unlock();
+ mutex2.Unlock();
+ mutex1.Unlock();
+}
+
+
+TEST(MultipleRecursiveMutexes) {
+ RecursiveMutex recursive_mutex1;
+ RecursiveMutex recursive_mutex2;
+ // Order 1
+ recursive_mutex1.Lock();
+ recursive_mutex2.Lock();
+ CHECK(recursive_mutex1.TryLock());
+ CHECK(recursive_mutex2.TryLock());
+ recursive_mutex1.Unlock();
+ recursive_mutex1.Unlock();
+ recursive_mutex2.Unlock();
+ recursive_mutex2.Unlock();
+ // Order 2
+ recursive_mutex1.Lock();
+ CHECK(recursive_mutex1.TryLock());
+ recursive_mutex2.Lock();
+ CHECK(recursive_mutex2.TryLock());
+ recursive_mutex2.Unlock();
+ recursive_mutex1.Unlock();
+ recursive_mutex2.Unlock();
+ recursive_mutex1.Unlock();
+}
diff --git a/deps/v8/test/cctest/test-object-observe.cc b/deps/v8/test/cctest/test-object-observe.cc
index 44ddb6fa20..b129ff3af4 100644
--- a/deps/v8/test/cctest/test-object-observe.cc
+++ b/deps/v8/test/cctest/test-object-observe.cc
@@ -313,11 +313,13 @@ static void ExpectRecords(Handle<Value> records,
recordObj->Get(String::New("object"))));
CHECK(String::New(expectations[i].type)->Equals(
recordObj->Get(String::New("type"))));
- CHECK(String::New(expectations[i].name)->Equals(
- recordObj->Get(String::New("name"))));
- if (!expectations[i].old_value.IsEmpty()) {
- CHECK(expectations[i].old_value->Equals(
- recordObj->Get(String::New("oldValue"))));
+ if (strcmp("splice", expectations[i].type) != 0) {
+ CHECK(String::New(expectations[i].name)->Equals(
+ recordObj->Get(String::New("name"))));
+ if (!expectations[i].old_value.IsEmpty()) {
+ CHECK(expectations[i].old_value->Equals(
+ recordObj->Get(String::New("oldValue"))));
+ }
}
}
}
@@ -435,14 +437,281 @@ TEST(ObservationWeakMap) {
i::Handle<i::JSWeakMap> objectInfoMap =
i::Handle<i::JSWeakMap>::cast(
i::GetProperty(observation_state, "objectInfoMap"));
- i::Handle<i::JSWeakMap> notifierTargetMap =
+ i::Handle<i::JSWeakMap> notifierObjectInfoMap =
i::Handle<i::JSWeakMap>::cast(
- i::GetProperty(observation_state, "notifierTargetMap"));
+ i::GetProperty(observation_state, "notifierObjectInfoMap"));
CHECK_EQ(1, NumberOfElements(callbackInfoMap));
CHECK_EQ(1, NumberOfElements(objectInfoMap));
- CHECK_EQ(1, NumberOfElements(notifierTargetMap));
+ CHECK_EQ(1, NumberOfElements(notifierObjectInfoMap));
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(0, NumberOfElements(callbackInfoMap));
CHECK_EQ(0, NumberOfElements(objectInfoMap));
- CHECK_EQ(0, NumberOfElements(notifierTargetMap));
+ CHECK_EQ(0, NumberOfElements(notifierObjectInfoMap));
+}
+
+
+static bool NamedAccessAlwaysAllowed(Local<Object>, Local<Value>, AccessType,
+ Local<Value>) {
+ return true;
+}
+
+
+static bool IndexedAccessAlwaysAllowed(Local<Object>, uint32_t, AccessType,
+ Local<Value>) {
+ return true;
+}
+
+
+static AccessType g_access_block_type = ACCESS_GET;
+
+
+static bool NamedAccessAllowUnlessBlocked(Local<Object> host,
+ Local<Value> key,
+ AccessType type,
+ Local<Value>) {
+ if (type != g_access_block_type) return true;
+ Handle<Object> global = Context::GetCurrent()->Global();
+ Handle<Value> blacklist = global->Get(String::New("blacklist"));
+ if (!blacklist->IsObject()) return true;
+ if (key->IsString()) return !blacklist.As<Object>()->Has(key);
+ return true;
+}
+
+
+static bool IndexedAccessAllowUnlessBlocked(Local<Object> host,
+ uint32_t index,
+ AccessType type,
+ Local<Value>) {
+ if (type != ACCESS_GET) return true;
+ Handle<Object> global = Context::GetCurrent()->Global();
+ Handle<Value> blacklist = global->Get(String::New("blacklist"));
+ if (!blacklist->IsObject()) return true;
+ return !blacklist.As<Object>()->Has(index);
+}
+
+
+static bool BlockAccessKeys(Local<Object> host, Local<Value> key,
+ AccessType type, Local<Value>) {
+ Handle<Object> global = Context::GetCurrent()->Global();
+ Handle<Value> blacklist = global->Get(String::New("blacklist"));
+ if (!blacklist->IsObject()) return true;
+ return type != ACCESS_KEYS ||
+ !blacklist.As<Object>()->Has(String::New("__block_access_keys"));
+}
+
+
+static Handle<Object> CreateAccessCheckedObject(
+ NamedSecurityCallback namedCallback,
+ IndexedSecurityCallback indexedCallback) {
+ Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
+ tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback);
+ Handle<Object> instance = tmpl->NewInstance();
+ instance->CreationContext()->Global()->Set(String::New("obj"), instance);
+ return instance;
+}
+
+
+TEST(NamedAccessCheck) {
+ HarmonyIsolate isolate;
+ const AccessType types[] = { ACCESS_GET, ACCESS_HAS };
+ for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+ HandleScope scope(isolate.GetIsolate());
+ LocalContext context;
+ g_access_block_type = types[i];
+ Handle<Object> instance = CreateAccessCheckedObject(
+ NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed);
+ CompileRun("var records = null;"
+ "var objNoCheck = {};"
+ "var blacklist = {foo: true};"
+ "var observer = function(r) { records = r };"
+ "Object.observe(obj, observer);"
+ "Object.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("var records2 = null;"
+ "var observer2 = function(r) { records2 = r };"
+ "Object.observe(obj, observer2);"
+ "Object.observe(objNoCheck, observer2);"
+ "obj.foo = 'bar';"
+ "Object.defineProperty(obj, 'foo', {value: 5});"
+ "Object.defineProperty(obj, 'foo', {get: function(){}});"
+ "obj.bar = 'baz';"
+ "objNoCheck.baz = 'quux'");
+ const RecordExpectation expected_records2[] = {
+ { instance, "new", "foo", Handle<Value>() },
+ { instance, "updated", "foo", String::New("bar") },
+ { instance, "reconfigured", "foo", Number::New(5) },
+ { instance, "new", "bar", Handle<Value>() },
+ { obj_no_check, "new", "baz", Handle<Value>() },
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { instance, "new", "bar", Handle<Value>() },
+ { obj_no_check, "new", "baz", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+ }
+}
+
+
+TEST(IndexedAccessCheck) {
+ HarmonyIsolate isolate;
+ const AccessType types[] = { ACCESS_GET, ACCESS_HAS };
+ for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+ HandleScope scope(isolate.GetIsolate());
+ LocalContext context;
+ g_access_block_type = types[i];
+ Handle<Object> instance = CreateAccessCheckedObject(
+ NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked);
+ CompileRun("var records = null;"
+ "var objNoCheck = {};"
+ "var blacklist = {7: true};"
+ "var observer = function(r) { records = r };"
+ "Object.observe(obj, observer);"
+ "Object.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("var records2 = null;"
+ "var observer2 = function(r) { records2 = r };"
+ "Object.observe(obj, observer2);"
+ "Object.observe(objNoCheck, observer2);"
+ "obj[7] = 'foo';"
+ "Object.defineProperty(obj, '7', {value: 5});"
+ "Object.defineProperty(obj, '7', {get: function(){}});"
+ "obj[8] = 'bar';"
+ "objNoCheck[42] = 'quux'");
+ const RecordExpectation expected_records2[] = {
+ { instance, "new", "7", Handle<Value>() },
+ { instance, "updated", "7", String::New("foo") },
+ { instance, "reconfigured", "7", Number::New(5) },
+ { instance, "new", "8", Handle<Value>() },
+ { obj_no_check, "new", "42", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { instance, "new", "8", Handle<Value>() },
+ { obj_no_check, "new", "42", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+ }
+}
+
+
+TEST(SpliceAccessCheck) {
+ HarmonyIsolate isolate;
+ HandleScope scope(isolate.GetIsolate());
+ LocalContext context;
+ g_access_block_type = ACCESS_GET;
+ Handle<Object> instance = CreateAccessCheckedObject(
+ NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked);
+ CompileRun("var records = null;"
+ "obj[1] = 'foo';"
+ "obj.length = 2;"
+ "var objNoCheck = {1: 'bar', length: 2};"
+ "var blacklist = {1: true};"
+ "observer = function(r) { records = r };"
+ "Array.observe(obj, observer);"
+ "Array.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("var records2 = null;"
+ "var observer2 = function(r) { records2 = r };"
+ "Array.observe(obj, observer2);"
+ "Array.observe(objNoCheck, observer2);"
+ // No one should hear about this: no splice records are emitted
+ // for access-checked objects
+ "[].push.call(obj, 5);"
+ "[].splice.call(obj, 1, 1);"
+ "[].pop.call(obj);"
+ "[].pop.call(objNoCheck);");
+ // TODO(adamk): Extend EXPECT_RECORDS to be able to assert more things
+ // about splice records. For this test it's not so important since
+ // we just want to guarantee the machinery is in operation at all.
+ const RecordExpectation expected_records2[] = {
+ { obj_no_check, "splice", "", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { obj_no_check, "splice", "", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+}
+
+
+TEST(DisallowAllForAccessKeys) {
+ HarmonyIsolate isolate;
+ HandleScope scope(isolate.GetIsolate());
+ LocalContext context;
+ Handle<Object> instance = CreateAccessCheckedObject(
+ BlockAccessKeys, IndexedAccessAlwaysAllowed);
+ CompileRun("var records = null;"
+ "var objNoCheck = {};"
+ "var observer = function(r) { records = r };"
+ "var blacklist = {__block_access_keys: true};"
+ "Object.observe(obj, observer);"
+ "Object.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("var records2 = null;"
+ "var observer2 = function(r) { records2 = r };"
+ "Object.observe(obj, observer2);"
+ "Object.observe(objNoCheck, observer2);"
+ "obj.foo = 'bar';"
+ "obj[5] = 'baz';"
+ "objNoCheck.baz = 'quux'");
+ const RecordExpectation expected_records2[] = {
+ { instance, "new", "foo", Handle<Value>() },
+ { instance, "new", "5", Handle<Value>() },
+ { obj_no_check, "new", "baz", Handle<Value>() },
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { obj_no_check, "new", "baz", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+}
+
+
+TEST(AccessCheckDisallowApiModifications) {
+ HarmonyIsolate isolate;
+ HandleScope scope(isolate.GetIsolate());
+ LocalContext context;
+ Handle<Object> instance = CreateAccessCheckedObject(
+ BlockAccessKeys, IndexedAccessAlwaysAllowed);
+ CompileRun("var records = null;"
+ "var observer = function(r) { records = r };"
+ "var blacklist = {__block_access_keys: true};"
+ "Object.observe(obj, observer);");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ CompileRun("var records2 = null;"
+ "var observer2 = function(r) { records2 = r };"
+ "Object.observe(obj, observer2);");
+ instance->Set(5, String::New("bar"));
+ instance->Set(String::New("foo"), String::New("bar"));
+ CompileRun(""); // trigger delivery
+ const RecordExpectation expected_records2[] = {
+ { instance, "new", "5", Handle<Value>() },
+ { instance, "new", "foo", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ CHECK(CompileRun("records")->IsNull());
}
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index 999fe4c5bd..80b276c8f9 100644
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -313,9 +313,10 @@ TEST(StandAlonePreParserNoNatives) {
TEST(RegressChromium62639) {
v8::V8::Initialize();
+ i::Isolate* isolate = i::Isolate::Current();
int marker;
- i::Isolate::Current()->stack_guard()->SetStackLimit(
+ isolate->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
const char* program = "var x = 'something';\n"
@@ -328,7 +329,7 @@ TEST(RegressChromium62639) {
i::Utf8ToUtf16CharacterStream stream(
reinterpret_cast<const i::byte*>(program),
static_cast<unsigned>(strlen(program)));
- i::ScriptDataImpl* data = i::PreParserApi::PreParse(&stream);
+ i::ScriptDataImpl* data = i::PreParserApi::PreParse(isolate, &stream);
CHECK(data->HasError());
delete data;
}
@@ -355,7 +356,7 @@ TEST(Regress928) {
i::Handle<i::String> source(
factory->NewStringFromAscii(i::CStrVector(program)));
i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
- i::ScriptDataImpl* data = i::PreParserApi::PreParse(&stream);
+ i::ScriptDataImpl* data = i::PreParserApi::PreParse(isolate, &stream);
CHECK(!data->HasError());
data->Initialize();
@@ -1066,8 +1067,8 @@ i::Handle<i::String> FormatMessage(i::ScriptDataImpl* data) {
i::GetProperty(builtins, "FormatMessage");
i::Handle<i::Object> arg_handles[] = { format, args_array };
bool has_exception = false;
- i::Handle<i::Object> result =
- i::Execution::Call(format_fun, builtins, 2, arg_handles, &has_exception);
+ i::Handle<i::Object> result = i::Execution::Call(
+ isolate, format_fun, builtins, 2, arg_handles, &has_exception);
CHECK(!has_exception);
CHECK(result->IsString());
for (int i = 0; i < args.length(); i++) {
@@ -1263,10 +1264,6 @@ TEST(ParserSync) {
NULL
};
- // TODO(mstarzinger): Disabled in GC stress mode for now, we should find the
- // correct timeout for this and re-enable this test again.
- if (i::FLAG_stress_compaction) return;
-
i::Isolate* isolate = i::Isolate::Current();
i::Factory* factory = isolate->factory();
diff --git a/deps/v8/test/cctest/test-platform-linux.cc b/deps/v8/test/cctest/test-platform-linux.cc
index 6bb2902f41..f289e94828 100644
--- a/deps/v8/test/cctest/test-platform-linux.cc
+++ b/deps/v8/test/cctest/test-platform-linux.cc
@@ -39,60 +39,7 @@
using namespace ::v8::internal;
-static void yield() {
- usleep(1);
-}
-
-static const int kLockCounterLimit = 50;
-static int busy_lock_counter = 0;
-
-
-static void LoopIncrement(Mutex* mutex, int rem) {
- while (true) {
- int count = 0;
- int last_count = -1;
- do {
- CHECK_EQ(0, mutex->Lock());
- count = busy_lock_counter;
- CHECK_EQ(0, mutex->Unlock());
- yield();
- } while (count % 2 == rem && count < kLockCounterLimit);
- if (count >= kLockCounterLimit) break;
- CHECK_EQ(0, mutex->Lock());
- CHECK_EQ(count, busy_lock_counter);
- CHECK(last_count == -1 || count == last_count + 1);
- busy_lock_counter++;
- last_count = count;
- CHECK_EQ(0, mutex->Unlock());
- yield();
- }
-}
-
-
-static void* RunTestBusyLock(void* arg) {
- LoopIncrement(static_cast<Mutex*>(arg), 0);
- return 0;
-}
-
-
-// Runs two threads that repeatedly acquire the lock and conditionally
-// increment a variable.
-TEST(BusyLock) {
- pthread_t other;
- Mutex* mutex = OS::CreateMutex();
- int thread_created = pthread_create(&other,
- NULL,
- &RunTestBusyLock,
- mutex);
- CHECK_EQ(0, thread_created);
- LoopIncrement(mutex, 1);
- pthread_join(other, NULL);
- delete mutex;
-}
-
-
TEST(VirtualMemory) {
- OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
@@ -107,6 +54,5 @@ TEST(VirtualMemory) {
TEST(GetCurrentProcessId) {
- OS::SetUp();
CHECK_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
}
diff --git a/deps/v8/test/cctest/test-platform-nullos.cc b/deps/v8/test/cctest/test-platform-nullos.cc
deleted file mode 100644
index 3afbd90aec..0000000000
--- a/deps/v8/test/cctest/test-platform-nullos.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Tests of the TokenLock class from lock.h
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <unistd.h> // for usleep()
-
-#include "v8.h"
-
-#include "platform.h"
-#include "cctest.h"
-
-using namespace ::v8::internal;
-
-
-static void yield() {
- UNIMPLEMENTED();
-}
-
-static const int kLockCounterLimit = 50;
-static int busy_lock_counter = 0;
-
-
-static void LoopIncrement(Mutex* mutex, int rem) {
- while (true) {
- int count = 0;
- int last_count = -1;
- do {
- CHECK_EQ(0, mutex->Lock());
- count = busy_lock_counter;
- CHECK_EQ(0, mutex->Unlock());
- yield();
- } while (count % 2 == rem && count < kLockCounterLimit);
- if (count >= kLockCounterLimit) break;
- CHECK_EQ(0, mutex->Lock());
- CHECK_EQ(count, busy_lock_counter);
- CHECK(last_count == -1 || count == last_count + 1);
- busy_lock_counter++;
- last_count = count;
- CHECK_EQ(0, mutex->Unlock());
- yield();
- }
-}
-
-
-static void* RunTestBusyLock(void* arg) {
- LoopIncrement(static_cast<Mutex*>(arg), 0);
- return 0;
-}
-
-
-// Runs two threads that repeatedly acquire the lock and conditionally
-// increment a variable.
-TEST(BusyLock) {
- pthread_t other;
- Mutex* mutex = OS::CreateMutex();
- int thread_created = pthread_create(&other,
- NULL,
- &RunTestBusyLock,
- mutex);
- CHECK_EQ(0, thread_created);
- LoopIncrement(mutex, 1);
- pthread_join(other, NULL);
- delete mutex;
-}
-
-
-TEST(VirtualMemory) {
- VirtualMemory* vm = new VirtualMemory(1 * MB);
- CHECK(vm->IsReserved());
- void* block_addr = vm->address();
- size_t block_size = 4 * KB;
- CHECK(vm->Commit(block_addr, block_size, false));
- // Check whether we can write to memory.
- int* addr = static_cast<int*>(block_addr);
- addr[KB-1] = 2;
- CHECK(vm->Uncommit(block_addr, block_size));
- delete vm;
-}
diff --git a/deps/v8/test/cctest/test-platform-win32.cc b/deps/v8/test/cctest/test-platform-win32.cc
index a5089d360a..d7fdab11ed 100644
--- a/deps/v8/test/cctest/test-platform-win32.cc
+++ b/deps/v8/test/cctest/test-platform-win32.cc
@@ -39,7 +39,6 @@ using namespace ::v8::internal;
TEST(VirtualMemory) {
- OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
@@ -54,7 +53,6 @@ TEST(VirtualMemory) {
TEST(GetCurrentProcessId) {
- OS::SetUp();
CHECK_EQ(static_cast<int>(::GetCurrentProcessId()),
OS::GetCurrentProcessId());
}
diff --git a/deps/v8/test/cctest/test-platform.cc b/deps/v8/test/cctest/test-platform.cc
index 2d8eb201e8..079cbd121b 100644
--- a/deps/v8/test/cctest/test-platform.cc
+++ b/deps/v8/test/cctest/test-platform.cc
@@ -32,11 +32,6 @@
using namespace ::v8::internal;
-TEST(NumberOfCores) {
- CHECK_GT(OS::NumberOfCores(), 0);
-}
-
-
#ifdef __GNUC__
#define ASM __asm__ __volatile__
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index f56275c1be..7504b171de 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -132,14 +132,12 @@ TEST(ProfileTreeAddPathFromStart) {
CHECK_EQ(NULL, helper.Walk(&entry3));
ProfileNode* node1 = helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
ProfileNode* node2 = helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node2);
CHECK_NE(node1, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
@@ -147,18 +145,14 @@ TEST(ProfileTreeAddPathFromStart) {
CHECK_NE(NULL, node3);
CHECK_NE(node1, node3);
CHECK_NE(node2, node3);
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(1, node3->self_ticks());
tree.AddPathFromStart(path_vec);
CHECK_EQ(node1, helper.Walk(&entry1));
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
CodeEntry* path2[] = {&entry1, &entry2, &entry2};
@@ -172,12 +166,10 @@ TEST(ProfileTreeAddPathFromStart) {
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
CHECK_NE(NULL, node4);
CHECK_NE(node3, node4);
- CHECK_EQ(0, node4->total_ticks());
CHECK_EQ(1, node4->self_ticks());
}
@@ -199,14 +191,12 @@ TEST(ProfileTreeAddPathFromEnd) {
CHECK_EQ(NULL, helper.Walk(&entry3));
ProfileNode* node1 = helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
ProfileNode* node2 = helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node2);
CHECK_NE(node1, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
@@ -214,18 +204,14 @@ TEST(ProfileTreeAddPathFromEnd) {
CHECK_NE(NULL, node3);
CHECK_NE(node1, node3);
CHECK_NE(node2, node3);
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(1, node3->self_ticks());
tree.AddPathFromEnd(path_vec);
CHECK_EQ(node1, helper.Walk(&entry1));
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
CodeEntry* path2[] = {&entry2, &entry2, &entry1};
@@ -239,28 +225,18 @@ TEST(ProfileTreeAddPathFromEnd) {
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
CHECK_NE(NULL, node4);
CHECK_NE(node3, node4);
- CHECK_EQ(0, node4->total_ticks());
CHECK_EQ(1, node4->self_ticks());
}
TEST(ProfileTreeCalculateTotalTicks) {
ProfileTree empty_tree;
- CHECK_EQ(0, empty_tree.root()->total_ticks());
- CHECK_EQ(0, empty_tree.root()->self_ticks());
- empty_tree.CalculateTotalTicks();
- CHECK_EQ(0, empty_tree.root()->total_ticks());
CHECK_EQ(0, empty_tree.root()->self_ticks());
empty_tree.root()->IncrementSelfTicks();
- CHECK_EQ(0, empty_tree.root()->total_ticks());
- CHECK_EQ(1, empty_tree.root()->self_ticks());
- empty_tree.CalculateTotalTicks();
- CHECK_EQ(1, empty_tree.root()->total_ticks());
CHECK_EQ(1, empty_tree.root()->self_ticks());
CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
@@ -271,17 +247,11 @@ TEST(ProfileTreeCalculateTotalTicks) {
ProfileTree single_child_tree;
single_child_tree.AddPathFromStart(e1_path_vec);
single_child_tree.root()->IncrementSelfTicks();
- CHECK_EQ(0, single_child_tree.root()->total_ticks());
CHECK_EQ(1, single_child_tree.root()->self_ticks());
ProfileTreeTestHelper single_child_helper(&single_child_tree);
ProfileNode* node1 = single_child_helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
- CHECK_EQ(1, node1->self_ticks());
- single_child_tree.CalculateTotalTicks();
- CHECK_EQ(2, single_child_tree.root()->total_ticks());
CHECK_EQ(1, single_child_tree.root()->self_ticks());
- CHECK_EQ(1, node1->total_ticks());
CHECK_EQ(1, node1->self_ticks());
CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
@@ -297,24 +267,16 @@ TEST(ProfileTreeCalculateTotalTicks) {
flat_tree.AddPathFromStart(e1_e2_path_vec);
flat_tree.AddPathFromStart(e1_e2_path_vec);
// Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
- CHECK_EQ(0, flat_tree.root()->total_ticks());
CHECK_EQ(0, flat_tree.root()->self_ticks());
node1 = flat_helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(3, node2->self_ticks());
- flat_tree.CalculateTotalTicks();
// Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3}
- CHECK_EQ(5, flat_tree.root()->total_ticks());
CHECK_EQ(0, flat_tree.root()->self_ticks());
- CHECK_EQ(5, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
- CHECK_EQ(3, node2->total_ticks());
- CHECK_EQ(3, node2->self_ticks());
CodeEntry* e2_path[] = {&entry2};
Vector<CodeEntry*> e2_path_vec(
@@ -339,37 +301,26 @@ TEST(ProfileTreeCalculateTotalTicks) {
// Results in -> {entry1,0,2} -> {entry2,0,1}
// {root,0,0} -> {entry2,0,3}
// -> {entry3,0,4}
- CHECK_EQ(0, wide_tree.root()->total_ticks());
CHECK_EQ(0, wide_tree.root()->self_ticks());
node1 = wide_helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
ProfileNode* node1_2 = wide_helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node1_2);
- CHECK_EQ(0, node1_2->total_ticks());
CHECK_EQ(1, node1_2->self_ticks());
node2 = wide_helper.Walk(&entry2);
CHECK_NE(NULL, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(3, node2->self_ticks());
ProfileNode* node3 = wide_helper.Walk(&entry3);
CHECK_NE(NULL, node3);
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(4, node3->self_ticks());
- wide_tree.CalculateTotalTicks();
// Calculates -> {entry1,3,2} -> {entry2,1,1}
// {root,10,0} -> {entry2,3,3}
// -> {entry3,4,4}
- CHECK_EQ(10, wide_tree.root()->total_ticks());
CHECK_EQ(0, wide_tree.root()->self_ticks());
- CHECK_EQ(3, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
- CHECK_EQ(1, node1_2->total_ticks());
CHECK_EQ(1, node1_2->self_ticks());
- CHECK_EQ(3, node2->total_ticks());
CHECK_EQ(3, node2->self_ticks());
- CHECK_EQ(4, node3->total_ticks());
CHECK_EQ(4, node3->self_ticks());
}
@@ -448,7 +399,7 @@ class TestSetup {
TEST(RecordTickSample) {
TestSetup test_setup;
- CpuProfilesCollection profiles;
+ CpuProfilesCollection profiles(CcTest::i_isolate()->heap());
profiles.StartProfiling("", 1, false);
ProfileGenerator generator(&profiles);
CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
@@ -514,7 +465,7 @@ static void CheckNodeIds(ProfileNode* node, int* expectedId) {
TEST(SampleIds) {
TestSetup test_setup;
- CpuProfilesCollection profiles;
+ CpuProfilesCollection profiles(CcTest::i_isolate()->heap());
profiles.StartProfiling("", 1, true);
ProfileGenerator generator(&profiles);
CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
@@ -562,7 +513,7 @@ TEST(SampleIds) {
TEST(NoSamples) {
TestSetup test_setup;
- CpuProfilesCollection profiles;
+ CpuProfilesCollection profiles(CcTest::i_isolate()->heap());
profiles.StartProfiling("", 1, false);
ProfileGenerator generator(&profiles);
CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
@@ -701,7 +652,7 @@ TEST(RecordStackTraceAtStartProfiling) {
TEST(Issue51919) {
- CpuProfilesCollection collection;
+ CpuProfilesCollection collection(CcTest::i_isolate()->heap());
i::EmbeddedVector<char*,
CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
@@ -831,3 +782,49 @@ TEST(LineNumber) {
profiler->StopProfiling("LineNumber");
}
+
+
+
+TEST(BailoutReason) {
+ const char* extensions[] = { "v8/profiler" };
+ v8::ExtensionConfiguration config(1, extensions);
+ LocalContext env(&config);
+ v8::HandleScope hs(env->GetIsolate());
+
+ v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
+ CHECK_EQ(0, profiler->GetProfileCount());
+ v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New(
+ "function TryCatch() {\n"
+ " try {\n"
+ " startProfiling();\n"
+ " } catch (e) { };\n"
+ "}\n"
+ "function TryFinally() {\n"
+ " try {\n"
+ " TryCatch();\n"
+ " } finally { };\n"
+ "}\n"
+ "TryFinally();\n"
+ "stopProfiling();"));
+ script->Run();
+ CHECK_EQ(1, profiler->GetProfileCount());
+ const v8::CpuProfile* profile = profiler->GetCpuProfile(0);
+ const v8::CpuProfileNode* current = profile->GetTopDownRoot();
+ reinterpret_cast<ProfileNode*>(
+ const_cast<v8::CpuProfileNode*>(current))->Print(0);
+ // The tree should look like this:
+ // (root)
+ // (anonymous function)
+ // kTryFinally
+ // kTryCatch
+ current = PickChild(current, i::ProfileGenerator::kAnonymousFunctionName);
+ CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
+
+ current = PickChild(current, "TryFinally");
+ CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
+ CHECK(!strcmp("TryFinallyStatement", current->GetBailoutReason()));
+
+ current = PickChild(current, "TryCatch");
+ CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
+ CHECK(!strcmp("TryCatchStatement", current->GetBailoutReason()));
+}
diff --git a/deps/v8/test/cctest/test-random-number-generator.cc b/deps/v8/test/cctest/test-random-number-generator.cc
new file mode 100644
index 0000000000..93f3257003
--- /dev/null
+++ b/deps/v8/test/cctest/test-random-number-generator.cc
@@ -0,0 +1,92 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "utils/random-number-generator.h"
+
+using namespace v8::internal;
+
+
+static const int kMaxRuns = 12345;
+static const int kRandomSeeds[] = {
+ -1, 1, 42, 100, 1234567890, 987654321
+};
+
+
+TEST(NextIntWithMaxValue) {
+ for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
+ RandomNumberGenerator rng(kRandomSeeds[n]);
+ for (int max = 1; max <= kMaxRuns; ++max) {
+ int n = rng.NextInt(max);
+ CHECK_LE(0, n);
+ CHECK_LT(n, max);
+ }
+ }
+}
+
+
+TEST(NextBoolReturnsBooleanValue) {
+ for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
+ RandomNumberGenerator rng(kRandomSeeds[n]);
+ for (int k = 0; k < kMaxRuns; ++k) {
+ bool b = rng.NextBool();
+ CHECK(b == false || b == true);
+ }
+ }
+}
+
+
+TEST(NextDoubleRange) {
+ for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
+ RandomNumberGenerator rng(kRandomSeeds[n]);
+ for (int k = 0; k < kMaxRuns; ++k) {
+ double d = rng.NextDouble();
+ CHECK_LE(0.0, d);
+ CHECK_LT(d, 1.0);
+ }
+ }
+}
+
+
+TEST(RandomSeedFlagIsUsed) {
+ for (unsigned n = 0; n < ARRAY_SIZE(kRandomSeeds); ++n) {
+ FLAG_random_seed = kRandomSeeds[n];
+ RandomNumberGenerator rng1;
+ RandomNumberGenerator rng2(kRandomSeeds[n]);
+ for (int k = 1; k <= kMaxRuns; ++k) {
+ int64_t i1, i2;
+ rng1.NextBytes(&i1, sizeof(i1));
+ rng2.NextBytes(&i2, sizeof(i2));
+ CHECK_EQ(i2, i1);
+ CHECK_EQ(rng2.NextInt(), rng1.NextInt());
+ CHECK_EQ(rng2.NextInt(k), rng1.NextInt(k));
+ CHECK_EQ(rng2.NextDouble(), rng1.NextDouble());
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/test-random.cc b/deps/v8/test/cctest/test-random.cc
index 0a8594c04e..4227326a92 100644
--- a/deps/v8/test/cctest/test-random.cc
+++ b/deps/v8/test/cctest/test-random.cc
@@ -53,8 +53,8 @@ void TestSeeds(Handle<JSFunction> fun,
Handle<ByteArray> seeds(context->random_seed());
SetSeeds(seeds, state0, state1);
- Handle<Object> value =
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Handle<Object> value = Execution::Call(
+ context->GetIsolate(), fun, global, 0, NULL, &has_pending_exception);
CHECK(value->IsHeapNumber());
CHECK(fun->IsOptimized());
double crankshaft_value = HeapNumber::cast(*value)->value();
@@ -69,12 +69,13 @@ void TestSeeds(Handle<JSFunction> fun,
TEST(CrankshaftRandom) {
v8::V8::Initialize();
// Skip test if crankshaft is disabled.
- if (!V8::UseCrankshaft()) return;
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope scope(isolate);
- v8::Context::Scope context_scope(v8::Context::New(isolate));
+ if (!Isolate::Current()->use_crankshaft()) return;
+ v8::Isolate* v8_isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope scope(v8_isolate);
+ v8::Context::Scope context_scope(v8::Context::New(v8_isolate));
- Handle<Context> context(Isolate::Current()->context());
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ Handle<Context> context(isolate->context());
Handle<JSObject> global(context->global_object());
Handle<ByteArray> seeds(context->random_seed());
bool has_pending_exception;
@@ -88,21 +89,12 @@ TEST(CrankshaftRandom) {
Handle<JSFunction> fun(JSFunction::cast(fun_object->ToObjectChecked()));
// Optimize function.
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
+ Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception);
if (!fun->IsOptimized()) fun->MarkForLazyRecompilation();
// Test with some random values.
TestSeeds(fun, context, 0xC0C0AFFE, 0x31415926);
TestSeeds(fun, context, 0x01020304, 0xFFFFFFFF);
- TestSeeds(fun, context, 0x00000001, 0x00000000);
-
- // Test that we bail out to runtime when seeds are uninitialized (zeros).
- SetSeeds(seeds, 0, 0);
- Handle<Object> value =
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
- CHECK(value->IsHeapNumber());
- CHECK(fun->IsOptimized());
- double crankshaft_value = HeapNumber::cast(*value)->value();
- CHECK_NE(0.0, crankshaft_value);
+ TestSeeds(fun, context, 0x00000001, 0x00000001);
}
diff --git a/deps/v8/test/cctest/test-semaphore.cc b/deps/v8/test/cctest/test-semaphore.cc
new file mode 100644
index 0000000000..895303f4f8
--- /dev/null
+++ b/deps/v8/test/cctest/test-semaphore.cc
@@ -0,0 +1,155 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "platform.h"
+#include "cctest.h"
+
+
+using namespace ::v8::internal;
+
+
+class WaitAndSignalThread V8_FINAL : public Thread {
+ public:
+ explicit WaitAndSignalThread(Semaphore* semaphore)
+ : Thread("WaitAndSignalThread"), semaphore_(semaphore) {}
+ virtual ~WaitAndSignalThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ for (int n = 0; n < 1000; ++n) {
+ semaphore_->Wait();
+ bool result = semaphore_->WaitFor(TimeDelta::FromMicroseconds(1));
+ ASSERT(!result);
+ USE(result);
+ semaphore_->Signal();
+ }
+ }
+
+ private:
+ Semaphore* semaphore_;
+};
+
+
+TEST(WaitAndSignal) {
+ Semaphore semaphore(0);
+ WaitAndSignalThread t1(&semaphore);
+ WaitAndSignalThread t2(&semaphore);
+
+ t1.Start();
+ t2.Start();
+
+ // Make something available.
+ semaphore.Signal();
+
+ t1.Join();
+ t2.Join();
+
+ semaphore.Wait();
+
+ bool result = semaphore.WaitFor(TimeDelta::FromMicroseconds(1));
+ ASSERT(!result);
+ USE(result);
+}
+
+
+TEST(WaitFor) {
+ bool ok;
+ Semaphore semaphore(0);
+
+ // Semaphore not signalled - timeout.
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
+ CHECK(!ok);
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
+ CHECK(!ok);
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
+ CHECK(!ok);
+
+ // Semaphore signalled - no timeout.
+ semaphore.Signal();
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
+ CHECK(ok);
+ semaphore.Signal();
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
+ CHECK(ok);
+ semaphore.Signal();
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
+ CHECK(ok);
+}
+
+
+static const char alphabet[] = "XKOAD";
+static const int kAlphabetSize = sizeof(alphabet) - 1;
+static const int kBufferSize = 4096; // GCD(buffer size, alphabet size) = 1
+static char buffer[kBufferSize];
+static const int kDataSize = kBufferSize * kAlphabetSize * 10;
+
+static Semaphore free_space(kBufferSize);
+static Semaphore used_space(0);
+
+
+class ProducerThread V8_FINAL : public Thread {
+ public:
+ ProducerThread() : Thread("ProducerThread") {}
+ virtual ~ProducerThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ for (int n = 0; n < kDataSize; ++n) {
+ free_space.Wait();
+ buffer[n % kBufferSize] = alphabet[n % kAlphabetSize];
+ used_space.Signal();
+ }
+ }
+};
+
+
+class ConsumerThread V8_FINAL : public Thread {
+ public:
+ ConsumerThread() : Thread("ConsumerThread") {}
+ virtual ~ConsumerThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ for (int n = 0; n < kDataSize; ++n) {
+ used_space.Wait();
+ ASSERT_EQ(static_cast<int>(alphabet[n % kAlphabetSize]),
+ static_cast<int>(buffer[n % kBufferSize]));
+ free_space.Signal();
+ }
+ }
+};
+
+
+TEST(ProducerConsumer) {
+ ProducerThread producer_thread;
+ ConsumerThread consumer_thread;
+ producer_thread.Start();
+ consumer_thread.Start();
+ producer_thread.Join();
+ consumer_thread.Join();
+}
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index f95ff65725..099f3a05a9 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -104,7 +104,7 @@ TEST(ExternalReferenceEncoder) {
isolate->stats_table()->SetCounterFunction(counter_function);
v8::V8::Initialize();
- ExternalReferenceEncoder encoder;
+ ExternalReferenceEncoder encoder(isolate);
CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode),
Encode(encoder, Builtins::kArrayCode));
CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
@@ -141,7 +141,7 @@ TEST(ExternalReferenceDecoder) {
isolate->stats_table()->SetCounterFunction(counter_function);
v8::V8::Initialize();
- ExternalReferenceDecoder decoder;
+ ExternalReferenceDecoder decoder(isolate);
CHECK_EQ(AddressOf(Builtins::kArrayCode),
decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
CHECK_EQ(AddressOf(Runtime::kAbort),
@@ -228,9 +228,9 @@ void FileByteSink::WriteSpaceUsed(
}
-static bool WriteToFile(const char* snapshot_file) {
+static bool WriteToFile(Isolate* isolate, const char* snapshot_file) {
FileByteSink file(snapshot_file);
- StartupSerializer ser(&file);
+ StartupSerializer ser(isolate, &file);
ser.Serialize();
file.WriteSpaceUsed(
@@ -251,19 +251,20 @@ static void Serialize() {
// can be loaded from v8natives.js and their addresses can be processed. This
// will clear the pending fixups array, which would otherwise contain GC roots
// that would confuse the serialization/deserialization process.
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
v8::Context::New(isolate);
}
- WriteToFile(FLAG_testing_serialization_file);
+ WriteToFile(reinterpret_cast<Isolate*>(isolate),
+ FLAG_testing_serialization_file);
}
// Test that the whole heap can be serialized.
TEST(Serialize) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::Enable();
+ Serializer::Enable(Isolate::Current());
v8::V8::Initialize();
Serialize();
}
@@ -273,7 +274,7 @@ TEST(Serialize) {
// Test that heap serialization is non-destructive.
TEST(SerializeTwice) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::Enable();
+ Serializer::Enable(Isolate::Current());
v8::V8::Initialize();
Serialize();
Serialize();
@@ -371,9 +372,9 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
TEST(PartialSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::Enable();
- v8::V8::Initialize();
Isolate* isolate = Isolate::Current();
+ Serializer::Enable(isolate);
+ v8::V8::Initialize();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Heap* heap = isolate->heap();
@@ -412,14 +413,14 @@ TEST(PartialSerialization) {
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
}
- env.Dispose(v8_isolate);
+ env.Dispose();
FileByteSink startup_sink(startup_name.start());
- StartupSerializer startup_serializer(&startup_sink);
+ StartupSerializer startup_serializer(isolate, &startup_sink);
startup_serializer.SerializeStrongReferences();
FileByteSink partial_sink(FLAG_testing_serialization_file);
- PartialSerializer p_ser(&startup_serializer, &partial_sink);
+ PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
p_ser.Serialize(&raw_foo);
startup_serializer.SerializeWeakReferences();
@@ -494,16 +495,17 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
int snapshot_size = 0;
byte* snapshot = ReadBytes(file_name, &snapshot_size);
+ Isolate* isolate = Isolate::Current();
Object* root;
{
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
ReserveSpaceForSnapshot(&deserializer, file_name);
- deserializer.DeserializePartial(&root);
+ deserializer.DeserializePartial(isolate, &root);
CHECK(root->IsString());
}
- v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
- Handle<Object> root_handle(root, Isolate::Current());
+ HandleScope handle_scope(isolate);
+ Handle<Object> root_handle(root, isolate);
Object* root2;
@@ -511,7 +513,7 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
ReserveSpaceForSnapshot(&deserializer, file_name);
- deserializer.DeserializePartial(&root2);
+ deserializer.DeserializePartial(isolate, &root2);
CHECK(root2->IsString());
CHECK(*root_handle == root2);
}
@@ -521,9 +523,9 @@ DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
TEST(ContextSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
- Serializer::Enable();
- v8::V8::Initialize();
Isolate* isolate = Isolate::Current();
+ Serializer::Enable(isolate);
+ v8::V8::Initialize();
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Heap* heap = isolate->heap();
@@ -558,14 +560,14 @@ TEST(ContextSerialization) {
i::Object* raw_context = *v8::Utils::OpenPersistent(env);
- env.Dispose(v8_isolate);
+ env.Dispose();
FileByteSink startup_sink(startup_name.start());
- StartupSerializer startup_serializer(&startup_sink);
+ StartupSerializer startup_serializer(isolate, &startup_sink);
startup_serializer.SerializeStrongReferences();
FileByteSink partial_sink(FLAG_testing_serialization_file);
- PartialSerializer p_ser(&startup_serializer, &partial_sink);
+ PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
p_ser.Serialize(&raw_context);
startup_serializer.SerializeWeakReferences();
@@ -605,16 +607,17 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
int snapshot_size = 0;
byte* snapshot = ReadBytes(file_name, &snapshot_size);
+ Isolate* isolate = Isolate::Current();
Object* root;
{
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
ReserveSpaceForSnapshot(&deserializer, file_name);
- deserializer.DeserializePartial(&root);
+ deserializer.DeserializePartial(isolate, &root);
CHECK(root->IsContext());
}
- v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
- Handle<Object> root_handle(root, Isolate::Current());
+ HandleScope handle_scope(isolate);
+ Handle<Object> root_handle(root, isolate);
Object* root2;
@@ -622,7 +625,7 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
ReserveSpaceForSnapshot(&deserializer, file_name);
- deserializer.DeserializePartial(&root2);
+ deserializer.DeserializePartial(isolate, &root2);
CHECK(root2->IsContext());
CHECK(*root_handle != root2);
}
diff --git a/deps/v8/test/cctest/test-sockets.cc b/deps/v8/test/cctest/test-socket.cc
index a9e31fc89d..47d8b17831 100644
--- a/deps/v8/test/cctest/test-sockets.cc
+++ b/deps/v8/test/cctest/test-socket.cc
@@ -27,6 +27,7 @@
#include "v8.h"
#include "platform.h"
+#include "platform/socket.h"
#include "cctest.h"
@@ -41,19 +42,18 @@ class SocketListenerThread : public Thread {
data_size_(data_size),
server_(NULL),
client_(NULL),
- listening_(OS::CreateSemaphore(0)) {
+ listening_(0) {
data_ = new char[data_size_];
}
~SocketListenerThread() {
// Close both sockets.
delete client_;
delete server_;
- delete listening_;
delete[] data_;
}
void Run();
- void WaitForListening() { listening_->Wait(); }
+ void WaitForListening() { listening_.Wait(); }
char* data() { return data_; }
private:
@@ -62,7 +62,7 @@ class SocketListenerThread : public Thread {
int data_size_;
Socket* server_; // Server socket used for bind/accept.
Socket* client_; // Single client connection used by the test.
- Semaphore* listening_; // Signalled when the server socket is in listen mode.
+ Semaphore listening_; // Signalled when the server socket is in listen mode.
};
@@ -70,7 +70,7 @@ void SocketListenerThread::Run() {
bool ok;
// Create the server socket and bind it to the requested port.
- server_ = OS::CreateSocket();
+ server_ = new Socket;
server_->SetReuseAddress(true);
CHECK(server_ != NULL);
ok = server_->Bind(port_);
@@ -79,7 +79,7 @@ void SocketListenerThread::Run() {
// Listen for new connections.
ok = server_->Listen(1);
CHECK(ok);
- listening_->Signal();
+ listening_.Signal();
// Accept a connection.
client_ = server_->Accept();
@@ -122,7 +122,7 @@ static void SendAndReceive(int port, char *data, int len) {
listener->WaitForListening();
// Connect and write some data.
- Socket* client = OS::CreateSocket();
+ Socket* client = new Socket;
CHECK(client != NULL);
ok = client->Connect(kLocalhost, port_str);
CHECK(ok);
@@ -151,12 +151,6 @@ TEST(Socket) {
// parallel.
static const int kPort = 5859 + FlagDependentPortOffset();
- bool ok;
-
- // Initialize socket support.
- ok = Socket::SetUp();
- CHECK(ok);
-
// Send and receive some data.
static const int kBufferSizeSmall = 20;
char small_data[kBufferSizeSmall + 1] = "1234567890abcdefghij";
@@ -180,12 +174,3 @@ TEST(Socket) {
SendAndReceive(kPort, large_data, kBufferSizeLarge);
delete[] large_data;
}
-
-
-TEST(HToNNToH) {
- uint16_t x = 1234;
- CHECK_EQ(x, Socket::NToH(Socket::HToN(x)));
-
- uint32_t y = 12345678;
- CHECK(y == Socket::NToH(Socket::HToN(y)));
-}
diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc
index 1f362d7e7a..3326a015de 100644
--- a/deps/v8/test/cctest/test-spaces.cc
+++ b/deps/v8/test/cctest/test-spaces.cc
@@ -207,7 +207,6 @@ static unsigned int Pseudorandom() {
TEST(MemoryChunk) {
- OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
@@ -264,7 +263,6 @@ TEST(MemoryChunk) {
TEST(MemoryAllocator) {
- OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
@@ -314,7 +312,6 @@ TEST(MemoryAllocator) {
TEST(NewSpace) {
- OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
@@ -344,7 +341,6 @@ TEST(NewSpace) {
TEST(OldSpace) {
- OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 726188d917..9049df1b72 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -41,9 +41,9 @@
#include "zone-inl.h"
// Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry
-class RandomNumberGenerator {
+class MyRandomNumberGenerator {
public:
- RandomNumberGenerator() {
+ MyRandomNumberGenerator() {
init();
}
@@ -133,7 +133,7 @@ class AsciiResource: public v8::String::ExternalAsciiStringResource,
static void InitializeBuildingBlocks(Handle<String>* building_blocks,
int bb_length,
bool long_blocks,
- RandomNumberGenerator* rng,
+ MyRandomNumberGenerator* rng,
Zone* zone) {
// A list of pointers that we don't have any interest in cleaning up.
// If they are reachable from a root then leak detection won't complain.
@@ -276,7 +276,7 @@ class ConsStringGenerationData {
// Cached data.
Handle<String> building_blocks_[kNumberOfBuildingBlocks];
String* empty_string_;
- RandomNumberGenerator rng_;
+ MyRandomNumberGenerator rng_;
// Stats.
ConsStringStats stats_;
unsigned early_terminations_;
diff --git a/deps/v8/test/cctest/test-strtod.cc b/deps/v8/test/cctest/test-strtod.cc
index 952f57cf3b..237d35db12 100644
--- a/deps/v8/test/cctest/test-strtod.cc
+++ b/deps/v8/test/cctest/test-strtod.cc
@@ -432,7 +432,7 @@ static uint32_t DeterministicRandom() {
static uint32_t lo = 0;
// Initialization values don't have any special meaning. (They are the result
- // of two calls to random().)
+ // of two calls to rand().)
if (hi == 0) hi = 0xbfe166e7;
if (lo == 0) lo = 0x64d1c3c9;
@@ -448,12 +448,13 @@ static const int kShortStrtodRandomCount = 2;
static const int kLargeStrtodRandomCount = 2;
TEST(RandomStrtod) {
+ srand(static_cast<unsigned int>(time(NULL)));
char buffer[kBufferSize];
for (int length = 1; length < 15; length++) {
for (int i = 0; i < kShortStrtodRandomCount; ++i) {
int pos = 0;
for (int j = 0; j < length; ++j) {
- buffer[pos++] = random() % 10 + '0';
+ buffer[pos++] = rand() % 10 + '0';
}
int exponent = DeterministicRandom() % (25*2 + 1) - 25 - length;
buffer[pos] = '\0';
@@ -466,7 +467,7 @@ TEST(RandomStrtod) {
for (int i = 0; i < kLargeStrtodRandomCount; ++i) {
int pos = 0;
for (int j = 0; j < length; ++j) {
- buffer[pos++] = random() % 10 + '0';
+ buffer[pos++] = rand() % 10 + '0';
}
int exponent = DeterministicRandom() % (308*2 + 1) - 308 - length;
buffer[pos] = '\0';
diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc
index b29b1dcf0c..b89f3ef8cf 100644
--- a/deps/v8/test/cctest/test-thread-termination.cc
+++ b/deps/v8/test/cctest/test-thread-termination.cc
@@ -171,7 +171,7 @@ class TerminatorThread : public v8::internal::Thread {
// Test that a single thread of JavaScript execution can be terminated
// from the side by another thread.
TEST(TerminateOnlyV8ThreadFromOtherThread) {
- semaphore = v8::internal::OS::CreateSemaphore(0);
+ semaphore = new v8::internal::Semaphore(0);
TerminatorThread thread(i::Isolate::Current());
thread.Start();
@@ -192,73 +192,6 @@ TEST(TerminateOnlyV8ThreadFromOtherThread) {
}
-class LoopingThread : public v8::internal::Thread {
- public:
- LoopingThread() : Thread("LoopingThread") { }
- void Run() {
- v8::Locker locker(CcTest::default_isolate());
- v8::HandleScope scope(CcTest::default_isolate());
- v8_thread_id_ = v8::V8::GetCurrentThreadId();
- v8::Handle<v8::ObjectTemplate> global =
- CreateGlobalTemplate(Signal, DoLoop);
- v8::Handle<v8::Context> context =
- v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
- v8::Context::Scope context_scope(context);
- CHECK(!v8::V8::IsExecutionTerminating());
- // Run a loop that will be infinite if thread termination does not work.
- v8::Handle<v8::String> source =
- v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
- v8::Script::Compile(source)->Run();
- }
-
- int GetV8ThreadId() { return v8_thread_id_; }
-
- private:
- int v8_thread_id_;
-};
-
-
-// Test that multiple threads using default isolate can be terminated
-// from another thread when using Lockers and preemption.
-TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
- {
- v8::Locker locker(CcTest::default_isolate());
- v8::V8::Initialize();
- v8::Locker::StartPreemption(1);
- semaphore = v8::internal::OS::CreateSemaphore(0);
- }
- 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(CcTest::default_isolate());
- 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];
- }
- {
- v8::Locker locker(CcTest::default_isolate());
- v8::Locker::StopPreemption();
- }
-
- delete semaphore;
- semaphore = NULL;
-}
-
-
int call_count = 0;
@@ -391,11 +324,11 @@ void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
// Test that a single thread of JavaScript execution can terminate
// itself and then resume execution.
TEST(TerminateCancelTerminateFromThreadItself) {
- v8::HandleScope scope;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> global =
CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate);
- v8::Handle<v8::Context> context =
- v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
+ v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global);
v8::Context::Scope context_scope(context);
CHECK(!v8::V8::IsExecutionTerminating());
v8::Handle<v8::String> source =
@@ -403,4 +336,3 @@ TEST(TerminateCancelTerminateFromThreadItself) {
// Check that execution completed with correct return value.
CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed")));
}
-
diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc
index a35a88dc26..6cc5f52338 100644
--- a/deps/v8/test/cctest/test-threads.cc
+++ b/deps/v8/test/cctest/test-threads.cc
@@ -180,7 +180,7 @@ TEST(ThreadIdValidation) {
const int kNThreads = 100;
i::List<ThreadIdValidationThread*> threads(kNThreads);
i::List<i::ThreadId> refs(kNThreads);
- i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
+ i::Semaphore* semaphore = new i::Semaphore(0);
ThreadIdValidationThread* prev = NULL;
for (int i = kNThreads - 1; i >= 0; i--) {
ThreadIdValidationThread* newThread =
diff --git a/deps/v8/test/cctest/test-time.cc b/deps/v8/test/cctest/test-time.cc
new file mode 100644
index 0000000000..8b92d8d32a
--- /dev/null
+++ b/deps/v8/test/cctest/test-time.cc
@@ -0,0 +1,144 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <cstdlib>
+
+#include "v8.h"
+
+#include "cctest.h"
+#if V8_OS_WIN
+#include "win32-headers.h"
+#endif
+
+using namespace v8::internal;
+
+
+TEST(TimeDeltaFromAndIn) {
+ CHECK(TimeDelta::FromDays(2) == TimeDelta::FromHours(48));
+ CHECK(TimeDelta::FromHours(3) == TimeDelta::FromMinutes(180));
+ CHECK(TimeDelta::FromMinutes(2) == TimeDelta::FromSeconds(120));
+ CHECK(TimeDelta::FromSeconds(2) == TimeDelta::FromMilliseconds(2000));
+ CHECK(TimeDelta::FromMilliseconds(2) == TimeDelta::FromMicroseconds(2000));
+ CHECK_EQ(static_cast<int>(13), TimeDelta::FromDays(13).InDays());
+ CHECK_EQ(static_cast<int>(13), TimeDelta::FromHours(13).InHours());
+ CHECK_EQ(static_cast<int>(13), TimeDelta::FromMinutes(13).InMinutes());
+ CHECK_EQ(static_cast<int64_t>(13), TimeDelta::FromSeconds(13).InSeconds());
+ CHECK_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF());
+ CHECK_EQ(static_cast<int64_t>(13),
+ TimeDelta::FromMilliseconds(13).InMilliseconds());
+ CHECK_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF());
+ CHECK_EQ(static_cast<int64_t>(13),
+ TimeDelta::FromMicroseconds(13).InMicroseconds());
+}
+
+
+#if V8_OS_MACOSX
+TEST(TimeDeltaFromMachTimespec) {
+ TimeDelta null = TimeDelta();
+ CHECK(null == TimeDelta::FromMachTimespec(null.ToMachTimespec()));
+ TimeDelta delta1 = TimeDelta::FromMilliseconds(42);
+ CHECK(delta1 == TimeDelta::FromMachTimespec(delta1.ToMachTimespec()));
+ TimeDelta delta2 = TimeDelta::FromDays(42);
+ CHECK(delta2 == TimeDelta::FromMachTimespec(delta2.ToMachTimespec()));
+}
+#endif
+
+
+TEST(TimeJsTime) {
+ Time t = Time::FromJsTime(700000.3);
+ CHECK_EQ(700000.3, t.ToJsTime());
+}
+
+
+#if V8_OS_POSIX
+TEST(TimeFromTimespec) {
+ Time null;
+ CHECK(null.IsNull());
+ CHECK(null == Time::FromTimespec(null.ToTimespec()));
+ Time now = Time::Now();
+ CHECK(now == Time::FromTimespec(now.ToTimespec()));
+ Time now_sys = Time::NowFromSystemTime();
+ CHECK(now_sys == Time::FromTimespec(now_sys.ToTimespec()));
+ Time unix_epoch = Time::UnixEpoch();
+ CHECK(unix_epoch == Time::FromTimespec(unix_epoch.ToTimespec()));
+ Time max = Time::Max();
+ CHECK(max.IsMax());
+ CHECK(max == Time::FromTimespec(max.ToTimespec()));
+}
+
+
+TEST(TimeFromTimeval) {
+ Time null;
+ CHECK(null.IsNull());
+ CHECK(null == Time::FromTimeval(null.ToTimeval()));
+ Time now = Time::Now();
+ CHECK(now == Time::FromTimeval(now.ToTimeval()));
+ Time now_sys = Time::NowFromSystemTime();
+ CHECK(now_sys == Time::FromTimeval(now_sys.ToTimeval()));
+ Time unix_epoch = Time::UnixEpoch();
+ CHECK(unix_epoch == Time::FromTimeval(unix_epoch.ToTimeval()));
+ Time max = Time::Max();
+ CHECK(max.IsMax());
+ CHECK(max == Time::FromTimeval(max.ToTimeval()));
+}
+#endif
+
+
+#if V8_OS_WIN
+TEST(TimeFromFiletime) {
+ Time null;
+ CHECK(null.IsNull());
+ CHECK(null == Time::FromFiletime(null.ToFiletime()));
+ Time now = Time::Now();
+ CHECK(now == Time::FromFiletime(now.ToFiletime()));
+ Time now_sys = Time::NowFromSystemTime();
+ CHECK(now_sys == Time::FromFiletime(now_sys.ToFiletime()));
+ Time unix_epoch = Time::UnixEpoch();
+ CHECK(unix_epoch == Time::FromFiletime(unix_epoch.ToFiletime()));
+ Time max = Time::Max();
+ CHECK(max.IsMax());
+ CHECK(max == Time::FromFiletime(max.ToFiletime()));
+}
+#endif
+
+
+TEST(TimeTicksIsMonotonic) {
+ TimeTicks previous_normal_ticks;
+ TimeTicks previous_highres_ticks;
+ ElapsedTimer timer;
+ timer.Start();
+ while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) {
+ TimeTicks normal_ticks = TimeTicks::Now();
+ TimeTicks highres_ticks = TimeTicks::HighResNow();
+ CHECK_GE(normal_ticks, previous_normal_ticks);
+ CHECK_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0);
+ CHECK_GE(highres_ticks, previous_highres_ticks);
+ CHECK_GE((highres_ticks - previous_highres_ticks).InMicroseconds(), 0);
+ previous_normal_ticks = normal_ticks;
+ previous_highres_ticks = highres_ticks;
+ }
+}
diff --git a/deps/v8/test/cctest/test-unique.cc b/deps/v8/test/cctest/test-unique.cc
new file mode 100644
index 0000000000..1d268580ed
--- /dev/null
+++ b/deps/v8/test/cctest/test-unique.cc
@@ -0,0 +1,488 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "factory.h"
+#include "global-handles.h"
+#include "unique.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+template <class T, class U>
+void CheckHashCodeEqual(Unique<T> a, Unique<U> b) {
+ int64_t hasha = static_cast<int64_t>(a.Hashcode());
+ int64_t hashb = static_cast<int64_t>(b.Hashcode());
+ CHECK_NE(static_cast<int64_t>(0), hasha);
+ CHECK_NE(static_cast<int64_t>(0), hashb);
+ CHECK_EQ(hasha, hashb);
+}
+
+
+template <class T, class U>
+void CheckHashCodeNotEqual(Unique<T> a, Unique<U> b) {
+ int64_t hasha = static_cast<int64_t>(a.Hashcode());
+ int64_t hashb = static_cast<int64_t>(b.Hashcode());
+ CHECK_NE(static_cast<int64_t>(0), hasha);
+ CHECK_NE(static_cast<int64_t>(0), hashb);
+ CHECK_NE(hasha, hashb);
+}
+
+
+TEST(UniqueCreate) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Handle<String> A = factory->InternalizeUtf8String("A");
+ Unique<String> HA(A);
+
+ CHECK(*HA.handle() == *A);
+ CHECK_EQ(*A, *HA.handle());
+
+ Unique<String> HA2(A);
+
+ CheckHashCodeEqual(HA, HA2);
+ CHECK(HA == HA2);
+ CHECK_EQ(*HA.handle(), *HA2.handle());
+
+ CHECK(HA2 == HA);
+ CHECK_EQ(*HA2.handle(), *HA.handle());
+
+ Handle<String> B = factory->InternalizeUtf8String("B");
+ Unique<String> HB(B);
+
+ CheckHashCodeNotEqual(HA, HB);
+ CHECK(HA != HB);
+ CHECK_NE(*HA.handle(), *HB.handle());
+
+ CHECK(HB != HA);
+ CHECK_NE(*HB.handle(), *HA.handle());
+
+ // TODO(titzer): check that Unique properly survives a GC.
+}
+
+
+TEST(UniqueSubsume) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Handle<String> A = factory->InternalizeUtf8String("A");
+ Unique<String> HA(A);
+
+ CHECK(*HA.handle() == *A);
+ CHECK_EQ(*A, *HA.handle());
+
+ Unique<Object> HO = HA; // Here comes the subsumption, boys.
+
+ CheckHashCodeEqual(HA, HO);
+ CHECK(HA == HO);
+ CHECK_EQ(*HA.handle(), *HO.handle());
+
+ CHECK(HO == HA);
+ CHECK_EQ(*HO.handle(), *HA.handle());
+}
+
+
+TEST(UniqueSet_Add) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+
+ Zone zone(isolate);
+
+ UniqueSet<String>* set = new(&zone) UniqueSet<String>();
+
+ CHECK_EQ(0, set->size());
+ set->Add(A, &zone);
+ CHECK_EQ(1, set->size());
+ set->Add(A, &zone);
+ CHECK_EQ(1, set->size());
+ set->Add(B, &zone);
+ CHECK_EQ(2, set->size());
+ set->Add(C, &zone);
+ CHECK_EQ(3, set->size());
+ set->Add(C, &zone);
+ CHECK_EQ(3, set->size());
+ set->Add(B, &zone);
+ CHECK_EQ(3, set->size());
+ set->Add(A, &zone);
+ CHECK_EQ(3, set->size());
+}
+
+
+template <class T>
+static void CHECK_SETS(
+ UniqueSet<T>* set1, UniqueSet<T>* set2, bool expected) {
+ CHECK(set1->Equals(set1));
+ CHECK(set2->Equals(set2));
+ CHECK(expected == set1->Equals(set2));
+ CHECK(expected == set2->Equals(set1));
+}
+
+
+TEST(UniqueSet_Equals) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+
+ Zone zone(isolate);
+
+ UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+
+ CHECK_SETS(set1, set2, true);
+
+ set1->Add(A, &zone);
+
+ CHECK_SETS(set1, set2, false);
+
+ set2->Add(A, &zone);
+
+ CHECK_SETS(set1, set2, true);
+
+ set1->Add(B, &zone);
+
+ CHECK_SETS(set1, set2, false);
+
+ set2->Add(C, &zone);
+
+ CHECK_SETS(set1, set2, false);
+
+ set1->Add(C, &zone);
+
+ CHECK_SETS(set1, set2, false);
+
+ set2->Add(B, &zone);
+
+ CHECK_SETS(set1, set2, true);
+}
+
+
+TEST(UniqueSet_IsSubset1) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+
+ Zone zone(isolate);
+
+ UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+
+ CHECK(set1->IsSubset(set2));
+ CHECK(set2->IsSubset(set1));
+
+ set1->Add(A, &zone);
+
+ CHECK(!set1->IsSubset(set2));
+ CHECK(set2->IsSubset(set1));
+
+ set2->Add(B, &zone);
+
+ CHECK(!set1->IsSubset(set2));
+ CHECK(!set2->IsSubset(set1));
+
+ set2->Add(A, &zone);
+
+ CHECK(set1->IsSubset(set2));
+ CHECK(!set2->IsSubset(set1));
+
+ set1->Add(B, &zone);
+
+ CHECK(set1->IsSubset(set2));
+ CHECK(set2->IsSubset(set1));
+}
+
+
+TEST(UniqueSet_IsSubset2) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+ Unique<String> D(factory->InternalizeUtf8String("D"));
+ Unique<String> E(factory->InternalizeUtf8String("E"));
+ Unique<String> F(factory->InternalizeUtf8String("F"));
+ Unique<String> G(factory->InternalizeUtf8String("G"));
+
+ Zone zone(isolate);
+
+ UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+
+ set1->Add(A, &zone);
+ set1->Add(C, &zone);
+ set1->Add(E, &zone);
+
+ set2->Add(A, &zone);
+ set2->Add(B, &zone);
+ set2->Add(C, &zone);
+ set2->Add(D, &zone);
+ set2->Add(E, &zone);
+ set2->Add(F, &zone);
+
+ CHECK(set1->IsSubset(set2));
+ CHECK(!set2->IsSubset(set1));
+
+ set1->Add(G, &zone);
+
+ CHECK(!set1->IsSubset(set2));
+ CHECK(!set2->IsSubset(set1));
+}
+
+
+template <class T>
+static UniqueSet<T>* MakeSet(Zone* zone, int which, Unique<T>* elements) {
+ UniqueSet<T>* set = new(zone) UniqueSet<T>();
+ for (int i = 0; i < 32; i++) {
+ if ((which & (1 << i)) != 0) set->Add(elements[i], zone);
+ }
+ return set;
+}
+
+
+TEST(UniqueSet_IsSubsetExhaustive) {
+ const int kSetSize = 6;
+
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Zone zone(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+ Unique<String> D(factory->InternalizeUtf8String("D"));
+ Unique<String> E(factory->InternalizeUtf8String("E"));
+ Unique<String> F(factory->InternalizeUtf8String("F"));
+ Unique<String> G(factory->InternalizeUtf8String("G"));
+
+ Unique<String> elements[] = {
+ A, B, C, D, E, F, G
+ };
+
+ // Exhaustively test all sets with <= 6 elements.
+ for (int i = 0; i < (1 << kSetSize); i++) {
+ for (int j = 0; j < (1 << kSetSize); j++) {
+ UniqueSet<String>* set1 = MakeSet(&zone, i, elements);
+ UniqueSet<String>* set2 = MakeSet(&zone, j, elements);
+
+ CHECK(((i & j) == i) == set1->IsSubset(set2));
+ }
+ }
+}
+
+
+TEST(UniqueSet_Intersect1) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+
+ Zone zone(isolate);
+
+ UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* result;
+
+ CHECK(set1->IsSubset(set2));
+ CHECK(set2->IsSubset(set1));
+
+ set1->Add(A, &zone);
+
+ result = set1->Intersect(set2, &zone);
+
+ CHECK_EQ(0, result->size());
+ CHECK(set2->Equals(result));
+
+ set2->Add(A, &zone);
+
+ result = set1->Intersect(set2, &zone);
+
+ CHECK_EQ(1, result->size());
+ CHECK(set1->Equals(result));
+ CHECK(set2->Equals(result));
+
+ set2->Add(B, &zone);
+ set2->Add(C, &zone);
+
+ result = set1->Intersect(set2, &zone);
+
+ CHECK_EQ(1, result->size());
+ CHECK(set1->Equals(result));
+}
+
+
+TEST(UniqueSet_IntersectExhaustive) {
+ const int kSetSize = 6;
+
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Zone zone(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+ Unique<String> D(factory->InternalizeUtf8String("D"));
+ Unique<String> E(factory->InternalizeUtf8String("E"));
+ Unique<String> F(factory->InternalizeUtf8String("F"));
+ Unique<String> G(factory->InternalizeUtf8String("G"));
+
+ Unique<String> elements[] = {
+ A, B, C, D, E, F, G
+ };
+
+ // Exhaustively test all sets with <= 6 elements.
+ for (int i = 0; i < (1 << kSetSize); i++) {
+ for (int j = 0; j < (1 << kSetSize); j++) {
+ UniqueSet<String>* set1 = MakeSet(&zone, i, elements);
+ UniqueSet<String>* set2 = MakeSet(&zone, j, elements);
+
+ UniqueSet<String>* result = set1->Intersect(set2, &zone);
+ UniqueSet<String>* expected = MakeSet(&zone, i & j, elements);
+
+ CHECK(result->Equals(expected));
+ CHECK(expected->Equals(result));
+ }
+ }
+}
+
+
+TEST(UniqueSet_Union1) {
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+
+ Zone zone(isolate);
+
+ UniqueSet<String>* set1 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* set2 = new(&zone) UniqueSet<String>();
+ UniqueSet<String>* result;
+
+ CHECK(set1->IsSubset(set2));
+ CHECK(set2->IsSubset(set1));
+
+ set1->Add(A, &zone);
+
+ result = set1->Union(set2, &zone);
+
+ CHECK_EQ(1, result->size());
+ CHECK(set1->Equals(result));
+
+ set2->Add(A, &zone);
+
+ result = set1->Union(set2, &zone);
+
+ CHECK_EQ(1, result->size());
+ CHECK(set1->Equals(result));
+ CHECK(set2->Equals(result));
+
+ set2->Add(B, &zone);
+ set2->Add(C, &zone);
+
+ result = set1->Union(set2, &zone);
+
+ CHECK_EQ(3, result->size());
+ CHECK(set2->Equals(result));
+}
+
+
+TEST(UniqueSet_UnionExhaustive) {
+ const int kSetSize = 6;
+
+ CcTest::InitializeVM();
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ HandleScope sc(isolate);
+
+ Zone zone(isolate);
+
+ Unique<String> A(factory->InternalizeUtf8String("A"));
+ Unique<String> B(factory->InternalizeUtf8String("B"));
+ Unique<String> C(factory->InternalizeUtf8String("C"));
+ Unique<String> D(factory->InternalizeUtf8String("D"));
+ Unique<String> E(factory->InternalizeUtf8String("E"));
+ Unique<String> F(factory->InternalizeUtf8String("F"));
+ Unique<String> G(factory->InternalizeUtf8String("G"));
+
+ Unique<String> elements[] = {
+ A, B, C, D, E, F, G
+ };
+
+ // Exhaustively test all sets with <= 6 elements.
+ for (int i = 0; i < (1 << kSetSize); i++) {
+ for (int j = 0; j < (1 << kSetSize); j++) {
+ UniqueSet<String>* set1 = MakeSet(&zone, i, elements);
+ UniqueSet<String>* set2 = MakeSet(&zone, j, elements);
+
+ UniqueSet<String>* result = set1->Union(set2, &zone);
+ UniqueSet<String>* expected = MakeSet(&zone, i | j, elements);
+
+ CHECK(result->Equals(expected));
+ CHECK(expected->Equals(result));
+ }
+ }
+}
+
diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc
index 541c42338c..feff477933 100644
--- a/deps/v8/test/cctest/test-utils.cc
+++ b/deps/v8/test/cctest/test-utils.cc
@@ -140,7 +140,6 @@ void TestMemMove(byte* area1,
TEST(MemMove) {
v8::V8::Initialize();
- OS::SetUp();
byte* area1 = new byte[kAreaSize];
byte* area2 = new byte[kAreaSize];
byte* area3 = new byte[kAreaSize];
diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc
index 9044f17e4e..932b06b850 100644
--- a/deps/v8/test/cctest/test-weakmaps.cc
+++ b/deps/v8/test/cctest/test-weakmaps.cc
@@ -69,7 +69,7 @@ static void WeakPointerCallback(v8::Isolate* isolate,
void* id) {
ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/deps/v8/test/cctest/test-weaksets.cc b/deps/v8/test/cctest/test-weaksets.cc
index 707f903284..aff4c7fcbe 100644
--- a/deps/v8/test/cctest/test-weaksets.cc
+++ b/deps/v8/test/cctest/test-weaksets.cc
@@ -69,7 +69,7 @@ static void WeakPointerCallback(v8::Isolate* isolate,
void* id) {
ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/deps/v8/test/mjsunit/array-push-non-smi-value.js b/deps/v8/test/mjsunit/array-push-non-smi-value.js
new file mode 100644
index 0000000000..460dd2a911
--- /dev/null
+++ b/deps/v8/test/mjsunit/array-push-non-smi-value.js
@@ -0,0 +1,36 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check pushes of non-SMI values.
+var a = [];
+function func() {
+ return a.push(0x40000000) > 60;
+}
+
+assertFalse(func());
+assertFalse(func());
+assertFalse(func());
diff --git a/deps/v8/test/mjsunit/array-store-and-grow.js b/deps/v8/test/mjsunit/array-store-and-grow.js
index a03a753e44..5ac95e9b3a 100644
--- a/deps/v8/test/mjsunit/array-store-and-grow.js
+++ b/deps/v8/test/mjsunit/array-store-and-grow.js
@@ -187,6 +187,7 @@ array_store_1(a, 0, 0.5);
assertEquals(0.5, a[0]);
assertEquals(0.5, array_store_1([], 0, 0.5));
+
// Verify that a grow store will deoptimize if the max gap (difference between
// the end of an array capacity and a new index) is passed. The wrapper is to
// make sure array_store_10 isn't inlined.
@@ -207,3 +208,49 @@ assertEquals(0.5, array_store_1([], 0, 0.5));
%ClearFunctionTypeFeedback(grow_store);
})();
+
+// Verify that a polymorphic store and grow IC when crankshafted is still
+// a grow IC (earlier it would revert to a standard store in the polymorphic
+// case).
+(function() {
+ function f(o, k, v) {
+ o[k] = v;
+ }
+
+ a = [3.5];
+ f(a, 1, "hi"); // DOUBLE packed array -> tagged packed grow
+ a = {};
+ a.p = "property";
+ a[0] = 1;
+ f(a, 0, 5.4);
+
+ %OptimizeFunctionOnNextCall(f);
+ // Should be a polymorphic grow stub. If not a grow stub it will deopt.
+ f(new Array("hi"), 1, 3);
+ assertOptimized(f);
+ %ClearFunctionTypeFeedback(f);
+})();
+
+
+// Now verify that a polymorphic store (non-growing) IC when crankshafted WILL
+// deopt if you pass an element out of bounds.
+(function() {
+ function f(o, k, v) {
+ o[k] = v;
+ }
+
+ a = [3.5];
+ f(a, 0, "hi"); // DOUBLE packed array -> tagged packed grow
+ a = {};
+ a.p = "property";
+ a[0] = 1;
+ f(a, 0, 5.4);
+
+ %OptimizeFunctionOnNextCall(f);
+ f(new Array("hi"), 0, 3);
+ assertOptimized(f);
+ // An attempt to grow should cause deopt
+ f(new Array("hi"), 1, 3);
+ assertUnoptimized(f);
+ %ClearFunctionTypeFeedback(f);
+})();
diff --git a/deps/v8/test/mjsunit/assert-opt-and-deopt.js b/deps/v8/test/mjsunit/assert-opt-and-deopt.js
index bfd2f3f489..d653bb5905 100644
--- a/deps/v8/test/mjsunit/assert-opt-and-deopt.js
+++ b/deps/v8/test/mjsunit/assert-opt-and-deopt.js
@@ -25,10 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --noconcurrent-recompilation
-if (%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is turned on after all. Skipping this test.");
+if (%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is turned on after all. Skipping this test.");
quit();
}
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis.js b/deps/v8/test/mjsunit/compiler/escape-analysis.js
index 9776f67ccf..74e638a538 100644
--- a/deps/v8/test/mjsunit/compiler/escape-analysis.js
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --use-escape-analysis
+// Flags: --allow-natives-syntax --use-escape-analysis --expose-gc
// Test stores on a join path.
@@ -132,3 +132,142 @@
delete deopt.deopt;
func(); func();
})();
+
+
+// Test deoptimization with captured objects on operand stack.
+(function testDeoptOperand() {
+ var deopt = { deopt:false };
+ function constructor1() {
+ this.a = 1.0;
+ this.b = 2.3;
+ deopt.deopt;
+ assertEquals(1.0, this.a);
+ assertEquals(2.3, this.b);
+ this.b = 2.7;
+ this.c = 3.0;
+ this.d = 4.5;
+ }
+ function constructor2() {
+ this.e = 5.0;
+ this.f = new constructor1();
+ assertEquals(1.0, this.f.a);
+ assertEquals(2.7, this.f.b);
+ assertEquals(3.0, this.f.c);
+ assertEquals(4.5, this.f.d);
+ assertEquals(5.0, this.e);
+ this.e = 5.9;
+ this.g = 6.7;
+ }
+ function func() {
+ var o = new constructor2();
+ assertEquals(1.0, o.f.a);
+ assertEquals(2.7, o.f.b);
+ assertEquals(3.0, o.f.c);
+ assertEquals(4.5, o.f.d);
+ assertEquals(5.9, o.e);
+ assertEquals(6.7, o.g);
+ }
+ func(); func();
+ %OptimizeFunctionOnNextCall(func);
+ func(); func();
+ delete deopt.deopt;
+ func(); func();
+})();
+
+
+// Test map checks on captured objects.
+(function testMapCheck() {
+ var sum = 0;
+ function getter() { return 27; }
+ function setter(v) { sum += v; }
+ function constructor() {
+ this.x = 23;
+ this.y = 42;
+ }
+ function check(x, y) {
+ var o = new constructor();
+ assertEquals(x, o.x);
+ assertEquals(y, o.y);
+ }
+ var monkey = Object.create(null, {
+ x: { get:getter, set:setter },
+ y: { get:getter, set:setter }
+ });
+ check(23, 42); check(23, 42);
+ %OptimizeFunctionOnNextCall(check);
+ check(23, 42); check(23, 42);
+ constructor.prototype = monkey;
+ check(27, 27); check(27, 27);
+ assertEquals(130, sum);
+})();
+
+
+// Test OSR into a loop with captured objects.
+(function testOSR() {
+ function constructor() {
+ this.a = 23;
+ }
+ function osr1(length) {
+ assertEquals(23, (new constructor()).a);
+ var result = 0;
+ for (var i = 0; i < length; i++) {
+ result = (result + i) % 99;
+ }
+ return result;
+ }
+ function osr2(length) {
+ var result = 0;
+ for (var i = 0; i < length; i++) {
+ result = (result + i) % 99;
+ }
+ assertEquals(23, (new constructor()).a);
+ return result;
+ }
+ function osr3(length) {
+ var result = 0;
+ var o = new constructor();
+ for (var i = 0; i < length; i++) {
+ result = (result + i) % 99;
+ }
+ assertEquals(23, o.a);
+ return result;
+ }
+ function test(closure) {
+ assertEquals(45, closure(10));
+ assertEquals(45, closure(10));
+ assertEquals(10, closure(50000));
+ }
+ test(osr1);
+ test(osr2);
+ test(osr3);
+})();
+
+
+// Test out-of-bounds access on captured objects.
+(function testOOB() {
+ function cons1() {
+ this.x = 1;
+ this.y = 2;
+ this.z = 3;
+ }
+ function cons2() {
+ this.a = 7;
+ }
+ function oob(constructor, branch) {
+ var o = new constructor();
+ if (branch) {
+ return o.a;
+ } else {
+ return o.z;
+ }
+ }
+ assertEquals(3, oob(cons1, false));
+ assertEquals(3, oob(cons1, false));
+ assertEquals(7, oob(cons2, true));
+ assertEquals(7, oob(cons2, true));
+ gc(); // Clears type feedback of constructor call.
+ assertEquals(7, oob(cons2, true));
+ assertEquals(7, oob(cons2, true));
+ %OptimizeFunctionOnNextCall(oob);
+ assertEquals(7, oob(cons2, true));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/increment-typefeedback.js b/deps/v8/test/mjsunit/compiler/increment-typefeedback.js
new file mode 100644
index 0000000000..798959296c
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/increment-typefeedback.js
@@ -0,0 +1,39 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+ x++;
+ return x;
+}
+
+f(0.5);
+f(0.5);
+%OptimizeFunctionOnNextCall(f);
+f(0.5);
+assertOptimized(f);
diff --git a/deps/v8/test/mjsunit/compiler/optimized-for-in.js b/deps/v8/test/mjsunit/compiler/optimized-for-in.js
index cb8c66df9f..9c756aafa7 100644
--- a/deps/v8/test/mjsunit/compiler/optimized-for-in.js
+++ b/deps/v8/test/mjsunit/compiler/optimized-for-in.js
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --optimize-for-in --allow-natives-syntax
+// Flags: --no-concurrent-osr
// Test for-in support in Crankshaft. For simplicity this tests assumes certain
// fixed iteration order for properties and will have to be adjusted if V8
diff --git a/deps/v8/test/mjsunit/compiler/osr-assert.js b/deps/v8/test/mjsunit/compiler/osr-assert.js
new file mode 100644
index 0000000000..94b901fd4f
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/osr-assert.js
@@ -0,0 +1,41 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --use-osr
+
+function f(x, b, c) {
+ var outer = 1000000;
+ var a = 1;
+ while (outer > 0) {
+ a = a + 5;
+ assertEquals(b + 1, c);
+ outer--;
+ }
+ return a + 4;
+}
+
+assertEquals(5000005, f(5, "122", "1221"));
diff --git a/deps/v8/test/mjsunit/compiler/osr-sar.js b/deps/v8/test/mjsunit/compiler/osr-sar.js
new file mode 100644
index 0000000000..fd68b98a45
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/osr-sar.js
@@ -0,0 +1,49 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function test() {
+ // Loop to force OSR.
+ var j = 0;
+ for (var i = 0; i < 80000; i++) {
+ j++;
+ }
+
+ function SarShr(val) {
+ return val >> (-2 >>> 0);
+ }
+
+ var K3 = 0x80000000;
+ assertEquals(-2, SarShr(K3 | 0));
+ assertEquals(-2, SarShr(K3 | 0));
+ %OptimizeFunctionOnNextCall(SarShr);
+ assertEquals(-2, SarShr(K3 | 0));
+}
+
+test();
+//test();
diff --git a/deps/v8/test/mjsunit/compiler/osr-uint32.js b/deps/v8/test/mjsunit/compiler/osr-uint32.js
new file mode 100644
index 0000000000..d6fcae546c
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/osr-uint32.js
@@ -0,0 +1,39 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Loop to force OSR.
+var j = 0;
+for (var i = 0; i < 80000; i++) {
+ j++;
+}
+
+function SarShr(val) {
+ return val >> (-2 >>> 0);
+}
+
+var K3 = 0x80000000;
+assertEquals(-2, SarShr(K3 | 0));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-298392.js b/deps/v8/test/mjsunit/compiler/osr-warm.js
index 8370654b6c..65ada1e114 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-298392.js
+++ b/deps/v8/test/mjsunit/compiler/osr-warm.js
@@ -25,27 +25,26 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-function foo() {
- return [[1,2,3], [5,6,6]];
-}
+// Flags: --use-osr
-function bar() {
- return ["foo", "bar"];
+function f1(x) {
+ while (x > 0) {
+ x--;
+ }
+ return x;
}
-function baz() {
- return [foo(), bar(), foo(), bar()];
-}
+assertEquals(0, f1(1));
+assertEquals(0, f1(10000000));
-function thingy() {
- var result = [];
- for (var i = 0; i < 50000; ++i) {
- result.push(baz());
+function f2(x) {
+ var sum = 1;
+ while (x > 0) {
+ x--;
+ sum++;
}
- return result;
+ return sum;
}
-var size = thingy().length;
-if (size != 50000) {
- throw "Error: bad size: " + size;
-}
+assertEquals(2, f2(1));
+assertEquals(10000001, f2(10000000));
diff --git a/deps/v8/test/mjsunit/compiler/parallel-proto-change.js b/deps/v8/test/mjsunit/compiler/parallel-proto-change.js
index 25ea3b59df..7602279893 100644
--- a/deps/v8/test/mjsunit/compiler/parallel-proto-change.js
+++ b/deps/v8/test/mjsunit/compiler/parallel-proto-change.js
@@ -26,10 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
-// Flags: --parallel-recompilation --parallel-recompilation-delay=50
+// Flags: --concurrent-recompilation --concurrent-recompilation-delay=50
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -41,11 +41,11 @@ o.__proto__ = { __proto__: { bar: function() { return 1; } } };
assertEquals(1, f(o));
assertEquals(1, f(o));
-// Mark for parallel optimization.
-%OptimizeFunctionOnNextCall(f, "parallel");
-// Trigger optimization in the parallel thread.
+// Mark for concurrent optimization.
+%OptimizeFunctionOnNextCall(f, "concurrent");
+// Trigger optimization in the background thread.
assertEquals(1, f(o));
-// While parallel recompilation is running, optimization not yet done.
+// While concurrent recompilation is running, optimization not yet done.
assertUnoptimized(f, "no sync");
// Change the prototype chain during optimization to trigger map invalidation.
o.__proto__.__proto__ = { bar: function() { return 2; } };
diff --git a/deps/v8/test/mjsunit/debug-script.js b/deps/v8/test/mjsunit/debug-script.js
index 6e673f71c0..1cbdb376cc 100644
--- a/deps/v8/test/mjsunit/debug-script.js
+++ b/deps/v8/test/mjsunit/debug-script.js
@@ -59,9 +59,9 @@ for (i = 0; i < scripts.length; i++) {
}
// This has to be updated if the number of native scripts change.
-assertEquals(16, named_native_count);
-// Only the 'gc' and (depending on flags) the 'i18n' extensions are loaded.
-assertTrue(extension_count == 1 || extension_count == 2);
+assertTrue(named_native_count == 16 || named_native_count == 17);
+// Only the 'gc' extension is loaded.
+assertEquals(1, extension_count);
// This script and mjsunit.js has been loaded. If using d8, d8 loads
// a normal script during startup too.
assertTrue(normal_count == 2 || normal_count == 3);
diff --git a/deps/v8/test/mjsunit/debug-step-4-in-frame.js b/deps/v8/test/mjsunit/debug-step-4-in-frame.js
new file mode 100644
index 0000000000..65ac4902dd
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-step-4-in-frame.js
@@ -0,0 +1,132 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+// Tests how debugger can step over not necessarily in the top frame.
+
+// Simple 3 functions, that protocol their execution state in global
+// variable state.
+var state;
+
+function f() {
+ var a = 1978;
+ for (state[2] = 0; state[2] < 5; state[2]++) {
+ void String(a);
+ }
+}
+function g() {
+ for (state[1] = 0; state[1] < 5; state[1]++) {
+ f();
+ }
+}
+function h() {
+ state = [-1, -1, -1];
+ for (state[0] = 0; state[0] < 5; state[0]++) {
+ g();
+ }
+}
+
+function TestCase(frame_index, step_count, expected_final_state) {
+ print("Test case, parameters " + frame_index + "/" + step_count);
+
+ var listener_exception = null;
+ var state_snapshot;
+ var listener_state;
+ var bp;
+
+ function listener(event, exec_state, event_data, data) {
+ print("Here ("+event+"/"+listener_state+"): " +
+ exec_state.frame(0).sourceLineText());
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ if (listener_state == 0) {
+ Debug.clearBreakPoint(bp);
+ var context_frame;
+ if (frame_index !== undefined) {
+ context_frame = exec_state.frame(frame_index);
+ }
+ exec_state.prepareStep(Debug.StepAction.StepNext,
+ step_count, context_frame);
+ listener_state = 1;
+ } else if (listener_state == 1) {
+ state_snapshot = String(state);
+ print("State: " + state_snapshot);
+ Debug.setListener(null);
+ listener_state = 2;
+ }
+ }
+ } catch (e) {
+ listener_exception = e;
+ }
+ }
+
+
+ // Add the debug event listener.
+ listener_state = 0;
+ Debug.setListener(listener);
+ bp = Debug.setBreakPoint(f, 1);
+
+ h();
+ Debug.setListener(null);
+ if (listener_exception !== null) {
+ print("Exception caught: " + listener_exception);
+ assertUnreachable();
+ }
+
+ assertEquals(expected_final_state, state_snapshot);
+}
+
+
+// Warm-up -- make sure all is compiled and ready for breakpoint.
+h();
+
+
+// Stepping in the default (top) frame.
+TestCase(undefined, 0, "0,0,-1");
+TestCase(undefined, 1, "0,0,-1");
+TestCase(undefined, 2, "0,0,0");
+TestCase(undefined, 5, "0,0,1");
+TestCase(undefined, 8, "0,0,3");
+
+// Stepping in the frame #0 (should be exactly the same as above).
+TestCase(0, 0, "0,0,-1");
+TestCase(0, 1, "0,0,-1");
+TestCase(0, 2, "0,0,0");
+TestCase(0, 5, "0,0,1");
+TestCase(0, 8, "0,0,3");
+
+// Stepping in the frame #1.
+TestCase(1, 0, "0,0,5");
+TestCase(1, 3, "0,1,5");
+TestCase(1, 8, "0,4,5");
+
+// Stepping in the frame #2.
+TestCase(2, 3, "1,5,5");
+TestCase(2, 8, "4,5,5");
diff --git a/deps/v8/test/mjsunit/debug-stepin-positions.js b/deps/v8/test/mjsunit/debug-stepin-positions.js
index 482e21be4d..e6d8204611 100644
--- a/deps/v8/test/mjsunit/debug-stepin-positions.js
+++ b/deps/v8/test/mjsunit/debug-stepin-positions.js
@@ -30,26 +30,35 @@
Debug = debug.Debug
function DebuggerStatement() {
- debugger;
+ debugger; /*pause*/
}
-function TestCase(fun) {
+function TestCase(fun, frame_number) {
var exception = false;
var codeSnippet = undefined;
var resultPositions = undefined;
function listener(event, exec_state, event_data, data) {
try {
- if (event == Debug.DebugEvent.Break) {
+ if (event == Debug.DebugEvent.Break ||
+ event == Debug.DebugEvent.Exception) {
Debug.setListener(null);
-
- var secondFrame = exec_state.frame(1);
- codeSnippet = secondFrame.sourceLineText();
- resultPositions = secondFrame.stepInPositions();
+ assertHasLineMark(/pause/, exec_state.frame(0));
+ assertHasLineMark(/positions/, exec_state.frame(frame_number));
+ var frame = exec_state.frame(frame_number);
+ codeSnippet = frame.sourceLineText();
+ resultPositions = frame.stepInPositions();
}
} catch (e) {
exception = e
}
+
+ function assertHasLineMark(mark, frame) {
+ var line = frame.sourceLineText();
+ if (!mark.exec(frame.sourceLineText())) {
+ throw new Error("Line " + line + " should contain mark " + mark);
+ }
+ }
}
Debug.setListener(listener);
@@ -101,26 +110,98 @@ function TestCase(fun) {
decoratedResult);
}
+function TestCaseWithDebugger(fun) {
+ TestCase(fun, 1);
+}
+
+function TestCaseWithBreakpoint(fun, line_number, frame_number) {
+ var breakpointId = Debug.setBreakPoint(fun, line_number);
+ TestCase(fun, frame_number);
+ Debug.clearBreakPoint(breakpointId);
+}
+
+function TestCaseWithException(fun, frame_number) {
+ Debug.setBreakOnException();
+ TestCase(fun, frame_number);
+ Debug.clearBreakOnException();
+}
+
// Test cases.
+// Step in position, when the function call that we are standing at is already
+// being executed.
+var fun = function() {
+ function g(p) {
+ throw String(p); /*pause*/
+ }
+ try {
+ var res = [ g(1), /*#*/g(2) ]; /*positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithBreakpoint(fun, 2, 1);
+TestCaseWithException(fun, 1);
+
+
+// Step in position, when the function call that we are standing at is raising
+// an exception.
+var fun = function() {
+ var o = {
+ g: function(p) {
+ throw p;
+ }
+ };
+ try {
+ var res = [ /*#*/f(1), /*#*/g(2) ]; /*pause, positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithException(fun, 0);
+
+
+// Step-in position, when already paused almost on the first call site.
+var fun = function() {
+ function g(p) {
+ throw p;
+ }
+ try {
+ var res = [ /*#*/g(Math.rand), /*#*/g(2) ]; /*pause, positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithBreakpoint(fun, 5, 0);
+
+// Step-in position, when already paused on the first call site.
+var fun = function() {
+ function g() {
+ throw "Debug";
+ }
+ try {
+ var res = [ /*#*/g(), /*#*/g() ]; /*pause, positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithBreakpoint(fun, 5, 0);
+
+
// Method calls.
var fun = function() {
var data = {
a: function() {}
};
- var res = [ DebuggerStatement(), data./*#*/a(), data[/*#*/String("a")]/*#*/(), data["a"]/*#*/(), data.a, data["a"] ];
+ var res = [ DebuggerStatement(), data./*#*/a(), data[/*#*/String("a")]/*#*/(), data["a"]/*#*/(), data.a, data["a"] ]; /*positions*/
};
-TestCase(fun);
+TestCaseWithDebugger(fun);
// Function call on a value.
var fun = function() {
function g(p) {
return g;
}
- var res = [ DebuggerStatement(), /*#*/g(2), /*#*/g(2)/*#*/(3), /*#*/g(0)/*#*/(0)/*#*/(g) ];
+ var res = [ DebuggerStatement(), /*#*/g(2), /*#*/g(2)/*#*/(3), /*#*/g(0)/*#*/(0)/*#*/(g) ]; /*positions*/
};
-TestCase(fun);
+TestCaseWithDebugger(fun);
// Local function call, closure function call,
// local function construction call.
@@ -128,15 +209,17 @@ var fun = (function(p) {
return function() {
function f(a, b) {
}
- var res = /*#*/f(DebuggerStatement(), /*#*/p(/*#*/new f()));
+ var res = /*#*/f(DebuggerStatement(), /*#*/p(/*#*/new f())); /*positions*/
};
})(Object);
-TestCase(fun);
+TestCaseWithDebugger(fun);
// Global function, global object construction, calls before pause point.
var fun = (function(p) {
return function() {
- var res = [ Math.abs(new Object()), DebuggerStatement(), Math./*#*/abs(4), /*#*/new Object()./*#*/toString() ];
+ var res = [ Math.abs(new Object()), DebuggerStatement(), Math./*#*/abs(4), /*#*/new Object()./*#*/toString() ]; /*positions*/
};
})(Object);
-TestCase(fun);
+TestCaseWithDebugger(fun);
+
+
diff --git a/deps/v8/test/mjsunit/external-array-no-sse2.js b/deps/v8/test/mjsunit/external-array-no-sse2.js
index 11e61ba186..575a8b53cf 100644
--- a/deps/v8/test/mjsunit/external-array-no-sse2.js
+++ b/deps/v8/test/mjsunit/external-array-no-sse2.js
@@ -679,3 +679,37 @@ boo(built_in_array, 0, 2.5);
assertEquals(2.5, goo(built_in_array, 0));
%ClearFunctionTypeFeedback(goo);
%ClearFunctionTypeFeedback(boo);
+
+// Check all int range edge cases
+function checkRange() {
+ var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
+ var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
+ var e8 = Math.pow(2,8); var e7 = Math.pow(2,7);
+ var a7 = new Uint32Array(2); var a71 = new Int32Array(2);
+ var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
+ var a74 = new Uint8Array(2); var a75 = new Int8Array(2);
+ for (i = 1; i <= Math.pow(2,33); i *= 2) {
+ var j = i-1;
+ a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
+ a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
+
+ if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
+ if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
+ if (i < e31) { assertEquals(a71[0], i); } else {
+ assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
+ if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
+
+ if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
+ if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
+ if (i < e15) { assertEquals(a73[0], i); } else {
+ assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
+ if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
+
+ if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
+ if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
+ if (i < e7) { assertEquals(a75[0], i); } else {
+ assertEquals(a75[0], (i < e8) ? -e7 : 0); }
+ if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
+ }
+}
+checkRange();
diff --git a/deps/v8/test/mjsunit/external-array.js b/deps/v8/test/mjsunit/external-array.js
index 3fcd544ab6..ab5435e5d6 100644
--- a/deps/v8/test/mjsunit/external-array.js
+++ b/deps/v8/test/mjsunit/external-array.js
@@ -678,3 +678,37 @@ boo(built_in_array, 0, 2.5);
assertEquals(2.5, goo(built_in_array, 0));
%ClearFunctionTypeFeedback(goo);
%ClearFunctionTypeFeedback(boo);
+
+// Check all int range edge cases
+function checkRange() {
+ var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
+ var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
+ var e8 = Math.pow(2,8); var e7 = Math.pow(2,7);
+ var a7 = new Uint32Array(2); var a71 = new Int32Array(2);
+ var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
+ var a74 = new Uint8Array(2); var a75 = new Int8Array(2);
+ for (i = 1; i <= Math.pow(2,33); i *= 2) {
+ var j = i-1;
+ a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
+ a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
+
+ if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
+ if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
+ if (i < e31) { assertEquals(a71[0], i); } else {
+ assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
+ if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
+
+ if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
+ if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
+ if (i < e15) { assertEquals(a73[0], i); } else {
+ assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
+ if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
+
+ if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
+ if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
+ if (i < e7) { assertEquals(a75[0], i); } else {
+ assertEquals(a75[0], (i < e8) ? -e7 : 0); }
+ if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
+ }
+}
+checkRange();
diff --git a/deps/v8/test/mjsunit/fast-literal.js b/deps/v8/test/mjsunit/fast-literal.js
new file mode 100644
index 0000000000..822d90656b
--- /dev/null
+++ b/deps/v8/test/mjsunit/fast-literal.js
@@ -0,0 +1,42 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --no-inline-new --nouse-allocation-folding
+
+%SetAllocationTimeout(10, 0);
+function f() {
+ return [[1, 2, 3], [1.1, 1.2, 1.3], [[], [], []]];
+}
+
+f(); f(); f();
+%OptimizeFunctionOnNextCall(f);
+for (var i=0; i<1000; i++) {
+ f();
+}
+
+
+
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part1.js b/deps/v8/test/mjsunit/fuzz-natives-part1.js
index 8ca523cc6f..e76b9be6d4 100644
--- a/deps/v8/test/mjsunit/fuzz-natives-part1.js
+++ b/deps/v8/test/mjsunit/fuzz-natives-part1.js
@@ -150,8 +150,7 @@ var knownProblems = {
"PushModuleContext": true,
"LazyCompile": true,
"LazyRecompile": true,
- "ParallelRecompile": true,
- "InstallRecompiledCode": true,
+ "ConcurrentRecompile": true,
"NotifyDeoptimized": true,
"NotifyStubFailure": true,
"NotifyOSR": true,
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part2.js b/deps/v8/test/mjsunit/fuzz-natives-part2.js
index ec84f35ada..0797deb18d 100644
--- a/deps/v8/test/mjsunit/fuzz-natives-part2.js
+++ b/deps/v8/test/mjsunit/fuzz-natives-part2.js
@@ -150,8 +150,7 @@ var knownProblems = {
"PushModuleContext": true,
"LazyCompile": true,
"LazyRecompile": true,
- "ParallelRecompile": true,
- "InstallRecompiledCode": true,
+ "ConcurrentRecompile": true,
"NotifyDeoptimized": true,
"NotifyStubFailure": true,
"NotifyOSR": true,
@@ -165,6 +164,7 @@ var knownProblems = {
"DeclareGlobals": true,
"ArrayConstructor": true,
"InternalArrayConstructor": true,
+ "SetAccessorProperty": true,
"PromoteScheduledException": true,
"DeleteHandleScopeExtensions": true,
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part3.js b/deps/v8/test/mjsunit/fuzz-natives-part3.js
index 928fb4634f..9a3a883fe4 100644
--- a/deps/v8/test/mjsunit/fuzz-natives-part3.js
+++ b/deps/v8/test/mjsunit/fuzz-natives-part3.js
@@ -150,8 +150,7 @@ var knownProblems = {
"PushModuleContext": true,
"LazyCompile": true,
"LazyRecompile": true,
- "ParallelRecompile": true,
- "InstallRecompiledCode": true,
+ "ConcurrentRecompile": true,
"NotifyDeoptimized": true,
"NotifyStubFailure": true,
"NotifyOSR": true,
diff --git a/deps/v8/test/mjsunit/fuzz-natives-part4.js b/deps/v8/test/mjsunit/fuzz-natives-part4.js
index d47db3467e..83e00d2b66 100644
--- a/deps/v8/test/mjsunit/fuzz-natives-part4.js
+++ b/deps/v8/test/mjsunit/fuzz-natives-part4.js
@@ -150,8 +150,7 @@ var knownProblems = {
"PushModuleContext": true,
"LazyCompile": true,
"LazyRecompile": true,
- "ParallelRecompile": true,
- "InstallRecompiledCode": true,
+ "ConcurrentRecompile": true,
"NotifyDeoptimized": true,
"NotifyStubFailure": true,
"NotifyOSR": true,
diff --git a/deps/v8/test/mjsunit/harmony/object-observe.js b/deps/v8/test/mjsunit/harmony/object-observe.js
index 830eb1b09a..75f0ff8bb8 100644
--- a/deps/v8/test/mjsunit/harmony/object-observe.js
+++ b/deps/v8/test/mjsunit/harmony/object-observe.js
@@ -145,13 +145,8 @@ assertThrows(function() { notifier.performChange(1, function(){}); }, TypeError)
assertThrows(function() { notifier.performChange(undefined, function(){}); }, TypeError);
assertThrows(function() { notifier.performChange('foo', undefined); }, TypeError);
assertThrows(function() { notifier.performChange('foo', 'bar'); }, TypeError);
-var testSelf = {};
notifier.performChange('foo', function() {
- assertTrue(testSelf === this);
-}, testSelf);
-var self = this;
-notifier.performChange('foo', function() {
- assertTrue(self === this);
+ assertEquals(undefined, this);
});
var notify = notifier.notify;
@@ -400,10 +395,11 @@ Thingy.prototype = {
increment: function(amount) {
var notifier = Object.getNotifier(this);
+ var self = this;
notifier.performChange(Thingy.INCREMENT, function() {
- this.a += amount;
- this.b += amount;
- }, this);
+ self.a += amount;
+ self.b += amount;
+ });
notifier.notify({
object: this,
@@ -415,10 +411,11 @@ Thingy.prototype = {
multiply: function(amount) {
var notifier = Object.getNotifier(this);
+ var self = this;
notifier.performChange(Thingy.MULTIPLY, function() {
- this.a *= amount;
- this.b *= amount;
- }, this);
+ self.a *= amount;
+ self.b *= amount;
+ });
notifier.notify({
object: this,
@@ -430,10 +427,11 @@ Thingy.prototype = {
incrementAndMultiply: function(incAmount, multAmount) {
var notifier = Object.getNotifier(this);
+ var self = this;
notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() {
- this.increment(incAmount);
- this.multiply(multAmount);
- }, this);
+ self.increment(incAmount);
+ self.multiply(multAmount);
+ });
notifier.notify({
object: this,
@@ -505,10 +503,11 @@ RecursiveThingy.prototype = {
if (!n)
return;
var notifier = Object.getNotifier(this);
+ var self = this;
notifier.performChange(RecursiveThingy.MULTIPLY_FIRST_N, function() {
- this[n-1] = this[n-1]*amount;
- this.multiplyFirstN(amount, n-1);
- }, this);
+ self[n-1] = self[n-1]*amount;
+ self.multiplyFirstN(amount, n-1);
+ });
notifier.notify({
object: this,
@@ -557,18 +556,19 @@ DeckSuit.prototype = {
shuffle: function() {
var notifier = Object.getNotifier(this);
+ var self = this;
notifier.performChange(DeckSuit.SHUFFLE, function() {
- this.reverse();
- this.sort(function() { return Math.random()* 2 - 1; });
- var cut = this.splice(0, 6);
- Array.prototype.push.apply(this, cut);
- this.reverse();
- this.sort(function() { return Math.random()* 2 - 1; });
- var cut = this.splice(0, 6);
- Array.prototype.push.apply(this, cut);
- this.reverse();
- this.sort(function() { return Math.random()* 2 - 1; });
- }, this);
+ self.reverse();
+ self.sort(function() { return Math.random()* 2 - 1; });
+ var cut = self.splice(0, 6);
+ Array.prototype.push.apply(self, cut);
+ self.reverse();
+ self.sort(function() { return Math.random()* 2 - 1; });
+ var cut = self.splice(0, 6);
+ Array.prototype.push.apply(self, cut);
+ self.reverse();
+ self.sort(function() { return Math.random()* 2 - 1; });
+ });
notifier.notify({
object: this,
diff --git a/deps/v8/test/mjsunit/lithium/MulI.js b/deps/v8/test/mjsunit/lithium/MulI.js
new file mode 100644
index 0000000000..68588bd512
--- /dev/null
+++ b/deps/v8/test/mjsunit/lithium/MulI.js
@@ -0,0 +1,70 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --no-use-osr
+
+function foo_smi(a, b) {
+ var result = a * b;
+ result += a * 35;
+ result += a * -1;
+ result += a * 1;
+ result += a * 0;
+ return result * a;
+}
+
+function foo_int(a, b) {
+ var result = a * b;
+ result += a * 35;
+ result += a * -1;
+ result += a * 1;
+ result += a * 0;
+ return result * a;
+}
+
+foo_smi(10, 5);
+var r1 = foo_smi(10, 5);
+%OptimizeFunctionOnNextCall(foo_smi);
+var r2 = foo_smi(10, 5);
+
+assertEquals(r1, r2);
+
+foo_int(10, 21474800);
+var r3 = foo_int(10, 21474800);
+%OptimizeFunctionOnNextCall(foo_int);
+var r4 = foo_int(10, 21474800);
+
+assertEquals(r3, r4);
+
+// Check overflow with -1 constant.
+function foo2(value) {
+ return value * -1;
+}
+
+foo2(-2147483600);
+foo2(-2147483600);
+%OptimizeFunctionOnNextCall(foo2);
+assertEquals(2147483648, foo2(-2147483648));
diff --git a/deps/v8/test/mjsunit/manual-parallel-recompile.js b/deps/v8/test/mjsunit/manual-parallel-recompile.js
index 84bfff1a57..0a0e61d524 100644
--- a/deps/v8/test/mjsunit/manual-parallel-recompile.js
+++ b/deps/v8/test/mjsunit/manual-parallel-recompile.js
@@ -26,10 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc
-// Flags: --parallel-recompilation --parallel-recompilation-delay=50
+// Flags: --concurrent-recompilation --concurrent-recompilation-delay=50
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -53,12 +53,12 @@ f(g(1));
assertUnoptimized(f);
assertUnoptimized(g);
-%OptimizeFunctionOnNextCall(f, "parallel");
-%OptimizeFunctionOnNextCall(g, "parallel");
+%OptimizeFunctionOnNextCall(f, "concurrent");
+%OptimizeFunctionOnNextCall(g, "concurrent");
f(g(2)); // Trigger optimization.
-assertUnoptimized(f, "no sync"); // Not yet optimized while parallel thread
+assertUnoptimized(f, "no sync"); // Not yet optimized while background thread
assertUnoptimized(g, "no sync"); // is running.
-assertOptimized(f, "sync"); // Optimized once we sync with the parallel thread.
-assertOptimized(g, "sync");
+assertOptimized(f, "sync"); // Optimized once we sync with the
+assertOptimized(g, "sync"); // background thread.
diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js
index 83449cc1e6..129353730c 100644
--- a/deps/v8/test/mjsunit/mjsunit.js
+++ b/deps/v8/test/mjsunit/mjsunit.js
@@ -100,7 +100,7 @@ var assertInstanceof;
var assertUnreachable;
// Assert that the function code is (not) optimized. If "no sync" is passed
-// as second argument, we do not wait for the parallel optimization thread to
+// as second argument, we do not wait for the concurrent optimization thread to
// finish when polling for optimization status.
// Only works with --allow-natives-syntax.
var assertOptimized;
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index 829efaf583..ee35af5a61 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -251,8 +251,5 @@ harmony/object-observe: SKIP
readonly: SKIP
array-feedback: SKIP
-# TODO(mstarzinger): Enable once escape analysis is stabilized.
-compiler/escape-analysis: SKIP
-
# Deopt every n garbage collections collides with the deopt every n times flag.
regress/regress-2653: SKIP
diff --git a/deps/v8/test/mjsunit/parallel-initial-prototype-change.js b/deps/v8/test/mjsunit/parallel-initial-prototype-change.js
index 942d9abc3c..625b590fcc 100644
--- a/deps/v8/test/mjsunit/parallel-initial-prototype-change.js
+++ b/deps/v8/test/mjsunit/parallel-initial-prototype-change.js
@@ -26,10 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
-// Flags: --parallel-recompilation --parallel-recompilation-delay=100
+// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -42,7 +42,7 @@ assertEquals(0.5, f1(arr, 0));
assertEquals(0.5, f1(arr, 0));
// Optimized code of f1 depends on initial object and array maps.
-%OptimizeFunctionOnNextCall(f1, "parallel");
+%OptimizeFunctionOnNextCall(f1, "concurrent");
// Trigger optimization in the background thread
assertEquals(0.5, f1(arr, 0));
Object.prototype[1] = 1.5; // Invalidate current initial object map.
diff --git a/deps/v8/test/mjsunit/parallel-invalidate-transition-map.js b/deps/v8/test/mjsunit/parallel-invalidate-transition-map.js
index 716f63198c..9a5d31003f 100644
--- a/deps/v8/test/mjsunit/parallel-invalidate-transition-map.js
+++ b/deps/v8/test/mjsunit/parallel-invalidate-transition-map.js
@@ -26,10 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --track-fields --track-double-fields --allow-natives-syntax
-// Flags: --parallel-recompilation --parallel-recompilation-delay=100
+// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -46,7 +46,7 @@ function add_field(obj) {
add_field(new_object());
add_field(new_object());
-%OptimizeFunctionOnNextCall(add_field, "parallel");
+%OptimizeFunctionOnNextCall(add_field, "concurrent");
var o = new_object();
// Trigger optimization in the background thread.
diff --git a/deps/v8/test/mjsunit/parallel-optimize-disabled.js b/deps/v8/test/mjsunit/parallel-optimize-disabled.js
index e19dbd095b..c144e649cc 100644
--- a/deps/v8/test/mjsunit/parallel-optimize-disabled.js
+++ b/deps/v8/test/mjsunit/parallel-optimize-disabled.js
@@ -25,11 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --nodead-code-elimination --parallel-recompilation
+// Flags: --nodead-code-elimination --concurrent-recompilation
// Flags: --allow-natives-syntax
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -45,7 +45,7 @@ function f(x) {
f();
f();
%OptimizeFunctionOnNextCall(f);
-%OptimizeFunctionOnNextCall(g, "parallel");
+%OptimizeFunctionOnNextCall(g, "concurrent");
f(0); // g() is disabled for optimization on inlining attempt.
// Attempt to optimize g() should not run into any assertion.
assertUnoptimized(g, "sync");
diff --git a/deps/v8/test/mjsunit/regress/post-increment-close-context.js b/deps/v8/test/mjsunit/regress/post-increment-close-context.js
new file mode 100644
index 0000000000..08ade10f1d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/post-increment-close-context.js
@@ -0,0 +1,42 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var foo = {bar: -2};
+function crash() {
+ return !(foo.bar++);
+}
+assertFalse(crash());
+assertEquals(-1, foo.bar);
+%OptimizeFunctionOnNextCall(crash);
+assertFalse(crash());
+assertEquals(0, foo.bar);
+assertTrue(crash());
+assertEquals(1, foo.bar);
+assertFalse(crash());
+assertEquals(2, foo.bar);
diff --git a/deps/v8/test/mjsunit/regress/regress-2594.js b/deps/v8/test/mjsunit/regress/regress-2594.js
new file mode 100644
index 0000000000..60720cb804
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2594.js
@@ -0,0 +1,104 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// In the assertions but the first, the ES5 spec actually requires 0, but
+// that is arguably a spec bug, and other browsers return 1 like us.
+// In ES6, all of those will presumably result in a ReferenceError.
+// Our main concern with this test is that we do not crash, though.
+
+function f1() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ eval("var h = function() { return XXX }")
+ }
+ return h()
+}
+assertEquals(1, f1())
+
+function f2() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ eval("function h(){ return XXX }")
+ }
+ return h()
+}
+assertEquals(1, f2())
+
+function f3() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ try { throw 2 } catch (y) {
+ eval("function h(){ return XXX }")
+ }
+ }
+ return h()
+}
+assertEquals(1, f3())
+
+function f4() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ with ({}) {
+ eval("function h(){ return XXX }")
+ }
+ }
+ return h()
+}
+assertEquals(1, f4())
+
+function f5() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ eval('eval("function h(){ return XXX }")')
+ }
+ return h()
+}
+assertEquals(1, f5())
+
+function f6() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ eval("var h = (function() { function g(){ return XXX } return g })()")
+ }
+ return h()
+}
+assertEquals(1, f6())
+
+function f7() {
+ var XXX = 0
+ try { throw 1 } catch (XXX) {
+ eval("function h() { var XXX=2; function g(){ return XXX } return g }")
+ }
+ return h()()
+}
+assertEquals(2, f7()) // !
+
+var XXX = 0
+try { throw 1 } catch (XXX) {
+ eval("function h(){ return XXX }")
+}
+assertEquals(1, h())
diff --git a/deps/v8/test/mjsunit/regress/regress-2829.js b/deps/v8/test/mjsunit/regress/regress-2829.js
new file mode 100644
index 0000000000..a046ae0395
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2829.js
@@ -0,0 +1,53 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-collections
+
+(function test1() {
+ var wm1 = new WeakMap();
+ wm1.set(Object.prototype, 23);
+ assertTrue(wm1.has(Object.prototype));
+ Object.freeze(Object.prototype);
+
+ var wm2 = new WeakMap();
+ var o = {};
+ wm2.set(o, 42);
+ assertEquals(42, wm2.get(o));
+})();
+
+(function test2() {
+ var wm1 = new WeakMap();
+ var o1 = {};
+ wm1.set(o1, 23);
+ assertTrue(wm1.has(o1));
+ Object.freeze(o1);
+
+ var wm2 = new WeakMap();
+ var o2 = Object.create(o1);
+ wm2.set(o2, 42);
+ assertEquals(42, wm2.get(o2));
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-2855.js b/deps/v8/test/mjsunit/regress/regress-2855.js
new file mode 100644
index 0000000000..24ec452d59
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2855.js
@@ -0,0 +1,57 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function foo(a) {
+ for (var i = 0; i < 100; ++i)
+ a = new String(a);
+ return a;
+}
+
+var expected = "hello";
+for (var i = 0; i < 4; ++i) {
+ if (i == 2) {
+ String.prototype.valueOf = function() { return 42; }
+ expected = "42";
+ }
+ assertEquals(expected, "" + foo("hello"));
+}
+
+// Make sure we look up "valueOf" only once.
+var count = 0;
+var x = new String("foo");
+Object.defineProperty(x, "valueOf",
+ { get: function() {
+ count++;
+ return function() {
+ return 11;
+ }
+ }
+ });
+for (var i = 0; i < 3; i++) {
+ assertEquals("11", "" + x);
+ assertEquals(i + 1, count);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-convert-function-to-double.js b/deps/v8/test/mjsunit/regress/regress-convert-function-to-double.js
new file mode 100644
index 0000000000..fca44f9632
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-convert-function-to-double.js
@@ -0,0 +1,36 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function f(v) {
+ this.func = v;
+}
+
+var o1 = new f(f);
+var d = 1.4;
+var o2 = new f(d);
+o2.func = 1.8;
+assertEquals(1.4, d)
diff --git a/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js b/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js
index 3a66235684..52c32e9cc3 100644
--- a/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js
+++ b/deps/v8/test/mjsunit/regress/regress-debug-deopt-while-recompile.js
@@ -61,8 +61,8 @@ g();
// Mark with builtin.
%OptimizeFunctionOnNextCall(f);
-if (%IsParallelRecompilationSupported()) {
- %OptimizeFunctionOnNextCall(g, "parallel");
+if (%IsConcurrentRecompilationSupported()) {
+ %OptimizeFunctionOnNextCall(g, "concurrent");
}
// Activate debugger.
diff --git a/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js b/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js
index 6a63da2fde..58a0b1c869 100644
--- a/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js
+++ b/deps/v8/test/mjsunit/regress/regress-embedded-cons-string.js
@@ -27,27 +27,27 @@
// Flags: --fold-constants --nodead-code-elimination
// Flags: --expose-gc --allow-natives-syntax
-// Flags: --parallel-recompilation --parallel-recompilation-delay=300
+// Flags: --concurrent-recompilation --concurrent-recompilation-delay=300
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
function test(fun) {
fun();
fun();
- // Mark for parallel optimization.
- %OptimizeFunctionOnNextCall(fun, "parallel");
+ // Mark for concurrent optimization.
+ %OptimizeFunctionOnNextCall(fun, "concurrent");
//Trigger optimization in the background.
fun();
//Tenure cons string.
gc();
- // In the mean time, parallel recompiling is not complete yet.
+ // In the mean time, concurrent recompiling is not complete yet.
assertUnoptimized(fun, "no sync");
- // Parallel recompilation eventually finishes and embeds tenured cons string.
+ // Concurrent recompilation eventually finishes, embeds tenured cons string.
assertOptimized(fun, "sync");
- //Visit embedded cons string during mark compact.
+ // Visit embedded cons string during mark compact.
gc();
}
diff --git a/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js b/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js
index 6605ba7858..1f896a495f 100644
--- a/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js
+++ b/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js
@@ -31,19 +31,24 @@ var c = { x: 2, y: 1 };
function g() {
var outer = { foo: 1 };
- function f() {
+ function f(b, c) {
var n = outer.foo;
- for (var i = 0; i < 100000; i++) {
+ for (var i = 0; i < 10; i++) {
n += c.x + outer.foo;
}
- var o2 = [{ x: 1.5, y: 1 }];
- return o2;
+ if (b) return [{ x: 1.5, y: 1 }];
+ else return c;
}
+ // Clear type feedback from previous stress runs.
+ %ClearFunctionTypeFeedback(f);
return f;
}
var fun = g();
-fun();
+fun(false, c);
+fun(false, c);
+fun(false, c);
+%OptimizeFunctionOnNextCall(fun);
+fun(false, c);
+fun(true, c);
assertOptimized(fun);
-fun();
-
diff --git a/deps/v8/test/mjsunit/regress/regress-merge-descriptors.js b/deps/v8/test/mjsunit/regress/regress-merge-descriptors.js
new file mode 100644
index 0000000000..a84a6254a0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-merge-descriptors.js
@@ -0,0 +1,92 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var extend = function (d, b) {
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+
+var Car = (function (Super) {
+ var Car = function () {
+ var self = this;
+
+ Super.call(self);
+
+ Object.defineProperties(self, {
+ "make": {
+ enumerable: true,
+ configurable: true,
+ get: function () {
+ return "Ford";
+ }
+ }
+ });
+
+ self.copy = function () {
+ throw new Error("Meant to be overriden");
+ };
+
+ return self;
+ };
+
+ extend(Car, Super);
+
+ return Car;
+}(Object));
+
+
+var SuperCar = ((function (Super) {
+ var SuperCar = function (make) {
+ var self = this;
+
+ Super.call(self);
+
+
+ Object.defineProperties(self, {
+ "make": {
+ enumerable: true,
+ configurable: true,
+ get: function () {
+ return make;
+ }
+ }
+ });
+
+ // Convert self.copy from CONSTANT to FIELD.
+ self.copy = function () { };
+
+ return self;
+ };
+ extend(SuperCar, Super);
+ return SuperCar;
+})(Car));
+
+assertEquals("Ford", new Car().make);
+assertEquals("Bugatti", new SuperCar("Bugatti").make);
+assertEquals("Lambo", new SuperCar("Lambo").make);
+assertEquals("Shelby", new SuperCar("Shelby").make);
diff --git a/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js b/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js
index 3de0217c81..8bf95ec5aa 100644
--- a/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js
+++ b/deps/v8/test/mjsunit/regress/regress-opt-after-debug-deopt.js
@@ -26,10 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax
-// Flags: --parallel-recompilation --parallel-recompilation-delay=100
+// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -57,12 +57,12 @@ var f = function() {
f();
f();
-%OptimizeFunctionOnNextCall(f, "parallel"); // Mark with builtin.
-f(); // Kick off parallel recompilation.
+%OptimizeFunctionOnNextCall(f, "concurrent"); // Mark with builtin.
+f(); // Kick off concurrent recompilation.
Debug.setListener(listener); // Activate debugger.
Debug.setBreakPoint(f, 2, 0); // Force deopt.
-// Sync with parallel optimization thread. But no optimized code is installed.
+// Sync with optimization thread. But no optimized code is installed.
assertUnoptimized(f, "sync");
f(); // Trigger break point.
diff --git a/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js b/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js
index e494173856..2fad5ca0d2 100644
--- a/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js
+++ b/deps/v8/test/mjsunit/regress/regress-prepare-break-while-recompile.js
@@ -26,10 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax
-// Flags: --parallel-recompilation-delay=300
+// Flags: --concurrent-recompilation-delay=300
-if (!%IsParallelRecompilationSupported()) {
- print("Parallel recompilation is disabled. Skipping this test.");
+if (!%IsConcurrentRecompilationSupported()) {
+ print("Concurrent recompilation is disabled. Skipping this test.");
quit();
}
@@ -46,8 +46,8 @@ function bar() {
}
foo();
-// Mark and trigger parallel optimization.
-%OptimizeFunctionOnNextCall(foo, "parallel");
+// Mark and trigger concurrent optimization.
+%OptimizeFunctionOnNextCall(foo, "concurrent");
foo();
// Set break points on an unrelated function. This clears both optimized
@@ -56,7 +56,7 @@ foo();
Debug.setBreakPoint(bar, 0, 0);
Debug.clearAllBreakPoints();
-// Install optimized code when parallel optimization finishes.
+// Install optimized code when concurrent optimization finishes.
// This needs to be able to deal with shared code being a builtin.
assertUnoptimized(foo, "sync");
diff --git a/deps/v8/test/mjsunit/regress/regress-store-uncacheable.js b/deps/v8/test/mjsunit/regress/regress-store-uncacheable.js
new file mode 100644
index 0000000000..e9c9fc25b4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-store-uncacheable.js
@@ -0,0 +1,40 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function f() {
+ var o = {};
+ o["<abc>"] = 123;
+}
+
+f();
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
+assertOptimized(f);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-282736.js b/deps/v8/test/mjsunit/regress/regress-x87.js
index afd9f75be4..60380a8fcb 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-282736.js
+++ b/deps/v8/test/mjsunit/regress/regress-x87.js
@@ -25,35 +25,24 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-function funcify(obj) {
- var type = typeof obj;
- if (type === "object") {
- var funcified = {}, foo = {};
- for (var prop in obj) {
- funcified[prop] = funcify(obj[prop]);
- foo[prop] = true;
- }
- return funcified;
- } else if (type === "function") {
- return obj;
+// Flags: --allow-natives-syntax --noenable-sse2
+
+// Regression for register allocation.
+var x;
+var a = new Float32Array([1,2, 4, 6, 8, 11, NaN, 1/0, -3])
+var val = 2.1*a[1]*a[0]*a[1*2*3*0]*a[1*1]*1.0;
+assertEquals(8.4, val);
+
+// Regression for double-phis
+var a;
+var t = true;
+var res = [2.5, 2];
+for (var i = 0; i < 2; i++) {
+ if (t) {
+ a = 1.5;
} else {
- return function () { return obj; };
+ a = true;
}
+ assertEquals(res[i], a+1);
+ t = false;
}
-
-var obj = {};
-
-obj.A = 1;
-obj.B = function () { return 2; };
-obj.C = 3;
-obj.D = 4;
-
-var funcified = funcify(obj);
-
-assertEquals("function", typeof funcified.A);
-assertEquals(1, funcified.A());
-assertEquals("function", typeof funcified.B);
-assertEquals(2, funcified.B());
-assertEquals("function", typeof funcified.C);
-assertEquals("function", typeof funcified.D);
-assertEquals(4, funcified.D());
diff --git a/deps/v8/test/mjsunit/smi-mul.js b/deps/v8/test/mjsunit/smi-mul.js
new file mode 100644
index 0000000000..6f23d5e3a0
--- /dev/null
+++ b/deps/v8/test/mjsunit/smi-mul.js
@@ -0,0 +1,67 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --noalways-opt
+
+function mul(a, b) {
+ return a * b;
+}
+
+
+mul(-1, 2);
+mul(-1, 2);
+%OptimizeFunctionOnNextCall(mul);
+assertEquals(-2, mul(-1, 2));
+assertOptimized(mul);
+
+// Deopt on minus zero.
+assertEquals(-0, mul(-1, 0));
+assertUnoptimized(mul);
+
+
+function mul2(a, b) {
+ return a * b;
+}
+
+mul2(-1, 2);
+mul2(-1, 2);
+%OptimizeFunctionOnNextCall(mul2);
+
+// 2^30 is a smi boundary on arm and ia32.
+var two_30 = 1 << 30;
+// 2^31 is a smi boundary on x64.
+var two_31 = 2 * two_30;
+
+if (%IsValidSmi(two_31)) {
+ // Deopt on two_31 on x64.
+ assertEquals(two_31, mul2(-two_31, -1));
+ assertUnoptimized(mul2);
+} else {
+ // Deopt on two_30 on ia32.
+ assertEquals(two_30, mul2(-two_30, -1));
+ assertUnoptimized(mul2);
+}
diff --git a/deps/v8/test/mjsunit/track-fields.js b/deps/v8/test/mjsunit/track-fields.js
index 8b0ec29623..4da1ab5d22 100644
--- a/deps/v8/test/mjsunit/track-fields.js
+++ b/deps/v8/test/mjsunit/track-fields.js
@@ -211,7 +211,6 @@ assertFalse(%HaveSameMap(o18, o19));
delete o18.to_delete;
delete o19.to_delete;
-assertTrue(%HaveSameMap(o18, o19));
assertEquals(1, o18.field2);
assertEquals(1.6, o19.field2);