summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-09-08 17:14:42 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-09-08 17:14:42 -0700
commit8796ed22783bbbb9d286463e27db275325106fed (patch)
treec4d13c9a6dc9196925489392ffe589f4d43d8939 /deps/v8/test/cctest
parent512016fd7441d8919c29f369a38622ab1dd01942 (diff)
downloadnode-8796ed22783bbbb9d286463e27db275325106fed.tar.gz
Upgrade V8 to 2.4.2
Diffstat (limited to 'deps/v8/test/cctest')
-rw-r--r--deps/v8/test/cctest/cctest.status8
-rw-r--r--deps/v8/test/cctest/test-api.cc34
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc54
-rw-r--r--deps/v8/test/cctest/test-assembler-mips.cc2
-rw-r--r--deps/v8/test/cctest/test-ast.cc29
-rw-r--r--deps/v8/test/cctest/test-debug.cc147
-rw-r--r--deps/v8/test/cctest/test-disasm-arm.cc48
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc125
-rw-r--r--deps/v8/test/cctest/test-heap.cc40
-rw-r--r--deps/v8/test/cctest/test-list.cc39
-rw-r--r--deps/v8/test/cctest/test-log-stack-tracer.cc124
-rwxr-xr-xdeps/v8/test/cctest/test-parsing.cc112
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc17
-rw-r--r--deps/v8/test/cctest/test-serialize.cc15
-rw-r--r--deps/v8/test/cctest/test-utils.cc61
-rw-r--r--deps/v8/test/cctest/testcfg.py8
16 files changed, 737 insertions, 126 deletions
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 7689371a0..d03f5f7a0 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -35,6 +35,11 @@ test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux
# BUG(382): Weird test. Can't guarantee that it never times out.
test-api/ApplyInterruption: PASS || TIMEOUT
+# Bug (484): This test which we thought was originally corrected in r5236
+# is reappering. Disabled until bug in test is fixed. This only fails
+# when snapshot is on, so I am marking it PASS || FAIL
+test-heap-profiler/HeapSnapshotsDiff: PASS || FAIL
+
# These tests always fail. They are here to test test.py. If
# they don't fail then test.py has failed.
test-serialize/TestThatAlwaysFails: FAIL
@@ -42,9 +47,6 @@ test-serialize/DependentTestThatAlwaysFails: FAIL
[ $arch == arm ]
-# BUG(240): Test seems flaky on ARM.
-test-api/RegExpInterruption: SKIP
-
# We cannot assume that we can throw OutOfMemory exceptions in all situations.
# Apparently our ARM box is in such a state. Skip the test as it also runs for
# a long time.
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 8bfa51c60..2b50db7ec 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -37,6 +37,7 @@
#include "top.h"
#include "utils.h"
#include "cctest.h"
+#include "parser.h"
static const bool kLogThreading = true;
@@ -3605,6 +3606,29 @@ THREADED_TEST(ExceptionExtensions) {
}
+static const char* kNativeCallInExtensionSource =
+ "function call_runtime_last_index_of(x) {"
+ " return %StringLastIndexOf(x, 'bob', 10);"
+ "}";
+
+
+static const char* kNativeCallTest =
+ "call_runtime_last_index_of('bobbobboellebobboellebobbob');";
+
+// Test that a native runtime calls are supported in extensions.
+THREADED_TEST(NativeCallInExtensions) {
+ v8::HandleScope handle_scope;
+ v8::RegisterExtension(new Extension("nativecall",
+ kNativeCallInExtensionSource));
+ const char* extension_names[] = { "nativecall" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ Context::Scope lock(context);
+ v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run();
+ CHECK_EQ(result, v8::Integer::New(3));
+}
+
+
static void CheckDependencies(const char* name, const char* expected) {
v8::HandleScope handle_scope;
v8::ExtensionConfiguration config(1, &name);
@@ -8601,15 +8625,12 @@ TEST(PreCompileInvalidPreparseDataError) {
v8::ScriptData::PreCompile(script, i::StrLength(script));
CHECK(!sd->HasError());
// ScriptDataImpl private implementation details
- const int kUnsignedSize = sizeof(unsigned);
- const int kHeaderSize = 4;
- const int kFunctionEntrySize = 4;
+ const int kHeaderSize = i::ScriptDataImpl::kHeaderSize;
+ const int kFunctionEntrySize = i::FunctionEntry::kSize;
const int kFunctionEntryStartOffset = 0;
const int kFunctionEntryEndOffset = 1;
unsigned* sd_data =
reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
- CHECK_EQ(sd->Length(),
- (kHeaderSize + 2 * kFunctionEntrySize) * kUnsignedSize);
// Overwrite function bar's end position with 0.
sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryEndOffset] = 0;
@@ -8625,6 +8646,8 @@ TEST(PreCompileInvalidPreparseDataError) {
try_catch.Reset();
// Overwrite function bar's start position with 200. The function entry
// will not be found when searching for it by position.
+ sd = v8::ScriptData::PreCompile(script, i::StrLength(script));
+ sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] =
200;
compiled_script = Script::New(source, NULL, sd);
@@ -9203,6 +9226,7 @@ class RegExpStringModificationTest {
morphs_ < kMaxModifications) {
int morphs_before = morphs_;
{
+ v8::HandleScope scope;
// Match 15-30 "a"'s against 14 and a "b".
const char* c_source =
"/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index 9033f4b87..7c669d30b 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -91,7 +91,7 @@ TEST(1) {
Label L, C;
__ mov(r1, Operand(r0));
- __ mov(r0, Operand(0));
+ __ mov(r0, Operand(0, RelocInfo::NONE));
__ b(&C);
__ bind(&L);
@@ -99,7 +99,7 @@ TEST(1) {
__ sub(r1, r1, Operand(1));
__ bind(&C);
- __ teq(r1, Operand(0));
+ __ teq(r1, Operand(0, RelocInfo::NONE));
__ b(ne, &L);
__ mov(pc, Operand(lr));
@@ -135,7 +135,7 @@ TEST(2) {
__ sub(r1, r1, Operand(1));
__ bind(&C);
- __ teq(r1, Operand(0));
+ __ teq(r1, Operand(0, RelocInfo::NONE));
__ b(ne, &L);
__ mov(pc, Operand(lr));
@@ -226,11 +226,17 @@ TEST(4) {
double a;
double b;
double c;
+ double d;
+ double e;
+ double f;
+ int i;
+ float x;
+ float y;
} T;
T t;
// Create a function that accepts &t, and loads, manipulates, and stores
- // the doubles t.a, t.b, and t.c.
+ // the doubles and floats.
Assembler assm(NULL, 0);
Label L, C;
@@ -252,6 +258,34 @@ TEST(4) {
__ vmov(d4, r2, r3);
__ vstr(d4, r4, OFFSET_OF(T, b));
+ // Load t.x and t.y, switch values, and store back to the struct.
+ __ vldr(s0, r4, OFFSET_OF(T, x));
+ __ vldr(s31, r4, OFFSET_OF(T, y));
+ __ vmov(s16, s0);
+ __ vmov(s0, s31);
+ __ vmov(s31, s16);
+ __ vstr(s0, r4, OFFSET_OF(T, x));
+ __ vstr(s31, r4, OFFSET_OF(T, y));
+
+ // Move a literal into a register that can be encoded in the instruction.
+ __ vmov(d4, 1.0);
+ __ vstr(d4, r4, OFFSET_OF(T, e));
+
+ // Move a literal into a register that requires 64 bits to encode.
+ // 0x3ff0000010000000 = 1.000000059604644775390625
+ __ vmov(d4, 1.000000059604644775390625);
+ __ vstr(d4, r4, OFFSET_OF(T, d));
+
+ // Convert from floating point to integer.
+ __ vmov(d4, 2.0);
+ __ vcvt_s32_f64(s31, d4);
+ __ vstr(s31, r4, OFFSET_OF(T, i));
+
+ // Convert from integer to floating point.
+ __ mov(lr, Operand(42));
+ __ vmov(s31, lr);
+ __ vcvt_f64_s32(d4, s31);
+ __ vstr(d4, r4, OFFSET_OF(T, f));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
CodeDesc desc;
@@ -267,8 +301,20 @@ TEST(4) {
t.a = 1.5;
t.b = 2.75;
t.c = 17.17;
+ t.d = 0.0;
+ t.e = 0.0;
+ t.f = 0.0;
+ t.i = 0;
+ t.x = 4.5;
+ t.y = 9.0;
Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
USE(dummy);
+ CHECK_EQ(4.5, t.y);
+ CHECK_EQ(9.0, t.x);
+ CHECK_EQ(2, t.i);
+ CHECK_EQ(42.0, t.f);
+ CHECK_EQ(1.0, t.e);
+ CHECK_EQ(1.000000059604644775390625, t.d);
CHECK_EQ(4.25, t.c);
CHECK_EQ(4.25, t.b);
CHECK_EQ(1.5, t.a);
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc
index 0a2310e3e..955562b28 100644
--- a/deps/v8/test/cctest/test-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-assembler-mips.cc
@@ -109,7 +109,7 @@ TEST(MIPS1) {
__ bind(&C);
__ xori(v1, a1, 0);
- __ Branch(ne, &L, v1, Operand(0));
+ __ Branch(ne, &L, v1, Operand(0, RelocInfo::NONE));
__ nop();
__ jr(ra);
diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc
index 9931f5607..9c292bcfc 100644
--- a/deps/v8/test/cctest/test-ast.cc
+++ b/deps/v8/test/cctest/test-ast.cc
@@ -57,35 +57,6 @@ TEST(List) {
}
-TEST(RemoveLast) {
- List<int> list(4);
- CHECK_EQ(0, list.length());
- list.Add(1);
- CHECK_EQ(1, list.length());
- CHECK_EQ(1, list.last());
- list.RemoveLast();
- CHECK_EQ(0, list.length());
- list.Add(2);
- list.Add(3);
- CHECK_EQ(2, list.length());
- CHECK_EQ(3, list.last());
- list.RemoveLast();
- CHECK_EQ(1, list.length());
- CHECK_EQ(2, list.last());
- list.RemoveLast();
- CHECK_EQ(0, list.length());
-
- const int kElements = 100;
- for (int i = 0; i < kElements; i++) list.Add(i);
- for (int j = kElements - 1; j >= 0; j--) {
- CHECK_EQ(j + 1, list.length());
- CHECK_EQ(j, list.last());
- list.RemoveLast();
- CHECK_EQ(j, list.length());
- }
-}
-
-
TEST(DeleteEmpty) {
{
List<int>* list = new List<int>(0);
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 0455790e0..f5526cea9 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -869,8 +869,8 @@ static void DebugEventBreakPointCollectGarbage(
// Scavenge.
Heap::CollectGarbage(0, v8::internal::NEW_SPACE);
} else {
- // Mark sweep (and perhaps compact).
- Heap::CollectAllGarbage(false);
+ // Mark sweep compact.
+ Heap::CollectAllGarbage(true);
}
}
}
@@ -1127,7 +1127,7 @@ TEST(BreakPointICCall) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- // Run with breakpoint
+ // Run with breakpoint.
int bp = SetBreakPoint(foo, 0);
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -1144,6 +1144,73 @@ TEST(BreakPointICCall) {
}
+// Test that a break point can be set at an IC call location and survive a GC.
+TEST(BreakPointICCallWithGC) {
+ break_point_hit_count = 0;
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
+ v8::Undefined());
+ 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 =
+ v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
+
+ // Run without breakpoints.
+ CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ int bp = SetBreakPoint(foo, 0);
+ CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
+ CHECK_EQ(1, break_point_hit_count);
+ CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(2, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
+// Test that a break point can be set at an IC call location and survive a GC.
+TEST(BreakPointConstructCallWithGC) {
+ break_point_hit_count = 0;
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
+ v8::Undefined());
+ 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();
+ v8::Local<v8::Function> foo =
+ v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
+
+ // Run without breakpoints.
+ CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ int bp = SetBreakPoint(foo, 0);
+ CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
+ CHECK_EQ(1, break_point_hit_count);
+ CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(2, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
// Test that a break point can be set at a return store location.
TEST(BreakPointReturn) {
break_point_hit_count = 0;
@@ -2680,6 +2747,65 @@ TEST(DebugStepNamedLoadLoop) {
}
+static void DoDebugStepNamedStoreLoop(int expected, bool full_compiler = true) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+
+ // Register a debug event listener which steps and counts before compiling the
+ // function to ensure the full compiler is used.
+ if (full_compiler) {
+ v8::Debug::SetDebugEventListener(DebugEventStep);
+ }
+
+ // Create a function for testing stepping of named store.
+ v8::Local<v8::Function> foo = CompileFunction(
+ &env,
+ "function foo() {\n"
+ " var a = {a:1};\n"
+ " for (var i = 0; i < 10; i++) {\n"
+ " a.a = 2\n"
+ " }\n"
+ "}\n",
+ "foo");
+
+ // Call function without any break points to ensure inlining is in place.
+ foo->Call(env->Global(), 0, NULL);
+
+ // Register a debug event listener which steps and counts after compiling the
+ // function to ensure the optimizing compiler is used.
+ if (!full_compiler) {
+ v8::Debug::SetDebugEventListener(DebugEventStep);
+ }
+
+ // Setup break point and step through the function.
+ SetBreakPoint(foo, 3);
+ step_action = StepNext;
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+
+ // With stepping all expected break locations are hit.
+ CHECK_EQ(expected, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
+// Test of the stepping mechanism for named load in a loop.
+TEST(DebugStepNamedStoreLoopFull) {
+ // With the full compiler it is possible to break on the for statement.
+ DoDebugStepNamedStoreLoop(22);
+}
+
+
+// Test of the stepping mechanism for named load in a loop.
+TEST(DebugStepNamedStoreLoopOptimizing) {
+ // With the optimizing compiler it is not possible to break on the for
+ // statement as it uses a local variable thus no IC's.
+ DoDebugStepNamedStoreLoop(11, false);
+}
+
+
// Test the stepping mechanism with different ICs.
TEST(DebugStepLinearMixedICs) {
v8::HandleScope scope;
@@ -4465,6 +4591,18 @@ int GetTotalFramesInt(char *message) {
}
+// We match parts of the message to get source line.
+int GetSourceLineFromBreakEventMessage(char *message) {
+ const char* source_line = "\"sourceLine\":";
+ char* pos = strstr(message, source_line);
+ if (pos == NULL) {
+ return -1;
+ }
+ int res = -1;
+ res = StringToInt(pos + strlen(source_line));
+ return res;
+}
+
/* Test MessageQueues */
/* Tests the message queues that hold debugger commands and
* response messages to the debugger. Fills queues and makes
@@ -4744,6 +4882,9 @@ static void ThreadedMessageHandler(const v8::Debug::Message& message) {
v8::String::Value json(message.GetJSON());
Utf16ToAscii(*json, json.length(), print_buffer);
if (IsBreakEventMessage(print_buffer)) {
+ // Check that we are inside the while loop.
+ int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
+ CHECK(8 <= source_line && source_line <= 13);
threaded_debugging_barriers.barrier_2.Wait();
}
}
diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc
index 0ba4f9ae4..61f5ffc72 100644
--- a/deps/v8/test/cctest/test-disasm-arm.cc
+++ b/deps/v8/test/cctest/test-disasm-arm.cc
@@ -422,6 +422,19 @@ TEST(Vfp) {
COMPARE(vmov(d3, d3, eq),
"0eb03b43 vmov.f64eq d3, d3");
+ COMPARE(vmov(s0, s31),
+ "eeb00a6f vmov.f32 s0, s31");
+ COMPARE(vmov(s31, s0),
+ "eef0fa40 vmov.f32 s31, s0");
+ COMPARE(vmov(r0, s0),
+ "ee100a10 vmov r0, s0");
+ COMPARE(vmov(r10, s31),
+ "ee1faa90 vmov r10, s31");
+ COMPARE(vmov(s0, r0),
+ "ee000a10 vmov s0, r0");
+ COMPARE(vmov(s31, r10),
+ "ee0faa90 vmov s31, r10");
+
COMPARE(vadd(d0, d1, d2),
"ee310b02 vadd.f64 d0, d1, d2");
COMPARE(vadd(d3, d4, d5, mi),
@@ -451,6 +464,41 @@ TEST(Vfp) {
"eeb70b00 vmov.f64 d0, #1");
COMPARE(vmov(d2, -13.0),
"eeba2b0a vmov.f64 d2, #-13");
+
+ COMPARE(vldr(s0, r0, 0),
+ "ed900a00 vldr s0, [r0 + 4*0]");
+ COMPARE(vldr(s1, r1, 4),
+ "edd10a01 vldr s1, [r1 + 4*1]");
+ COMPARE(vldr(s15, r4, 16),
+ "edd47a04 vldr s15, [r4 + 4*4]");
+ COMPARE(vldr(s16, r5, 20),
+ "ed958a05 vldr s16, [r5 + 4*5]");
+ COMPARE(vldr(s31, r10, 1020),
+ "eddafaff vldr s31, [r10 + 4*255]");
+
+ COMPARE(vstr(s0, r0, 0),
+ "ed800a00 vstr s0, [r0 + 4*0]");
+ COMPARE(vstr(s1, r1, 4),
+ "edc10a01 vstr s1, [r1 + 4*1]");
+ COMPARE(vstr(s15, r8, 8),
+ "edc87a02 vstr s15, [r8 + 4*2]");
+ COMPARE(vstr(s16, r9, 12),
+ "ed898a03 vstr s16, [r9 + 4*3]");
+ COMPARE(vstr(s31, r10, 1020),
+ "edcafaff vstr s31, [r10 + 4*255]");
+
+ COMPARE(vldr(d0, r0, 0),
+ "ed900b00 vldr d0, [r0 + 4*0]");
+ COMPARE(vldr(d1, r1, 4),
+ "ed911b01 vldr d1, [r1 + 4*1]");
+ COMPARE(vldr(d15, r10, 1020),
+ "ed9afbff vldr d15, [r10 + 4*255]");
+ COMPARE(vstr(d0, r0, 0),
+ "ed800b00 vstr d0, [r0 + 4*0]");
+ COMPARE(vstr(d1, r1, 4),
+ "ed811b01 vstr d1, [r1 + 4*1]");
+ COMPARE(vstr(d15, r10, 1020),
+ "ed8afbff vstr d15, [r10 + 4*255]");
}
VERIFY_RUN();
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index 92ad0a400..6dc49c0e5 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -372,6 +372,7 @@ TEST(RetainerProfile) {
i::HeapIterator iterator;
for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
ret_profile.CollectStats(obj);
+ ret_profile.CoarseAndAggregate();
RetainerProfilePrinter printer;
ret_profile.DebugPrintStats(&printer);
const char* retainers_of_a = printer.GetRetainers("A");
@@ -650,6 +651,8 @@ TEST(HeapSnapshotCodeObjects) {
CompileAndRunScript(
"function lazy(x) { return x - 1; }\n"
"function compiled(x) { return x + 1; }\n"
+ "var inferred = function(x) { return x; }\n"
+ "var anonymous = (function() { return function() { return 0; } })();\n"
"compiled(1)");
const v8::HeapSnapshot* snapshot =
v8::HeapProfiler::TakeSnapshot(v8::String::New("code"));
@@ -663,6 +666,18 @@ TEST(HeapSnapshotCodeObjects) {
GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
CHECK_NE(NULL, lazy);
CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
+ const v8::HeapGraphNode* inferred =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "inferred");
+ CHECK_NE(NULL, inferred);
+ CHECK_EQ(v8::HeapGraphNode::kClosure, inferred->GetType());
+ v8::String::AsciiValue inferred_name(inferred->GetName());
+ CHECK_EQ("inferred", *inferred_name);
+ const v8::HeapGraphNode* anonymous =
+ GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous");
+ CHECK_NE(NULL, anonymous);
+ CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType());
+ v8::String::AsciiValue anonymous_name(anonymous->GetName());
+ CHECK_EQ("(anonymous function)", *anonymous_name);
// Find references to code.
const v8::HeapGraphNode* compiled_code =
@@ -864,4 +879,114 @@ TEST(Issue822) {
i::HeapSnapshotTester::CalculateNetworkSize(*jsobj);
}
+
+static const v8::HeapGraphNode* GetChild(
+ const v8::HeapGraphNode* node,
+ v8::HeapGraphNode::Type type,
+ const char* name,
+ const v8::HeapGraphNode* after = NULL) {
+ bool ignore_child = after == NULL ? false : true;
+ for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = node->GetChild(i);
+ const v8::HeapGraphNode* child = prop->GetToNode();
+ v8::String::AsciiValue child_name(child->GetName());
+ if (!ignore_child
+ && child->GetType() == type
+ && strcmp(name, *child_name) == 0)
+ return child;
+ if (after != NULL && child == after) ignore_child = false;
+ }
+ return NULL;
+}
+
+static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
+ int element) {
+ for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = node->GetRetainer(i);
+ if (prop->GetType() == v8::HeapGraphEdge::kElement
+ && element == prop->GetName()->Int32Value())
+ return true;
+ }
+ return false;
+}
+
+TEST(AggregatedHeapSnapshot) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileAndRunScript(
+ "function A() {}\n"
+ "function B(x) { this.x = x; }\n"
+ "var a = new A();\n"
+ "var b = new B(a);");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(
+ v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
+ const v8::HeapGraphNode* strings = GetChild(snapshot->GetRoot(),
+ v8::HeapGraphNode::kInternal,
+ "STRING_TYPE");
+ CHECK_NE(NULL, strings);
+ CHECK_NE(0, strings->GetSelfSize());
+ CHECK_NE(0, strings->GetInstancesCount());
+ const v8::HeapGraphNode* maps = GetChild(snapshot->GetRoot(),
+ v8::HeapGraphNode::kInternal,
+ "MAP_TYPE");
+ CHECK_NE(NULL, maps);
+ CHECK_NE(0, maps->GetSelfSize());
+ CHECK_NE(0, maps->GetInstancesCount());
+
+ const v8::HeapGraphNode* a = GetChild(snapshot->GetRoot(),
+ v8::HeapGraphNode::kObject,
+ "A");
+ CHECK_NE(NULL, a);
+ CHECK_NE(0, a->GetSelfSize());
+ CHECK_EQ(1, a->GetInstancesCount());
+
+ const v8::HeapGraphNode* b = GetChild(snapshot->GetRoot(),
+ v8::HeapGraphNode::kObject,
+ "B");
+ CHECK_NE(NULL, b);
+ CHECK_NE(0, b->GetSelfSize());
+ CHECK_EQ(1, b->GetInstancesCount());
+
+ const v8::HeapGraphNode* glob_prop = GetChild(snapshot->GetRoot(),
+ v8::HeapGraphNode::kObject,
+ "(global property)",
+ b);
+ CHECK_NE(NULL, glob_prop);
+ CHECK_EQ(0, glob_prop->GetSelfSize());
+ CHECK_EQ(0, glob_prop->GetInstancesCount());
+ CHECK_NE(0, glob_prop->GetChildrenCount());
+
+ const v8::HeapGraphNode* a_from_glob_prop = GetChild(
+ glob_prop,
+ v8::HeapGraphNode::kObject,
+ "A");
+ CHECK_NE(NULL, a_from_glob_prop);
+ CHECK_EQ(0, a_from_glob_prop->GetSelfSize());
+ CHECK_EQ(0, a_from_glob_prop->GetInstancesCount());
+ CHECK_EQ(0, a_from_glob_prop->GetChildrenCount()); // Retains nothing.
+ CHECK(IsNodeRetainedAs(a_from_glob_prop, 1)); // (global propery) has 1 ref.
+
+ const v8::HeapGraphNode* b_with_children = GetChild(
+ snapshot->GetRoot(),
+ v8::HeapGraphNode::kObject,
+ "B",
+ b);
+ CHECK_NE(NULL, b_with_children);
+ CHECK_EQ(0, b_with_children->GetSelfSize());
+ CHECK_EQ(0, b_with_children->GetInstancesCount());
+ CHECK_NE(0, b_with_children->GetChildrenCount());
+
+ const v8::HeapGraphNode* a_from_b = GetChild(
+ b_with_children,
+ v8::HeapGraphNode::kObject,
+ "A");
+ CHECK_NE(NULL, a_from_b);
+ CHECK_EQ(0, a_from_b->GetSelfSize());
+ CHECK_EQ(0, a_from_b->GetInstancesCount());
+ CHECK_EQ(0, a_from_b->GetChildrenCount()); // Retains nothing.
+ CHECK(IsNodeRetainedAs(a_from_b, 1)); // B has 1 ref to A.
+}
+
#endif // ENABLE_LOGGING_AND_PROFILING
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 2c286e3f0..eec024f3f 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -36,8 +36,8 @@ TEST(HeapMaps) {
InitializeVM();
CheckMap(Heap::meta_map(), MAP_TYPE, Map::kSize);
CheckMap(Heap::heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
- CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, FixedArray::kHeaderSize);
- CheckMap(Heap::string_map(), STRING_TYPE, SeqTwoByteString::kAlignedSize);
+ CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+ CheckMap(Heap::string_map(), STRING_TYPE, kVariableSizeSentinel);
}
@@ -637,22 +637,27 @@ TEST(JSArray) {
// Allocate the object.
Handle<JSObject> object = Factory::NewJSObject(function);
Handle<JSArray> array = Handle<JSArray>::cast(object);
- array->Initialize(0);
+ Object* ok = array->Initialize(0);
+ // We just initialized the VM, no heap allocation failure yet.
+ CHECK(!ok->IsFailure());
// Set array length to 0.
- array->SetElementsLength(Smi::FromInt(0));
+ ok = array->SetElementsLength(Smi::FromInt(0));
+ CHECK(!ok->IsFailure());
CHECK_EQ(Smi::FromInt(0), array->length());
CHECK(array->HasFastElements()); // Must be in fast mode.
// array[length] = name.
- array->SetElement(0, *name);
+ ok = array->SetElement(0, *name);
+ CHECK(!ok->IsFailure());
CHECK_EQ(Smi::FromInt(1), array->length());
CHECK_EQ(array->GetElement(0), *name);
// Set array length with larger than smi value.
Handle<Object> length =
Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
- array->SetElementsLength(*length);
+ ok = array->SetElementsLength(*length);
+ CHECK(!ok->IsFailure());
uint32_t int_length = 0;
CHECK(length->ToArrayIndex(&int_length));
@@ -660,7 +665,8 @@ TEST(JSArray) {
CHECK(array->HasDictionaryElements()); // Must be in slow mode.
// array[length] = name.
- array->SetElement(int_length, *name);
+ ok = array->SetElement(int_length, *name);
+ CHECK(!ok->IsFailure());
uint32_t new_int_length = 0;
CHECK(array->length()->ToArrayIndex(&new_int_length));
CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
@@ -684,8 +690,11 @@ TEST(JSObjectCopy) {
obj->SetProperty(*first, Smi::FromInt(1), NONE);
obj->SetProperty(*second, Smi::FromInt(2), NONE);
- obj->SetElement(0, *first);
- obj->SetElement(1, *second);
+ Object* ok = obj->SetElement(0, *first);
+ CHECK(!ok->IsFailure());
+
+ ok = obj->SetElement(1, *second);
+ CHECK(!ok->IsFailure());
// Make the clone.
Handle<JSObject> clone = Copy(obj);
@@ -701,8 +710,10 @@ TEST(JSObjectCopy) {
clone->SetProperty(*first, Smi::FromInt(2), NONE);
clone->SetProperty(*second, Smi::FromInt(1), NONE);
- clone->SetElement(0, *second);
- clone->SetElement(1, *first);
+ ok = clone->SetElement(0, *second);
+ CHECK(!ok->IsFailure());
+ ok = clone->SetElement(1, *first);
+ CHECK(!ok->IsFailure());
CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
@@ -973,9 +984,10 @@ TEST(TestCodeFlushing) {
Heap::CollectAllGarbage(true);
Heap::CollectAllGarbage(true);
- // foo should still be in the compilation cache and therefore not
- // have been removed.
CHECK(function->shared()->is_compiled());
+
+ Heap::CollectAllGarbage(true);
+ Heap::CollectAllGarbage(true);
Heap::CollectAllGarbage(true);
Heap::CollectAllGarbage(true);
Heap::CollectAllGarbage(true);
@@ -983,7 +995,9 @@ TEST(TestCodeFlushing) {
// foo should no longer be in the compilation cache
CHECK(!function->shared()->is_compiled());
+ CHECK(!function->is_compiled());
// Call foo to get it recompiled.
CompileRun("foo()");
CHECK(function->shared()->is_compiled());
+ CHECK(function->is_compiled());
}
diff --git a/deps/v8/test/cctest/test-list.cc b/deps/v8/test/cctest/test-list.cc
index 624b6e939..e20ee8a36 100644
--- a/deps/v8/test/cctest/test-list.cc
+++ b/deps/v8/test/cctest/test-list.cc
@@ -99,3 +99,42 @@ TEST(ListAddAll) {
CHECK_EQ(i % 3, list[i]);
}
}
+
+
+TEST(RemoveLast) {
+ List<int> list(4);
+ CHECK_EQ(0, list.length());
+ list.Add(1);
+ CHECK_EQ(1, list.length());
+ CHECK_EQ(1, list.last());
+ list.RemoveLast();
+ CHECK_EQ(0, list.length());
+ list.Add(2);
+ list.Add(3);
+ CHECK_EQ(2, list.length());
+ CHECK_EQ(3, list.last());
+ list.RemoveLast();
+ CHECK_EQ(1, list.length());
+ CHECK_EQ(2, list.last());
+ list.RemoveLast();
+ CHECK_EQ(0, list.length());
+
+ const int kElements = 100;
+ for (int i = 0; i < kElements; i++) list.Add(i);
+ for (int j = kElements - 1; j >= 0; j--) {
+ CHECK_EQ(j + 1, list.length());
+ CHECK_EQ(j, list.last());
+ list.RemoveLast();
+ CHECK_EQ(j, list.length());
+ }
+}
+
+
+TEST(Clear) {
+ List<int> list(4);
+ CHECK_EQ(0, list.length());
+ for (int i = 0; i < 4; ++i) list.Add(i);
+ CHECK_EQ(4, list.length());
+ list.Clear();
+ CHECK_EQ(0, list.length());
+}
diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc
index 6da1a7597..c92117678 100644
--- a/deps/v8/test/cctest/test-log-stack-tracer.cc
+++ b/deps/v8/test/cctest/test-log-stack-tracer.cc
@@ -1,4 +1,29 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Tests of profiler-related functions from log.h
@@ -107,11 +132,17 @@ v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction(
Address TraceExtension::GetFP(const v8::Arguments& args) {
- CHECK_EQ(1, args.Length());
- // CodeGenerator::GenerateGetFramePointer pushes EBP / RBP value
- // on stack. In 64-bit mode we can't use Smi operations code because
- // they check that value is within Smi bounds.
+ // Convert frame pointer from encoding as smis in the arguments to a pointer.
+ CHECK_EQ(2, args.Length()); // Ignore second argument on 32-bit platform.
+#if defined(V8_HOST_ARCH_32_BIT)
Address fp = *reinterpret_cast<Address*>(*args[0]);
+#elif defined(V8_HOST_ARCH_64_BIT)
+ int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32;
+ int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]);
+ Address fp = reinterpret_cast<Address>(high_bits | low_bits);
+#else
+#error Host architecture is neither 32-bit nor 64-bit.
+#endif
printf("Trace: %p\n", fp);
return fp;
}
@@ -210,51 +241,60 @@ static Handle<v8::internal::String> NewString(const char* s) {
}
-namespace v8 {
-namespace internal {
-
-class CodeGeneratorPatcher {
- public:
- CodeGeneratorPatcher() {
- CodeGenerator::InlineRuntimeLUT genGetFramePointer =
- {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer", 0};
- // _RandomHeapNumber is just used as a dummy function that has zero
- // arguments, the same as the _GetFramePointer function we actually patch
- // in.
- bool result = CodeGenerator::PatchInlineRuntimeEntry(
- NewString("_RandomHeapNumber"),
- genGetFramePointer, &oldInlineEntry);
- CHECK(result);
- }
-
- ~CodeGeneratorPatcher() {
- CHECK(CodeGenerator::PatchInlineRuntimeEntry(
- NewString("_GetFramePointer"),
- oldInlineEntry, NULL));
- }
+// This C++ function is called as a constructor, to grab the frame pointer
+// from the calling function. When this function runs, the stack contains
+// a C_Entry frame and a Construct frame above the calling function's frame.
+static v8::Handle<Value> construct_call(const v8::Arguments& args) {
+ i::StackFrameIterator frame_iterator;
+ CHECK(frame_iterator.frame()->is_exit());
+ frame_iterator.Advance();
+ CHECK(frame_iterator.frame()->is_construct());
+ frame_iterator.Advance();
+ i::StackFrame* calling_frame = frame_iterator.frame();
+ CHECK(calling_frame->is_java_script());
+
+#if defined(V8_HOST_ARCH_32_BIT)
+ int32_t low_bits = reinterpret_cast<intptr_t>(calling_frame->fp());
+ args.This()->Set(v8_str("low_bits"), v8_num(low_bits >> 1));
+#elif defined(V8_HOST_ARCH_64_BIT)
+ int32_t low_bits = reinterpret_cast<uintptr_t>(calling_frame->fp());
+ int32_t high_bits = reinterpret_cast<uintptr_t>(calling_frame->fp()) >> 32;
+ args.This()->Set(v8_str("low_bits"), v8_num(low_bits));
+ args.This()->Set(v8_str("high_bits"), v8_num(high_bits));
+#else
+#error Host architecture is neither 32-bit nor 64-bit.
+#endif
+ return args.This();
+}
- private:
- CodeGenerator::InlineRuntimeLUT oldInlineEntry;
-};
-} } // namespace v8::internal
+// Use the API to create a JSFunction object that calls the above C++ function.
+void CreateFramePointerGrabberConstructor(const char* constructor_name) {
+ Local<v8::FunctionTemplate> constructor_template =
+ v8::FunctionTemplate::New(construct_call);
+ constructor_template->SetClassName(v8_str("FPGrabber"));
+ Local<Function> fun = constructor_template->GetFunction();
+ env->Global()->Set(v8_str(constructor_name), fun);
+}
// Creates a global function named 'func_name' that calls the tracing
// function 'trace_func_name' with an actual EBP register value,
-// shifted right to be presented as Smi.
+// encoded as one or two Smis.
static void CreateTraceCallerFunction(const char* func_name,
const char* trace_func_name) {
i::EmbeddedVector<char, 256> trace_call_buf;
- i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name);
+ i::OS::SNPrintF(trace_call_buf,
+ "fp = new FPGrabber(); %s(fp.low_bits, fp.high_bits);",
+ trace_func_name);
+
+ // Create the FPGrabber function, which grabs the caller's frame pointer
+ // when called as a constructor.
+ CreateFramePointerGrabberConstructor("FPGrabber");
// Compile the script.
- i::CodeGeneratorPatcher patcher;
- bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
- i::FLAG_allow_natives_syntax = true;
Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
CHECK(!func.is_null());
- i::FLAG_allow_natives_syntax = allow_natives_syntax;
func->shared()->set_name(*NewString(func_name));
#ifdef DEBUG
@@ -273,11 +313,6 @@ static void CreateTraceCallerFunction(const char* func_name,
// StackTracer uses Top::c_entry_fp as a starting point for stack
// walking.
TEST(CFromJSStackTrace) {
- // TODO(711) The hack of replacing the inline runtime function
- // RandomHeapNumber with GetFrameNumber does not work with the way the full
- // compiler generates inline runtime calls.
- i::FLAG_always_full_compiler = false;
-
TickSample sample;
InitTraceEnv(&sample);
@@ -313,11 +348,6 @@ TEST(CFromJSStackTrace) {
// Top::c_entry_fp value. In this case, StackTracer uses passed frame
// pointer value as a starting point for stack walking.
TEST(PureJSStackTrace) {
- // TODO(711) The hack of replacing the inline runtime function
- // RandomHeapNumber with GetFrameNumber does not work with the way the full
- // compiler generates inline runtime calls.
- i::FLAG_always_full_compiler = false;
-
TickSample sample;
InitTraceEnv(&sample);
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index d62b6a5d5..5ddd04416 100755
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -31,7 +31,9 @@
#include "token.h"
#include "scanner.h"
+#include "parser.h"
#include "utils.h"
+#include "execution.h"
#include "cctest.h"
@@ -127,3 +129,113 @@ TEST(KeywordMatcher) {
CHECK_EQ(i::Token::IDENTIFIER, full_stop.token());
}
+
+TEST(ScanHTMLEndComments) {
+ // Regression test. See:
+ // http://code.google.com/p/chromium/issues/detail?id=53548
+ // Tests that --> is correctly interpreted as comment-to-end-of-line if there
+ // is only whitespace before it on the line, even after a multiline-comment
+ // comment. This was not the case if it occurred before the first real token
+ // in the input.
+ const char* tests[] = {
+ // Before first real token.
+ "--> is eol-comment\nvar y = 37;\n",
+ "\n --> is eol-comment\nvar y = 37;\n",
+ "/* precomment */ --> is eol-comment\nvar y = 37;\n",
+ "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
+ // After first real token.
+ "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
+ "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
+ NULL
+ };
+
+ // Parser/Scanner needs a stack limit.
+ int marker;
+ i::StackGuard::SetStackLimit(
+ reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+ for (int i = 0; tests[i]; i++) {
+ v8::ScriptData* data =
+ v8::ScriptData::PreCompile(tests[i], strlen(tests[i]));
+ CHECK(data != NULL && !data->HasError());
+ delete data;
+ }
+}
+
+
+class ScriptResource : public v8::String::ExternalAsciiStringResource {
+ public:
+ ScriptResource(const char* data, size_t length)
+ : data_(data), length_(length) { }
+
+ const char* data() const { return data_; }
+ size_t length() const { return length_; }
+
+ private:
+ const char* data_;
+ size_t length_;
+};
+
+
+TEST(Preparsing) {
+ v8::HandleScope handles;
+ v8::Persistent<v8::Context> context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+ int marker;
+ i::StackGuard::SetStackLimit(
+ reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+ // Source containing functions that might be lazily compiled and all types
+ // of symbols (string, propertyName, regexp).
+ const char* source =
+ "var x = 42;"
+ "function foo(a) { return function nolazy(b) { return a + b; } }"
+ "function bar(a) { if (a) return function lazy(b) { return b; } }"
+ "var z = {'string': 'string literal', bareword: 'propertyName', "
+ " 42: 'number literal', for: 'keyword as propertyName', "
+ " f\\u006fr: 'keyword propertyname with escape'};"
+ "var v = /RegExp Literal/;"
+ "var w = /RegExp Literal\\u0020With Escape/gin;"
+ "var y = { get getter() { return 42; }, "
+ " set setter(v) { this.value = v; }};";
+ int source_length = strlen(source);
+ const char* error_source = "var x = y z;";
+ int error_source_length = strlen(error_source);
+
+ v8::ScriptData* preparse =
+ v8::ScriptData::PreCompile(source, source_length);
+ CHECK(!preparse->HasError());
+ bool lazy_flag = i::FLAG_lazy;
+ {
+ i::FLAG_lazy = true;
+ ScriptResource* resource = new ScriptResource(source, source_length);
+ v8::Local<v8::String> script_source = v8::String::NewExternal(resource);
+ v8::Script::Compile(script_source, NULL, preparse);
+ }
+
+ {
+ i::FLAG_lazy = false;
+
+ ScriptResource* resource = new ScriptResource(source, source_length);
+ v8::Local<v8::String> script_source = v8::String::NewExternal(resource);
+ v8::Script::New(script_source, NULL, preparse, v8::Local<v8::String>());
+ }
+ delete preparse;
+ i::FLAG_lazy = lazy_flag;
+
+ // Syntax error.
+ v8::ScriptData* error_preparse =
+ v8::ScriptData::PreCompile(error_source, error_source_length);
+ CHECK(error_preparse->HasError());
+ i::ScriptDataImpl *pre_impl =
+ reinterpret_cast<i::ScriptDataImpl*>(error_preparse);
+ i::Scanner::Location error_location =
+ pre_impl->MessageLocation();
+ // Error is at "z" in source, location 10..11.
+ CHECK_EQ(10, error_location.beg_pos);
+ CHECK_EQ(11, error_location.end_pos);
+ // Should not crash.
+ const char* message = pre_impl->BuildMessage();
+ i::Vector<const char*> args = pre_impl->BuildArgs();
+ CHECK_GT(strlen(message), 0);
+}
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index ea477de66..b36220284 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -775,4 +775,21 @@ TEST(RecordStackTraceAtStartProfiling) {
CHECK_EQ(0, current->children()->length());
}
+
+TEST(Issue51919) {
+ CpuProfilesCollection collection;
+ i::EmbeddedVector<char*,
+ CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
+ for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
+ i::Vector<char> title = i::Vector<char>::New(16);
+ i::OS::SNPrintF(title, "%d", i);
+ CHECK(collection.StartProfiling(title.start(), i + 1)); // UID must be > 0.
+ titles[i] = title.start();
+ }
+ CHECK(!collection.StartProfiling(
+ "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1));
+ for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
+ i::DeleteArray(titles[i]);
+}
+
#endif // ENABLE_LOGGING_AND_PROFILING
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 3ec25c9f4..20fb2fe6c 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -98,13 +98,6 @@ static int make_code(TypeCode type, int id) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
-static int register_code(int reg) {
- return Debug::k_register_address << kDebugIdShift | reg;
-}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
-
TEST(ExternalReferenceEncoder) {
StatsTable::SetCounterFunction(counter_function);
Heap::Setup(false);
@@ -115,10 +108,6 @@ TEST(ExternalReferenceEncoder) {
Encode(encoder, Runtime::kAbort));
CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty),
Encode(encoder, IC_Utility(IC::kLoadCallbackProperty)));
-#ifdef ENABLE_DEBUGGER_SUPPORT
- CHECK_EQ(make_code(DEBUG_ADDRESS, register_code(3)),
- Encode(encoder, Debug_Address(Debug::k_register_address, 3)));
-#endif // ENABLE_DEBUGGER_SUPPORT
ExternalReference keyed_load_function_prototype =
ExternalReference(&Counters::keyed_load_function_prototype);
CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
@@ -156,10 +145,6 @@ TEST(ExternalReferenceDecoder) {
decoder.Decode(make_code(RUNTIME_FUNCTION, Runtime::kAbort)));
CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
-#ifdef ENABLE_DEBUGGER_SUPPORT
- CHECK_EQ(AddressOf(Debug_Address(Debug::k_register_address, 3)),
- decoder.Decode(make_code(DEBUG_ADDRESS, register_code(3))));
-#endif // ENABLE_DEBUGGER_SUPPORT
ExternalReference keyed_load_function =
ExternalReference(&Counters::keyed_load_function_prototype);
CHECK_EQ(keyed_load_function.address(),
diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc
index bcb185d24..88ef0a204 100644
--- a/deps/v8/test/cctest/test-utils.cc
+++ b/deps/v8/test/cctest/test-utils.cc
@@ -131,3 +131,64 @@ TEST(MemCopy) {
buffer2.Dispose();
buffer1.Dispose();
}
+
+
+TEST(Collector) {
+ Collector<int> collector(8);
+ const int kLoops = 5;
+ const int kSequentialSize = 1000;
+ const int kBlockSize = 7;
+ for (int loop = 0; loop < kLoops; loop++) {
+ Vector<int> block = collector.AddBlock(7, 0xbadcafe);
+ for (int i = 0; i < kSequentialSize; i++) {
+ collector.Add(i);
+ }
+ for (int i = 0; i < kBlockSize - 1; i++) {
+ block[i] = i * 7;
+ }
+ }
+ Vector<int> result = collector.ToVector();
+ CHECK_EQ(kLoops * (kBlockSize + kSequentialSize), result.length());
+ for (int i = 0; i < kLoops; i++) {
+ int offset = i * (kSequentialSize + kBlockSize);
+ for (int j = 0; j < kBlockSize - 1; j++) {
+ CHECK_EQ(j * 7, result[offset + j]);
+ }
+ CHECK_EQ(0xbadcafe, result[offset + kBlockSize - 1]);
+ for (int j = 0; j < kSequentialSize; j++) {
+ CHECK_EQ(j, result[offset + kBlockSize + j]);
+ }
+ }
+ result.Dispose();
+}
+
+
+TEST(SequenceCollector) {
+ SequenceCollector<int> collector(8);
+ const int kLoops = 5000;
+ const int kMaxSequenceSize = 13;
+ int total_length = 0;
+ for (int loop = 0; loop < kLoops; loop++) {
+ int seq_length = loop % kMaxSequenceSize;
+ collector.StartSequence();
+ for (int j = 0; j < seq_length; j++) {
+ collector.Add(j);
+ }
+ Vector<int> sequence = collector.EndSequence();
+ for (int j = 0; j < seq_length; j++) {
+ CHECK_EQ(j, sequence[j]);
+ }
+ total_length += seq_length;
+ }
+ Vector<int> result = collector.ToVector();
+ CHECK_EQ(total_length, result.length());
+ int offset = 0;
+ for (int loop = 0; loop < kLoops; loop++) {
+ int seq_length = loop % kMaxSequenceSize;
+ for (int j = 0; j < seq_length; j++) {
+ CHECK_EQ(j, result[offset]);
+ offset++;
+ }
+ }
+ result.Dispose();
+}
diff --git a/deps/v8/test/cctest/testcfg.py b/deps/v8/test/cctest/testcfg.py
index c2427c8dc..485f2cfdb 100644
--- a/deps/v8/test/cctest/testcfg.py
+++ b/deps/v8/test/cctest/testcfg.py
@@ -31,15 +31,12 @@ from os.path import join, dirname, exists
import platform
import utils
-CCTEST_DEBUG_FLAGS = ['--enable-slow-asserts', '--debug-code', '--verify-heap']
-
class CcTestCase(test.TestCase):
def __init__(self, path, executable, mode, raw_name, dependency, context):
- super(CcTestCase, self).__init__(context, path)
+ super(CcTestCase, self).__init__(context, path, mode)
self.executable = executable
- self.mode = mode
self.raw_name = raw_name
self.dependency = dependency
@@ -54,8 +51,7 @@ class CcTestCase(test.TestCase):
serialization_file += '_' + self.GetName()
serialization_option = '--testing_serialization_file=' + serialization_file
result = [ self.executable, name, serialization_option ]
- if self.mode == 'debug':
- result += CCTEST_DEBUG_FLAGS
+ result += self.context.GetVmFlags(self, self.mode)
return result
def GetCommand(self):