summaryrefslogtreecommitdiffstats
path: root/V8Binding/v8/test/cctest
diff options
context:
space:
mode:
Diffstat (limited to 'V8Binding/v8/test/cctest')
-rw-r--r--V8Binding/v8/test/cctest/SConscript4
-rw-r--r--V8Binding/v8/test/cctest/cctest.status6
-rw-r--r--V8Binding/v8/test/cctest/test-api.cc190
-rw-r--r--V8Binding/v8/test/cctest/test-ast.cc4
-rw-r--r--V8Binding/v8/test/cctest/test-debug.cc68
-rw-r--r--V8Binding/v8/test/cctest/test-heap.cc2
-rw-r--r--V8Binding/v8/test/cctest/test-log-stack-tracer.cc (renamed from V8Binding/v8/test/cctest/test-log-ia32.cc)12
-rw-r--r--V8Binding/v8/test/cctest/test-log.cc44
-rw-r--r--V8Binding/v8/test/cctest/test-regexp.cc2
9 files changed, 312 insertions, 20 deletions
diff --git a/V8Binding/v8/test/cctest/SConscript b/V8Binding/v8/test/cctest/SConscript
index 7506d29..112ecd6 100644
--- a/V8Binding/v8/test/cctest/SConscript
+++ b/V8Binding/v8/test/cctest/SConscript
@@ -63,9 +63,9 @@ SOURCES = {
'arch:ia32': [
'test-assembler-ia32.cc',
'test-disasm-ia32.cc',
- 'test-log-ia32.cc'
+ 'test-log-stack-tracer.cc'
],
- 'arch:x64': ['test-assembler-x64.cc'],
+ 'arch:x64': ['test-assembler-x64.cc', 'test-log-stack-tracer.cc'],
'os:linux': ['test-platform-linux.cc'],
'os:macos': ['test-platform-macos.cc'],
'os:nullos': ['test-platform-nullos.cc'],
diff --git a/V8Binding/v8/test/cctest/cctest.status b/V8Binding/v8/test/cctest/cctest.status
index b234ca3..9abe408 100644
--- a/V8Binding/v8/test/cctest/cctest.status
+++ b/V8Binding/v8/test/cctest/cctest.status
@@ -63,7 +63,6 @@ test-api/TryCatchInTryFinally: FAIL
[ $arch == x64 ]
-test-regexp/Graph: PASS || CRASH || FAIL
test-decls/Present: CRASH || FAIL
test-decls/Unknown: CRASH || FAIL
test-decls/Appearing: CRASH || FAIL
@@ -113,10 +112,9 @@ test-debug/RecursiveBreakpoints: CRASH || FAIL
test-debug/DebuggerUnload: CRASH || FAIL
test-debug/DebuggerHostDispatch: CRASH || FAIL
test-debug/DebugBreakInMessageHandler: CRASH || FAIL
-test-api/HugeConsStringOutOfMemory: CRASH || FAIL
-test-api/OutOfMemory: CRASH || FAIL
-test-api/OutOfMemoryNested: CRASH || FAIL
+test-debug/NoDebugBreakInAfterCompileMessageHandler: CRASH || FAIL
test-api/Threading: CRASH || FAIL
+test-api/Threading2: PASS || TIMEOUT
test-api/TryCatchSourceInfo: CRASH || FAIL
test-api/RegExpInterruption: PASS || TIMEOUT
test-api/RegExpStringModification: PASS || TIMEOUT
diff --git a/V8Binding/v8/test/cctest/test-api.cc b/V8Binding/v8/test/cctest/test-api.cc
index 806e711..35ac031 100644
--- a/V8Binding/v8/test/cctest/test-api.cc
+++ b/V8Binding/v8/test/cctest/test-api.cc
@@ -633,6 +633,53 @@ THREADED_TEST(FunctionTemplate) {
}
+THREADED_TEST(FindInstanceInPrototypeChain) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New();
+ derived->Inherit(base);
+
+ Local<v8::Function> base_function = base->GetFunction();
+ Local<v8::Function> derived_function = derived->GetFunction();
+ Local<v8::Function> other_function = other->GetFunction();
+
+ Local<v8::Object> base_instance = base_function->NewInstance();
+ Local<v8::Object> derived_instance = derived_function->NewInstance();
+ Local<v8::Object> derived_instance2 = derived_function->NewInstance();
+ Local<v8::Object> other_instance = other_function->NewInstance();
+ derived_instance2->Set(v8_str("__proto__"), derived_instance);
+ other_instance->Set(v8_str("__proto__"), derived_instance2);
+
+ // base_instance is only an instance of base.
+ CHECK_EQ(base_instance,
+ base_instance->FindInstanceInPrototypeChain(base));
+ CHECK(base_instance->FindInstanceInPrototypeChain(derived).IsEmpty());
+ CHECK(base_instance->FindInstanceInPrototypeChain(other).IsEmpty());
+
+ // derived_instance is an instance of base and derived.
+ CHECK_EQ(derived_instance,
+ derived_instance->FindInstanceInPrototypeChain(base));
+ CHECK_EQ(derived_instance,
+ derived_instance->FindInstanceInPrototypeChain(derived));
+ CHECK(derived_instance->FindInstanceInPrototypeChain(other).IsEmpty());
+
+ // other_instance is an instance of other and its immediate
+ // prototype derived_instance2 is an instance of base and derived.
+ // Note, derived_instance is an instance of base and derived too,
+ // but it comes after derived_instance2 in the prototype chain of
+ // other_instance.
+ CHECK_EQ(derived_instance2,
+ other_instance->FindInstanceInPrototypeChain(base));
+ CHECK_EQ(derived_instance2,
+ other_instance->FindInstanceInPrototypeChain(derived));
+ CHECK_EQ(other_instance,
+ other_instance->FindInstanceInPrototypeChain(other));
+}
+
+
static v8::Handle<Value> handle_property(Local<String> name,
const AccessorInfo&) {
ApiTestFuzzer::Fuzz();
@@ -7548,3 +7595,146 @@ THREADED_TEST(Regress16276) {
context->DetachGlobal();
CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value());
}
+
+
+THREADED_TEST(PixelArray) {
+ v8::HandleScope scope;
+ LocalContext context;
+ const int kElementCount = 40;
+ uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
+ i::Handle<i::PixelArray> pixels = i::Factory::NewPixelArray(kElementCount,
+ pixel_data);
+ i::Heap::CollectAllGarbage(); // Force GC to trigger verification.
+ for (int i = 0; i < kElementCount; i++) {
+ pixels->set(i, i);
+ }
+ i::Heap::CollectAllGarbage(); // Force GC to trigger verification.
+ for (int i = 0; i < kElementCount; i++) {
+ CHECK_EQ(i, pixels->get(i));
+ CHECK_EQ(i, pixel_data[i]);
+ }
+
+ v8::Handle<v8::Object> obj = v8::Object::New();
+ i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
+ // 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))->value());
+ obj->Set(v8_str("field"), v8::Int32::New(1503));
+ context->Global()->Set(v8_str("pixels"), obj);
+ v8::Handle<v8::Value> result = CompileRun("pixels.field");
+ CHECK_EQ(1503, result->Int32Value());
+ result = CompileRun("pixels[1]");
+ CHECK_EQ(1, result->Int32Value());
+ result = CompileRun("var sum = 0;"
+ "for (var i = 0; i < 8; i++) {"
+ " sum += pixels[i];"
+ "}"
+ "sum;");
+ CHECK_EQ(28, result->Int32Value());
+
+ i::Handle<i::Smi> value(i::Smi::FromInt(2));
+ i::SetElement(jsobj, 1, value);
+ CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1))->value());
+ *value.location() = i::Smi::FromInt(256);
+ i::SetElement(jsobj, 1, value);
+ CHECK_EQ(255, i::Smi::cast(jsobj->GetElement(1))->value());
+ *value.location() = i::Smi::FromInt(-1);
+ i::SetElement(jsobj, 1, value);
+ CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1))->value());
+
+ 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))->value());
+ CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1))->value());
+ CHECK_EQ(21, i::Smi::cast(jsobj->GetElement(2))->value());
+ CHECK_EQ(86, i::Smi::cast(jsobj->GetElement(3))->value());
+ CHECK_EQ(151, i::Smi::cast(jsobj->GetElement(4))->value());
+ CHECK_EQ(216, i::Smi::cast(jsobj->GetElement(5))->value());
+ CHECK_EQ(255, i::Smi::cast(jsobj->GetElement(6))->value());
+ CHECK_EQ(255, i::Smi::cast(jsobj->GetElement(7))->value());
+ result = CompileRun("var sum = 0;"
+ "for (var i = 0; i < 8; i++) {"
+ " sum += pixels[i];"
+ "}"
+ "sum;");
+ CHECK_EQ(984, result->Int32Value());
+
+ result = CompileRun("for (var i = 0; i < 8; i++) {"
+ " pixels[i] = (i * 1.1);"
+ "}"
+ "pixels[1] + pixels[6];");
+ CHECK_EQ(8, result->Int32Value());
+ CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0))->value());
+ CHECK_EQ(1, i::Smi::cast(jsobj->GetElement(1))->value());
+ CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(2))->value());
+ CHECK_EQ(3, i::Smi::cast(jsobj->GetElement(3))->value());
+ CHECK_EQ(4, i::Smi::cast(jsobj->GetElement(4))->value());
+ CHECK_EQ(6, i::Smi::cast(jsobj->GetElement(5))->value());
+ CHECK_EQ(7, i::Smi::cast(jsobj->GetElement(6))->value());
+ CHECK_EQ(8, i::Smi::cast(jsobj->GetElement(7))->value());
+
+ 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))->value());
+
+ 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))->value());
+
+ 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))->value());
+
+ 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))->value());
+
+ 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))->value());
+
+ result = CompileRun("pixels[3] = 33;"
+ "delete pixels[3];"
+ "pixels[3];");
+ CHECK_EQ(33, result->Int32Value());
+
+ result = CompileRun("pixels[0] = 10; pixels[1] = 11;"
+ "pixels[2] = 12; pixels[3] = 13;"
+ "pixels.__defineGetter__('2',"
+ "function() { return 120; });"
+ "pixels[2];");
+ CHECK_EQ(12, result->Int32Value());
+
+ result = CompileRun("var js_array = new Array(40);"
+ "js_array[0] = 77;"
+ "js_array;");
+ CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value());
+
+ result = CompileRun("pixels[1] = 23;"
+ "pixels.__proto__ = [];"
+ "js_array.__proto__ = pixels;"
+ "js_array.concat(pixels);");
+ CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value());
+ CHECK_EQ(23, v8::Object::Cast(*result)->Get(v8_str("1"))->Int32Value());
+
+ free(pixel_data);
+}
diff --git a/V8Binding/v8/test/cctest/test-ast.cc b/V8Binding/v8/test/cctest/test-ast.cc
index 2054348..9931f56 100644
--- a/V8Binding/v8/test/cctest/test-ast.cc
+++ b/V8Binding/v8/test/cctest/test-ast.cc
@@ -35,11 +35,11 @@
using namespace v8::internal;
TEST(List) {
- List<Node*>* list = new List<Node*>(0);
+ List<AstNode*>* list = new List<AstNode*>(0);
CHECK_EQ(0, list->length());
ZoneScope zone_scope(DELETE_ON_EXIT);
- Node* node = new EmptyStatement();
+ AstNode* node = new EmptyStatement();
list->Add(node);
CHECK_EQ(1, list->length());
CHECK_EQ(node, list->at(0));
diff --git a/V8Binding/v8/test/cctest/test-debug.cc b/V8Binding/v8/test/cctest/test-debug.cc
index fddd000..9e2c38d 100644
--- a/V8Binding/v8/test/cctest/test-debug.cc
+++ b/V8Binding/v8/test/cctest/test-debug.cc
@@ -4875,7 +4875,7 @@ TEST(DebugBreakInMessageHandler) {
v8::Debug::SetMessageHandler2(DebugBreakMessageHandler);
// Test functions.
- const char* script = "function f() { debugger; } function g() { }";
+ const char* script = "function f() { debugger; g(); } function g() { }";
CompileRun(script);
v8::Local<v8::Function> f =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
@@ -4954,8 +4954,10 @@ TEST(RegExpDebugBreak) {
v8::Debug::DebugBreak();
result = f->Call(env->Global(), argc, argv);
- CHECK_EQ(20, break_point_hit_count);
- CHECK_EQ("exec", last_function_hit);
+ // Check that there was only one break event. Matching RegExp should not
+ // cause Break events.
+ CHECK_EQ(1, break_point_hit_count);
+ CHECK_EQ("f", last_function_hit);
}
#endif // V8_NATIVE_REGEXP
@@ -5295,3 +5297,63 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
ClearBreakPointFromJS(sbp2);
v8::Debug::SetMessageHandler2(NULL);
}
+
+
+static void BreakMessageHandler(const v8::Debug::Message& message) {
+ if (message.IsEvent() && message.GetEvent() == v8::Break) {
+ // Count the number of breaks.
+ break_point_hit_count++;
+
+ v8::HandleScope scope;
+ v8::Handle<v8::String> json = message.GetJSON();
+
+ SendContinueCommand();
+ } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
+ v8::HandleScope scope;
+
+ bool is_debug_break = i::StackGuard::IsDebugBreak();
+ // Force DebugBreak flag while serializer is working.
+ i::StackGuard::DebugBreak();
+
+ // Force serialization to trigger some internal JS execution.
+ v8::Handle<v8::String> json = message.GetJSON();
+
+ // Restore previous state.
+ if (is_debug_break) {
+ i::StackGuard::DebugBreak();
+ } else {
+ i::StackGuard::Continue(i::DEBUGBREAK);
+ }
+ }
+}
+
+
+// Test that if DebugBreak is forced it is ignored when code from
+// debug-delay.js is executed.
+TEST(NoDebugBreakInAfterCompileMessageHandler) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+
+ // Register a debug event listener which sets the break flag and counts.
+ v8::Debug::SetMessageHandler2(BreakMessageHandler);
+
+ // Set the debug break flag.
+ v8::Debug::DebugBreak();
+
+ // Create a function for testing stepping.
+ const char* src = "function f() { eval('var x = 10;'); } ";
+ v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
+
+ // There should be only one break event.
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Set the debug break flag again.
+ v8::Debug::DebugBreak();
+ f->Call(env->Global(), 0, NULL);
+ // There should be one more break event when the script is evaluated in 'f'.
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Get rid of the debug message handler.
+ v8::Debug::SetMessageHandler2(NULL);
+ CheckDebuggerUnloaded();
+}
diff --git a/V8Binding/v8/test/cctest/test-heap.cc b/V8Binding/v8/test/cctest/test-heap.cc
index 5163ff9..6b5907c 100644
--- a/V8Binding/v8/test/cctest/test-heap.cc
+++ b/V8Binding/v8/test/cctest/test-heap.cc
@@ -653,7 +653,7 @@ TEST(JSArray) {
uint32_t int_length = 0;
CHECK(Array::IndexFromObject(length, &int_length));
CHECK_EQ(length, array->length());
- CHECK(!array->HasFastElements()); // Must be in slow mode.
+ CHECK(array->HasDictionaryElements()); // Must be in slow mode.
// array[length] = name.
array->SetElement(int_length, name);
diff --git a/V8Binding/v8/test/cctest/test-log-ia32.cc b/V8Binding/v8/test/cctest/test-log-stack-tracer.cc
index a40a800..1ef0a93 100644
--- a/V8Binding/v8/test/cctest/test-log-ia32.cc
+++ b/V8Binding/v8/test/cctest/test-log-stack-tracer.cc
@@ -50,7 +50,7 @@ static void DoTrace(Address fp) {
trace_env.sample->fp = reinterpret_cast<uintptr_t>(fp);
// sp is only used to define stack high bound
trace_env.sample->sp =
- reinterpret_cast<unsigned int>(trace_env.sample) - 10240;
+ reinterpret_cast<uintptr_t>(trace_env.sample) - 10240;
StackTracer::Trace(trace_env.sample);
}
@@ -130,7 +130,10 @@ v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction(
Address TraceExtension::GetFP(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
- Address fp = reinterpret_cast<Address>(args[0]->Int32Value() << 2);
+ // 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.
+ Address fp = *reinterpret_cast<Address*>(*args[0]);
printf("Trace: %p\n", fp);
return fp;
}
@@ -330,8 +333,11 @@ static void CFuncDoTrace() {
Address fp;
#ifdef __GNUC__
fp = reinterpret_cast<Address>(__builtin_frame_address(0));
-#elif defined _MSC_VER
+#elif defined _MSC_VER && defined V8_TARGET_ARCH_IA32
__asm mov [fp], ebp // NOLINT
+#elif defined _MSC_VER && defined V8_TARGET_ARCH_X64
+ // FIXME: I haven't really tried to compile it.
+ __asm movq [fp], rbp // NOLINT
#endif
DoTrace(fp);
}
diff --git a/V8Binding/v8/test/cctest/test-log.cc b/V8Binding/v8/test/cctest/test-log.cc
index f3f7efc..df58234 100644
--- a/V8Binding/v8/test/cctest/test-log.cc
+++ b/V8Binding/v8/test/cctest/test-log.cc
@@ -4,8 +4,12 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
-#include "v8.h"
+#ifdef __linux__
+#include <signal.h>
+#include <unistd.h>
+#endif
+#include "v8.h"
#include "log.h"
#include "cctest.h"
@@ -144,8 +148,25 @@ class LoggerTestHelper : public AllStatic {
using v8::internal::LoggerTestHelper;
+// Under Linux, we need to check if signals were delivered to avoid false
+// positives. Under other platforms profiling is done via a high-priority
+// thread, so this case never happen.
+static bool was_sigprof_received = true;
+#ifdef __linux__
+
+struct sigaction old_sigprof_handler;
+
+static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) {
+ if (signal != SIGPROF) return;
+ was_sigprof_received = true;
+ old_sigprof_handler.sa_sigaction(signal, info, context);
+}
+
+#endif // __linux__
+
+
static int CheckThatProfilerWorks(int log_pos) {
- Logger::ResumeProfiler();
+ Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU);
CHECK(LoggerTestHelper::IsSamplerActive());
// Verify that the current map of compiled functions has been logged.
@@ -160,6 +181,18 @@ static int CheckThatProfilerWorks(int log_pos) {
const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/
CHECK_NE(NULL, strstr(buffer.start(), code_creation));
+#ifdef __linux__
+ // Intercept SIGPROF handler to make sure that the test process
+ // had received it. Under load, system can defer it causing test failure.
+ // It is important to execute this after 'ResumeProfiler'.
+ was_sigprof_received = false;
+ struct sigaction sa;
+ sa.sa_sigaction = SigProfSignalHandler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ CHECK_EQ(0, sigaction(SIGPROF, &sa, &old_sigprof_handler));
+#endif // __linux__
+
// Force compiler to generate new code by parametrizing source.
EmbeddedVector<char, 100> script_src;
i::OS::SNPrintF(script_src,
@@ -170,9 +203,11 @@ static int CheckThatProfilerWorks(int log_pos) {
const double end_time = i::OS::TimeCurrentMillis() + 200;
while (i::OS::TimeCurrentMillis() < end_time) {
CompileAndRunScript(script_src.start());
+ // Yield CPU to give Profiler thread a chance to process ticks.
+ i::OS::Sleep(1);
}
- Logger::PauseProfiler();
+ Logger::PauseProfiler(v8::PROFILER_MODULE_CPU);
CHECK(!LoggerTestHelper::IsSamplerActive());
// Wait 50 msecs to allow Profiler thread to process the last
@@ -189,7 +224,8 @@ static int CheckThatProfilerWorks(int log_pos) {
buffer[log_size] = '\0';
const char* tick = "\ntick,";
CHECK_NE(NULL, strstr(buffer.start(), code_creation));
- CHECK_NE(NULL, strstr(buffer.start(), tick));
+ const bool ticks_found = strstr(buffer.start(), tick) != NULL;
+ CHECK_EQ(was_sigprof_received, ticks_found);
return log_pos;
}
diff --git a/V8Binding/v8/test/cctest/test-regexp.cc b/V8Binding/v8/test/cctest/test-regexp.cc
index 33a83c7..8d8326c 100644
--- a/V8Binding/v8/test/cctest/test-regexp.cc
+++ b/V8Binding/v8/test/cctest/test-regexp.cc
@@ -35,7 +35,7 @@
#include "zone-inl.h"
#include "parser.h"
#include "ast.h"
-#include "jsregexp-inl.h"
+#include "jsregexp.h"
#include "regexp-macro-assembler.h"
#include "regexp-macro-assembler-irregexp.h"
#ifdef V8_TARGET_ARCH_ARM