Various extension-related cleanup and simplifications.

Removes the embarrassing "static"s, shuffles some code around, doing various cleanups on the way.

R=dcarney@chromium.org

Review URL: https://codereview.chromium.org/130213009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18659 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7cee5294
......@@ -3718,17 +3718,6 @@ class V8_EXPORT Extension { // NOLINT
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);
......
......@@ -101,12 +101,39 @@ void Bootstrapper::Initialize(bool create_heap_objects) {
}
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_;
}
......
......@@ -90,6 +90,7 @@ class SourceCodeCache BASE_EMBEDDED {
class Bootstrapper {
public:
static void InitializeOncePerProcess();
static void TearDownExtensions();
// Requires: Heap::SetUp has been called.
void Initialize(bool create_heap_objects);
......@@ -146,6 +147,12 @@ class Bootstrapper {
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);
};
......
......@@ -145,10 +145,4 @@ void ExternalizeStringExtension::IsAscii(
args.GetReturnValue().Set(is_one_byte);
}
void ExternalizeStringExtension::Register() {
static ExternalizeStringExtension externalize_extension;
static v8::DeclareExtension declaration(&externalize_extension);
}
} } // namespace v8::internal
......@@ -41,7 +41,7 @@ class ExternalizeStringExtension : public v8::Extension {
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;
};
......
......@@ -47,14 +47,4 @@ void FreeBufferExtension::FreeBuffer(
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
......@@ -35,13 +35,12 @@ namespace 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
......
......@@ -50,18 +50,4 @@ void GCExtension::GC(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
}
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
......@@ -35,12 +35,21 @@ namespace 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
......
......@@ -170,10 +170,4 @@ void StatisticsExtension::GetCounters(
args.GetReturnValue().Set(result);
}
void StatisticsExtension::Register() {
static StatisticsExtension statistics_extension;
static v8::DeclareExtension declaration(&statistics_extension);
}
} } // namespace v8::internal
......@@ -40,7 +40,7 @@ class StatisticsExtension : public v8::Extension {
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;
};
......
......@@ -76,10 +76,4 @@ void TriggerFailureExtension::TriggerSlowAssertFalse(
SLOW_ASSERT(false);
}
void TriggerFailureExtension::Register() {
static TriggerFailureExtension trigger_failure_extension;
static v8::DeclareExtension declaration(&trigger_failure_extension);
}
} } // namespace v8::internal
......@@ -45,7 +45,6 @@ class TriggerFailureExtension : public v8::Extension {
const v8::FunctionCallbackInfo<v8::Value>& args);
static void TriggerSlowAssertFalse(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void Register();
private:
static const char* const kSource;
......
......@@ -99,6 +99,7 @@ void V8::TearDown() {
isolate->TearDown();
delete isolate;
Bootstrapper::TearDownExtensions();
ElementsAccessor::TearDown();
LOperand::TearDownCaches();
ExternalReference::TearDownMathExpData();
......
......@@ -27,6 +27,10 @@
#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};
......@@ -141,6 +145,13 @@ int main(int argc, char* argv[]) {
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++) {
......
......@@ -47,6 +47,7 @@
'gay-fixed.cc',
'gay-precision.cc',
'gay-shortest.cc',
'print-extension.cc',
'profiler-extension.cc',
'test-accessors.cc',
'test-alloc.cc',
......@@ -115,7 +116,8 @@
'test-version.cc',
'test-weakmaps.cc',
'test-weaksets.cc',
'test-weaktypedarrays.cc'
'test-weaktypedarrays.cc',
'trace-extension.cc'
],
'conditions': [
['v8_target_arch=="ia32"', {
......
......@@ -58,10 +58,11 @@
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 {
......
// 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
// 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
......@@ -28,8 +28,11 @@
// 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 =
......@@ -69,6 +72,4 @@ void ProfilerExtension::StopProfiling(
: v8::String::Empty(args.GetIsolate()));
}
static ProfilerExtension kProfilerExtension;
v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension);
} } // namespace v8::internal
......@@ -27,8 +27,14 @@
//
// 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) { }
......@@ -41,3 +47,8 @@ class ProfilerExtension : public v8::Extension {
private:
static const char* kSource;
};
} } // namespace v8::internal
#endif
......@@ -32,54 +32,10 @@
#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 =
......
......@@ -400,7 +400,7 @@ TEST(ProfileStartEndTime) {
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();
......@@ -554,7 +554,7 @@ TEST(CollectCpuProfile) {
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();
......@@ -628,7 +628,7 @@ TEST(SampleWhenFrameIsNotSetup) {
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();
......@@ -748,7 +748,7 @@ TEST(NativeAccessorUninitializedIC) {
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 =
......@@ -805,7 +805,7 @@ TEST(NativeAccessorMonomorphicIC) {
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 =
......@@ -859,7 +859,7 @@ TEST(NativeMethodUninitializedIC) {
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 =
......@@ -916,7 +916,7 @@ TEST(NativeMethodMonomorphicIC) {
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");
......@@ -957,7 +957,7 @@ TEST(BoundFunctionCall) {
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);
......@@ -1018,7 +1018,7 @@ TEST(FunctionCallSample) {
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();
{
......@@ -1101,7 +1101,7 @@ TEST(FunctionApplySample) {
};
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();
{
......@@ -1187,10 +1187,9 @@ static void CallJsFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
// 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);
......@@ -1272,10 +1271,9 @@ static const char* js_native_js_runtime_js_test_source =
// 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);
......@@ -1361,10 +1359,9 @@ static const char* js_native1_js_native2_js_test_source =
// 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);
......@@ -1494,10 +1491,9 @@ static void CheckFunctionDetails(v8::Isolate* isolate,
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(
......@@ -1514,7 +1510,7 @@ TEST(FunctionDetails) {
"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);
......@@ -1543,11 +1539,10 @@ TEST(FunctionDetails) {
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);
......
......@@ -2070,57 +2070,6 @@ TEST(JSFunctionHasCodeLink) {
}
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) {
......
......@@ -38,6 +38,7 @@
#include "isolate.h"
#include "log.h"
#include "sampler.h"
#include "trace-extension.h"
#include "vm-state-inl.h"
using v8::Function;
......@@ -52,137 +53,9 @@ using v8::internal::Address;
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);
......@@ -271,7 +144,7 @@ TEST(CFromJSStackTrace) {
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);
......@@ -296,7 +169,7 @@ TEST(CFromJSStackTrace) {
// 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;
......@@ -319,7 +192,7 @@ TEST(PureJSStackTrace) {
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);
......@@ -349,7 +222,7 @@ TEST(PureJSStackTrace) {
//
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;
......@@ -371,7 +244,7 @@ static void CFuncDoTrace(byte dummy_parameter) {
#else
#error Unexpected platform.
#endif
DoTrace(fp);
i::TraceExtension::DoTrace(fp);
}
......@@ -390,7 +263,7 @@ static int CFunc(int depth) {
// 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);
......@@ -403,11 +276,11 @@ TEST(JsEntrySp) {
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());
}
......@@ -552,12 +552,9 @@ TEST(RecordStackTraceAtStartProfiling) {
// 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());
......@@ -630,10 +627,9 @@ TEST(ProfileNodeScriptId) {
// 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);
......@@ -648,7 +644,7 @@ TEST(ProfileNodeScriptId) {
"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);
......@@ -733,10 +729,9 @@ TEST(LineNumber) {
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);
......@@ -757,7 +752,7 @@ TEST(BailoutReason) {
"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*>(
......
// 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
// 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment