void V8_EXPORT RegisterExtension(Extension* extension);
-/**
- * Ignore
- */
-class V8_EXPORT DeclareExtension {
- public:
- V8_INLINE DeclareExtension(Extension* extension) {
- RegisterExtension(extension);
- }
-};
-
-
// --- Statics ---
V8_INLINE Handle<Primitive> Undefined(Isolate* isolate);
}
+static const char* GCFunctionName() {
+ bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
+ return flag_given ? FLAG_expose_gc_as : "gc";
+}
+
+
+v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
+v8::Extension* Bootstrapper::gc_extension_ = NULL;
+v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
+v8::Extension* Bootstrapper::statistics_extension_ = NULL;
+v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
+
+
void Bootstrapper::InitializeOncePerProcess() {
- FreeBufferExtension::Register();
- GCExtension::Register();
- ExternalizeStringExtension::Register();
- StatisticsExtension::Register();
- TriggerFailureExtension::Register();
+ free_buffer_extension_ = new FreeBufferExtension;
+ v8::RegisterExtension(free_buffer_extension_);
+ gc_extension_ = new GCExtension(GCFunctionName());
+ v8::RegisterExtension(gc_extension_);
+ externalize_string_extension_ = new ExternalizeStringExtension;
+ v8::RegisterExtension(externalize_string_extension_);
+ statistics_extension_ = new StatisticsExtension;
+ v8::RegisterExtension(statistics_extension_);
+ trigger_failure_extension_ = new TriggerFailureExtension;
+ v8::RegisterExtension(trigger_failure_extension_);
+}
+
+
+void Bootstrapper::TearDownExtensions() {
+ delete free_buffer_extension_;
+ delete gc_extension_;
+ delete externalize_string_extension_;
+ delete statistics_extension_;
+ delete trigger_failure_extension_;
}
class Bootstrapper {
public:
static void InitializeOncePerProcess();
+ static void TearDownExtensions();
// Requires: Heap::SetUp has been called.
void Initialize(bool create_heap_objects);
explicit Bootstrapper(Isolate* isolate);
+ static v8::Extension* free_buffer_extension_;
+ static v8::Extension* gc_extension_;
+ static v8::Extension* externalize_string_extension_;
+ static v8::Extension* statistics_extension_;
+ static v8::Extension* trigger_failure_extension_;
+
DISALLOW_COPY_AND_ASSIGN(Bootstrapper);
};
args.GetReturnValue().Set(is_one_byte);
}
-
-void ExternalizeStringExtension::Register() {
- static ExternalizeStringExtension externalize_extension;
- static v8::DeclareExtension declaration(&externalize_extension);
-}
-
} } // namespace v8::internal
v8::Handle<v8::String> name);
static void Externalize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsAscii(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void Register();
+
private:
static const char* const kSource;
};
V8::ArrayBufferAllocator()->Free(contents.Data(), contents.ByteLength());
}
-
-void FreeBufferExtension::Register() {
- static char buffer[100];
- Vector<char> temp_vector(buffer, sizeof(buffer));
- OS::SNPrintF(temp_vector, "native function freeBuffer();");
-
- static FreeBufferExtension buffer_free_extension(buffer);
- static v8::DeclareExtension declaration(&buffer_free_extension);
-}
-
} } // namespace v8::internal
class FreeBufferExtension : public v8::Extension {
public:
- explicit FreeBufferExtension(const char* source)
- : v8::Extension("v8/free-buffer", source) {}
+ FreeBufferExtension()
+ : v8::Extension("v8/free-buffer", "native function freeBuffer();") {}
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate,
v8::Handle<v8::String> name);
static void FreeBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void Register();
};
} } // namespace v8::internal
}
}
-
-void GCExtension::Register() {
- static char buffer[50];
- Vector<char> temp_vector(buffer, sizeof(buffer));
- if (FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0) {
- OS::SNPrintF(temp_vector, "native function %s();", FLAG_expose_gc_as);
- } else {
- OS::SNPrintF(temp_vector, "native function gc();");
- }
-
- static GCExtension gc_extension(buffer);
- static v8::DeclareExtension declaration(&gc_extension);
-}
-
} } // namespace v8::internal
class GCExtension : public v8::Extension {
public:
- explicit GCExtension(const char* source) : v8::Extension("v8/gc", source) {}
+ explicit GCExtension(const char* fun_name)
+ : v8::Extension("v8/gc",
+ BuildSource(buffer_, sizeof(buffer_), fun_name)) {}
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate,
v8::Handle<v8::String> name);
static void GC(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void Register();
+
+ private:
+ static const char* BuildSource(char* buf, size_t size, const char* fun_name) {
+ OS::SNPrintF(Vector<char>(buf, size), "native function %s();", fun_name);
+ return buf;
+ }
+
+ char buffer_[50];
};
} } // namespace v8::internal
args.GetReturnValue().Set(result);
}
-
-void StatisticsExtension::Register() {
- static StatisticsExtension statistics_extension;
- static v8::DeclareExtension declaration(&statistics_extension);
-}
-
} } // namespace v8::internal
v8::Isolate* isolate,
v8::Handle<v8::String> name);
static void GetCounters(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void Register();
+
private:
static const char* const kSource;
};
SLOW_ASSERT(false);
}
-
-void TriggerFailureExtension::Register() {
- static TriggerFailureExtension trigger_failure_extension;
- static v8::DeclareExtension declaration(&trigger_failure_extension);
-}
-
} } // namespace v8::internal
const v8::FunctionCallbackInfo<v8::Value>& args);
static void TriggerSlowAssertFalse(
const v8::FunctionCallbackInfo<v8::Value>& args);
- static void Register();
private:
static const char* const kSource;
isolate->TearDown();
delete isolate;
+ Bootstrapper::TearDownExtensions();
ElementsAccessor::TearDown();
LOperand::TearDownCaches();
ExternalReference::TearDownMathExpData();
#include <v8.h>
#include "cctest.h"
+
+#include "print-extension.h"
+#include "profiler-extension.h"
+#include "trace-extension.h"
#include "debug.h"
enum InitializationState {kUnset, kUnintialized, kInitialized};
CcTestArrayBufferAllocator array_buffer_allocator;
v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
+ i::PrintExtension print_extension;
+ v8::RegisterExtension(&print_extension);
+ i::ProfilerExtension profiler_extension;
+ v8::RegisterExtension(&profiler_extension);
+ i::TraceExtension trace_extension;
+ v8::RegisterExtension(&trace_extension);
+
int tests_run = 0;
bool print_run_count = true;
for (int i = 1; i < argc; i++) {
'gay-fixed.cc',
'gay-precision.cc',
'gay-shortest.cc',
+ 'print-extension.cc',
'profiler-extension.cc',
'test-accessors.cc',
'test-alloc.cc',
'test-version.cc',
'test-weakmaps.cc',
'test-weaksets.cc',
- 'test-weaktypedarrays.cc'
+ 'test-weaktypedarrays.cc',
+ 'trace-extension.cc'
],
'conditions': [
['v8_target_arch=="ia32"', {
static void Test##Name()
#endif
-#define EXTENSION_LIST(V) \
- V(GC_EXTENSION, "v8/gc") \
- V(PRINT_EXTENSION, "v8/print") \
- V(TRACE_EXTENSION, "v8/trace")
+#define EXTENSION_LIST(V) \
+ V(GC_EXTENSION, "v8/gc") \
+ V(PRINT_EXTENSION, "v8/print") \
+ V(PROFILER_EXTENSION, "v8/profiler") \
+ V(TRACE_EXTENSION, "v8/trace")
#define DEFINE_EXTENSION_ID(Name, Ident) Name##_ID,
enum CcTestExtensionIds {
--- /dev/null
+// Copyright 2014 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 "print-extension.h"
+
+namespace v8 {
+namespace internal {
+
+v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
+ v8::Handle<v8::String> str) {
+ return v8::FunctionTemplate::New(isolate, PrintExtension::Print);
+}
+
+
+void PrintExtension::Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ for (int i = 0; i < args.Length(); i++) {
+ if (i != 0) printf(" ");
+ v8::HandleScope scope(args.GetIsolate());
+ v8::String::Utf8Value str(args[i]);
+ if (*str == NULL) return;
+ printf("%s", *str);
+ }
+ printf("\n");
+}
+
+} } // namespace v8::internal
--- /dev/null
+// Copyright 2014 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.
+
+#ifndef V8_TEST_CCTEST_PRINT_EXTENSION_H_
+#define V8_TEST_CCTEST_PRINT_EXTENSION_H_
+
+#include "v8.h"
+
+namespace v8 {
+namespace internal {
+
+class PrintExtension : public v8::Extension {
+ public:
+ PrintExtension() : v8::Extension("v8/print", "native function print();") { }
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
+ v8::Handle<v8::String> name);
+ static void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
+};
+
+} } // namespace v8::internal
+
+#endif
// Tests of profiles generator and utilities.
#include "profiler-extension.h"
+#include "checks.h"
+
+namespace v8 {
+namespace internal {
-#include "cctest.h"
const v8::CpuProfile* ProfilerExtension::last_profile = NULL;
const char* ProfilerExtension::kSource =
: v8::String::Empty(args.GetIsolate()));
}
-
-static ProfilerExtension kProfilerExtension;
-v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension);
+} } // namespace v8::internal
//
// Tests of profiles generator and utilities.
+#ifndef V8_TEST_CCTEST_PROFILER_EXTENSION_H_
+#define V8_TEST_CCTEST_PROFILER_EXTENSION_H_
+
#include "../include/v8-profiler.h"
+namespace v8 {
+namespace internal {
+
class ProfilerExtension : public v8::Extension {
public:
ProfilerExtension() : v8::Extension("v8/profiler", kSource) { }
private:
static const char* kSource;
};
+
+
+} } // namespace v8::internal
+
+#endif
#include "compiler.h"
#include "disasm.h"
-#include "disassembler.h"
-#include "execution.h"
-#include "factory.h"
-#include "platform.h"
#include "cctest.h"
using namespace v8::internal;
-// --- P r i n t E x t e n s i o n ---
-
-class PrintExtension : public v8::Extension {
- public:
- PrintExtension() : v8::Extension("v8/print", kSource) { }
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
- v8::Isolate* isolate,
- v8::Handle<v8::String> name);
- static void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
- private:
- static const char* kSource;
-};
-
-
-const char* PrintExtension::kSource = "native function print();";
-
-
-v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunctionTemplate(
- v8::Isolate* isolate,
- v8::Handle<v8::String> str) {
- return v8::FunctionTemplate::New(isolate, PrintExtension::Print);
-}
-
-
-void PrintExtension::Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
- for (int i = 0; i < args.Length(); i++) {
- if (i != 0) printf(" ");
- v8::HandleScope scope(args.GetIsolate());
- v8::String::Utf8Value str(args[i]);
- if (*str == NULL) return;
- printf("%s", *str);
- }
- printf("\n");
-}
-
-
-static PrintExtension kPrintExtension;
-v8::DeclareExtension kPrintExtensionDeclaration(&kPrintExtension);
-
-
static MaybeObject* GetGlobalProperty(const char* name) {
Isolate* isolate = CcTest::i_isolate();
Handle<String> internalized_name =
static const v8::CpuProfile* RunProfiler(
- LocalContext& env, v8::Handle<v8::Function> function,
+ v8::Handle<v8::Context> env, v8::Handle<v8::Function> function,
v8::Handle<v8::Value> argv[], int argc,
unsigned min_js_samples) {
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Integer::New(env->GetIsolate(), profiling_interval_ms)
};
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 200);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
v8::Integer::New(env->GetIsolate(), repeat_count)
};
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
int32_t repeat_count = 1;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 180);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 180);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode =
int32_t repeat_count = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 200);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode =
int32_t repeat_count = 1;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode =
int32_t repeat_count = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
GetChild(isolate, root, "start");
v8::Integer::New(env->GetIsolate(), duration_ms)
};
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
ScopedVector<v8::Handle<v8::String> > names(3);
v8::Integer::New(env->GetIsolate(), duration_ms)
};
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
{
};
const v8::CpuProfile* profile =
- RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
+ RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
{
// 55 1 bar #16 5
// 54 54 foo #16 6
TEST(JsNativeJsSample) {
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(
env->GetIsolate(), CallJsFunction);
// 51 51 foo #16 6
// 2 2 (program) #0 2
TEST(JsNativeJsRuntimeJsSample) {
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(
env->GetIsolate(), CallJsFunction);
// 54 54 foo #16 7
// 2 2 (program) #0 2
TEST(JsNative1JsNative2JsSample) {
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(
env->GetIsolate(), CallJsFunction);
TEST(FunctionDetails) {
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
- v8::HandleScope handleScope(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::Handle<v8::Script> script_a = v8::Script::Compile(
v8::String::NewFromUtf8(
"stopProfiling();\n"),
v8::String::NewFromUtf8(env->GetIsolate(), "script_b"));
script_b->Run();
- const v8::CpuProfile* profile = ProfilerExtension::last_profile;
+ const v8::CpuProfile* profile = i::ProfilerExtension::last_profile;
const v8::CpuProfileNode* current = profile->GetTopDownRoot();
reinterpret_cast<ProfileNode*>(
const_cast<v8::CpuProfileNode*>(current))->Print(0);
TEST(DontStopOnFinishedProfileDelete) {
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope handleScope(isolate);
v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
}
-
-class HeapProfilerExtension : public v8::Extension {
- public:
- static const char* kName;
- HeapProfilerExtension() : v8::Extension(kName, kSource) { }
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
- v8::Isolate* isolate,
- v8::Handle<v8::String> name);
- static void FindUntrackedObjects(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- private:
- static const char* kSource;
-};
-
-const char* HeapProfilerExtension::kName = "v8/heap-profiler";
-
-
-const char* HeapProfilerExtension::kSource =
- "native function findUntrackedObjects();";
-
-
-v8::Handle<v8::FunctionTemplate>
-HeapProfilerExtension::GetNativeFunctionTemplate(v8::Isolate* isolate,
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::NewFromUtf8(isolate, "findUntrackedObjects"))) {
- return v8::FunctionTemplate::New(
- isolate,
- HeapProfilerExtension::FindUntrackedObjects);
- } else {
- CHECK(false);
- return v8::Handle<v8::FunctionTemplate>();
- }
-}
-
-
-void HeapProfilerExtension::FindUntrackedObjects(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- i::HeapProfiler* heap_profiler =
- reinterpret_cast<i::HeapProfiler*>(args.GetIsolate()->GetHeapProfiler());
- int untracked_objects =
- heap_profiler->heap_object_map()->FindUntrackedObjects();
- args.GetReturnValue().Set(untracked_objects);
- CHECK_EQ(0, untracked_objects);
-}
-
-
-static HeapProfilerExtension kHeapProfilerExtension;
-v8::DeclareExtension kHeapProfilerExtensionDeclaration(
- &kHeapProfilerExtension);
-
-
static const v8::HeapGraphNode* GetNodeByPath(const v8::HeapSnapshot* snapshot,
const char* path[],
int depth) {
#include "isolate.h"
#include "log.h"
#include "sampler.h"
+#include "trace-extension.h"
#include "vm-state-inl.h"
using v8::Function;
using v8::internal::Handle;
using v8::internal::Isolate;
using v8::internal::JSFunction;
-using v8::internal::RegisterState;
using v8::internal::TickSample;
-static struct {
- TickSample* sample;
-} trace_env = { NULL };
-
-
-static void InitTraceEnv(TickSample* sample) {
- trace_env.sample = sample;
-}
-
-
-static void DoTrace(Address fp) {
- RegisterState regs;
- regs.fp = fp;
- // sp is only used to define stack high bound
- regs.sp =
- reinterpret_cast<Address>(trace_env.sample) - 10240;
- trace_env.sample->Init(CcTest::i_isolate(), regs);
-}
-
-
-// Hide c_entry_fp to emulate situation when sampling is done while
-// pure JS code is being executed
-static void DoTraceHideCEntryFPAddress(Address fp) {
- v8::internal::Address saved_c_frame_fp =
- *(CcTest::i_isolate()->c_entry_fp_address());
- CHECK(saved_c_frame_fp);
- *(CcTest::i_isolate()->c_entry_fp_address()) = 0;
- DoTrace(fp);
- *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp;
-}
-
-
-// --- T r a c e E x t e n s i o n ---
-
-class TraceExtension : public v8::Extension {
- public:
- TraceExtension() : v8::Extension("v8/trace", kSource) { }
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
- v8::Isolate* isolate,
- v8::Handle<String> name);
- static void Trace(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void JSEntrySP(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void JSEntrySPLevel2(const v8::FunctionCallbackInfo<v8::Value>& args);
- private:
- static Address GetFP(const v8::FunctionCallbackInfo<v8::Value>& args);
- static const char* kSource;
-};
-
-
-const char* TraceExtension::kSource =
- "native function trace();"
- "native function js_trace();"
- "native function js_entry_sp();"
- "native function js_entry_sp_level2();";
-
-v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate(
- v8::Isolate* isolate, v8::Handle<String> name) {
- if (name->Equals(String::NewFromUtf8(isolate, "trace"))) {
- return v8::FunctionTemplate::New(isolate, TraceExtension::Trace);
- } else if (name->Equals(
- String::NewFromUtf8(isolate, "js_trace"))) {
- return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace);
- } else if (name->Equals(String::NewFromUtf8(isolate, "js_entry_sp"))) {
- return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP);
- } else if (name->Equals(String::NewFromUtf8(isolate, "js_entry_sp_level2"))) {
- return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2);
- } else {
- CHECK(false);
- return v8::Handle<v8::FunctionTemplate>();
- }
-}
-
-
-Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) {
- // 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;
-}
-
-
-void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) {
- DoTrace(GetFP(args));
-}
-
-
-void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) {
- DoTraceHideCEntryFPAddress(GetFP(args));
-}
-
-
-static Address GetJsEntrySp() {
- CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top());
- return CcTest::i_isolate()->js_entry_sp();
-}
-
-
-void TraceExtension::JSEntrySP(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_NE(0, GetJsEntrySp());
-}
-
-
-void TraceExtension::JSEntrySPLevel2(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::HandleScope scope(args.GetIsolate());
- const Address js_entry_sp = GetJsEntrySp();
- CHECK_NE(0, js_entry_sp);
- CompileRun("js_entry_sp();");
- CHECK_EQ(js_entry_sp, GetJsEntrySp());
-}
-
-
-static TraceExtension kTraceExtension;
-v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);
-
-
static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) {
i::Code* code = function->code();
return code->contains(addr);
i::FLAG_use_inlining = false;
TickSample sample;
- InitTraceEnv(&sample);
+ i::TraceExtension::InitTraceEnv(&sample);
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
// TickSample::Trace
CHECK(sample.has_external_callback);
- CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback);
+ CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace), sample.external_callback);
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
int base = 0;
i::FLAG_use_inlining = false;
TickSample sample;
- InitTraceEnv(&sample);
+ i::TraceExtension::InitTraceEnv(&sample);
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
//
CHECK(sample.has_external_callback);
- CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace), sample.external_callback);
+ CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace), sample.external_callback);
// Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
int base = 0;
#else
#error Unexpected platform.
#endif
- DoTrace(fp);
+ i::TraceExtension::DoTrace(fp);
}
// get any meaningful info here.
TEST(PureCStackTrace) {
TickSample sample;
- InitTraceEnv(&sample);
+ i::TraceExtension::InitTraceEnv(&sample);
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
v8::Context::Scope context_scope(context);
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
v8::Context::Scope context_scope(context);
- CHECK_EQ(0, GetJsEntrySp());
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp());
CompileRun("a = 1; b = a + 1;");
- CHECK_EQ(0, GetJsEntrySp());
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp());
CompileRun("js_entry_sp();");
- CHECK_EQ(0, GetJsEntrySp());
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp());
CompileRun("js_entry_sp_level2();");
- CHECK_EQ(0, GetJsEntrySp());
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp());
}
// don't appear in the stack trace.
i::FLAG_use_inlining = false;
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- v8::Local<v8::Context> context = v8::Context::New(isolate, &config);
- context->Enter();
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler();
CHECK_EQ(0, profiler->GetProfilesCount());
// don't appear in the stack trace.
i::FLAG_use_inlining = false;
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
- v8::HandleScope hs(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
"stopProfiling();\n"));
script_b->Run();
CHECK_EQ(1, iprofiler->GetProfilesCount());
- const v8::CpuProfile* profile = ProfilerExtension::last_profile;
+ const v8::CpuProfile* profile = i::ProfilerExtension::last_profile;
const v8::CpuProfileNode* current = profile->GetTopDownRoot();
reinterpret_cast<ProfileNode*>(
const_cast<v8::CpuProfileNode*>(current))->Print(0);
TEST(BailoutReason) {
- const char* extensions[] = { "v8/profiler" };
- v8::ExtensionConfiguration config(1, extensions);
- LocalContext env(&config);
- v8::HandleScope hs(env->GetIsolate());
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Context::Scope context_scope(env);
v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
"stopProfiling();"));
script->Run();
CHECK_EQ(1, iprofiler->GetProfilesCount());
- const v8::CpuProfile* profile = ProfilerExtension::last_profile;
+ const v8::CpuProfile* profile = i::ProfilerExtension::last_profile;
CHECK(profile);
const v8::CpuProfileNode* current = profile->GetTopDownRoot();
reinterpret_cast<ProfileNode*>(
--- /dev/null
+// Copyright 2014 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 "trace-extension.h"
+
+#include "cctest.h"
+#include "sampler.h"
+
+namespace v8 {
+namespace internal {
+
+const char* TraceExtension::kSource =
+ "native function trace();"
+ "native function js_trace();"
+ "native function js_entry_sp();"
+ "native function js_entry_sp_level2();";
+
+
+v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate(
+ v8::Isolate* isolate, v8::Handle<v8::String> name) {
+ if (name->Equals(v8::String::NewFromUtf8(isolate, "trace"))) {
+ return v8::FunctionTemplate::New(isolate, TraceExtension::Trace);
+ } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_trace"))) {
+ return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace);
+ } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_entry_sp"))) {
+ return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP);
+ } else if (name->Equals(v8::String::NewFromUtf8(isolate,
+ "js_entry_sp_level2"))) {
+ return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2);
+ } else {
+ CHECK(false);
+ return v8::Handle<v8::FunctionTemplate>();
+ }
+}
+
+
+Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ // 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;
+}
+
+
+static struct {
+ TickSample* sample;
+} trace_env = { NULL };
+
+
+void TraceExtension::InitTraceEnv(TickSample* sample) {
+ trace_env.sample = sample;
+}
+
+
+void TraceExtension::DoTrace(Address fp) {
+ RegisterState regs;
+ regs.fp = fp;
+ // sp is only used to define stack high bound
+ regs.sp =
+ reinterpret_cast<Address>(trace_env.sample) - 10240;
+ trace_env.sample->Init(CcTest::i_isolate(), regs);
+}
+
+
+void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ DoTrace(GetFP(args));
+}
+
+
+// Hide c_entry_fp to emulate situation when sampling is done while
+// pure JS code is being executed
+static void DoTraceHideCEntryFPAddress(Address fp) {
+ v8::internal::Address saved_c_frame_fp =
+ *(CcTest::i_isolate()->c_entry_fp_address());
+ CHECK(saved_c_frame_fp);
+ *(CcTest::i_isolate()->c_entry_fp_address()) = 0;
+ i::TraceExtension::DoTrace(fp);
+ *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp;
+}
+
+
+void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ DoTraceHideCEntryFPAddress(GetFP(args));
+}
+
+
+Address TraceExtension::GetJsEntrySp() {
+ CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top());
+ return CcTest::i_isolate()->js_entry_sp();
+}
+
+
+void TraceExtension::JSEntrySP(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ CHECK_NE(0, GetJsEntrySp());
+}
+
+
+void TraceExtension::JSEntrySPLevel2(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::HandleScope scope(args.GetIsolate());
+ const Address js_entry_sp = GetJsEntrySp();
+ CHECK_NE(0, js_entry_sp);
+ CompileRun("js_entry_sp();");
+ CHECK_EQ(js_entry_sp, GetJsEntrySp());
+}
+
+
+} } // namespace v8::internal
--- /dev/null
+// Copyright 2014 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.
+
+#ifndef V8_TEST_CCTEST_TRACE_EXTENSION_H_
+#define V8_TEST_CCTEST_TRACE_EXTENSION_H_
+
+#include "v8.h"
+
+namespace v8 {
+namespace internal {
+
+class TraceExtension : public v8::Extension {
+ public:
+ TraceExtension() : v8::Extension("v8/trace", kSource) { }
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
+ v8::Handle<v8::String> name);
+ static void Trace(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void JSEntrySP(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void JSEntrySPLevel2(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static Address GetJsEntrySp();
+ static void InitTraceEnv(TickSample* sample);
+ static void DoTrace(Address fp);
+ private:
+ static Address GetFP(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static const char* kSource;
+};
+
+} } // namespace v8::internal
+
+#endif