Commit 42365d42 authored by titzer@chromium.org's avatar titzer@chromium.org

The empty husk of a JSFunction is useful to us.

We hollow out the rotting core and with evil intent repurpose its dry carcass to empower ourselves; with such a shell we can test.

R=mstarzinger@chromium.org

BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24459 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8faca47e
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
#include "src/compiler.h" #include "src/compiler.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h" #include "src/compiler/pipeline.h"
#include "src/execution.h" #include "src/execution.h"
#include "src/full-codegen.h" #include "src/full-codegen.h"
...@@ -37,51 +38,15 @@ class FunctionTester : public InitializedHandleScope { ...@@ -37,51 +38,15 @@ class FunctionTester : public InitializedHandleScope {
CHECK_EQ(0, flags_ & ~supported_flags); CHECK_EQ(0, flags_ & ~supported_flags);
} }
Isolate* isolate; explicit FunctionTester(Graph* graph)
Handle<JSFunction> function; : isolate(main_isolate()),
function(NewFunction("(function(a,b){})")),
Handle<JSFunction> Compile(Handle<JSFunction> function) { flags_(0) {
#if V8_TURBOFAN_TARGET CompileGraph(graph);
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
if (flags_ & CompilationInfo::kContextSpecializing) {
info.MarkAsContextSpecializing();
}
if (flags_ & CompilationInfo::kInliningEnabled) {
info.MarkAsInliningEnabled();
}
if (flags_ & CompilationInfo::kTypingEnabled) {
info.MarkAsTypingEnabled();
}
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
Pipeline pipeline(&info);
Handle<Code> code = pipeline.GenerateCode();
if (FLAG_turbo_deoptimization) {
info.context()->native_context()->AddOptimizedCode(*code);
} }
CHECK(!code.is_null()); Isolate* isolate;
function->ReplaceCode(*code); Handle<JSFunction> function;
#elif USE_CRANKSHAFT
Handle<Code> unoptimized = Handle<Code>(function->code());
Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
Compiler::NOT_CONCURRENT);
CHECK(!code.is_null());
#if ENABLE_DISASSEMBLER
if (FLAG_print_opt_code) {
CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
code->Disassemble("test code", tracing_scope.file());
}
#endif
function->ReplaceCode(*code);
#endif
return function;
}
MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) { MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
Handle<Object> args[] = {a, b}; Handle<Object> args[] = {a, b};
...@@ -183,8 +148,82 @@ class FunctionTester : public InitializedHandleScope { ...@@ -183,8 +148,82 @@ class FunctionTester : public InitializedHandleScope {
Handle<Object> false_value() { return isolate->factory()->false_value(); } Handle<Object> false_value() { return isolate->factory()->false_value(); }
Handle<JSFunction> Compile(Handle<JSFunction> function) {
// TODO(titzer): make this method private.
#if V8_TURBOFAN_TARGET
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
if (flags_ & CompilationInfo::kContextSpecializing) {
info.MarkAsContextSpecializing();
}
if (flags_ & CompilationInfo::kInliningEnabled) {
info.MarkAsInliningEnabled();
}
if (flags_ & CompilationInfo::kTypingEnabled) {
info.MarkAsTypingEnabled();
}
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
Pipeline pipeline(&info);
Handle<Code> code = pipeline.GenerateCode();
if (FLAG_turbo_deoptimization) {
info.context()->native_context()->AddOptimizedCode(*code);
}
CHECK(!code.is_null());
function->ReplaceCode(*code);
#elif USE_CRANKSHAFT
Handle<Code> unoptimized = Handle<Code>(function->code());
Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
Compiler::NOT_CONCURRENT);
CHECK(!code.is_null());
#if ENABLE_DISASSEMBLER
if (FLAG_print_opt_code) {
CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
code->Disassemble("test code", tracing_scope.file());
}
#endif
function->ReplaceCode(*code);
#endif
return function;
}
static Handle<JSFunction> ForMachineGraph(Graph* graph) {
JSFunction* p = NULL;
{ // because of the implicit handle scope of FunctionTester.
FunctionTester f(graph);
p = *f.function;
}
return Handle<JSFunction>(p); // allocated in outer handle scope.
}
private: private:
uint32_t flags_; uint32_t flags_;
// Compile the given machine graph instead of the source of the function
// and replace the JSFunction's code with the result.
Handle<JSFunction> CompileGraph(Graph* graph) {
CHECK(Pipeline::SupportedTarget());
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
info.SetOptimizing(BailoutId::None(),
Handle<Code>(function->shared()->code()));
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
Pipeline pipeline(&info);
Linkage linkage(&info);
Handle<Code> code = pipeline.GenerateCodeForMachineGraph(&linkage, graph);
CHECK(!code.is_null());
function->ReplaceCode(*code);
return function;
}
}; };
} }
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "src/scopes.h" #include "src/scopes.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
#include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/codegen-tester.h"
#include "test/cctest/compiler/function-tester.h"
#include "test/cctest/compiler/graph-builder-tester.h" #include "test/cctest/compiler/graph-builder-tester.h"
#include "test/cctest/compiler/value-helper.h" #include "test/cctest/compiler/value-helper.h"
...@@ -45,29 +46,10 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> { ...@@ -45,29 +46,10 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
template <typename T> template <typename T>
T* CallWithPotentialGC() { T* CallWithPotentialGC() {
// TODO(titzer): we need to wrap the code in a JSFunction and call it via // TODO(titzer): we wrap the code in a JSFunction here to reuse the
// Execution::Call() so that the GC knows about the frame, can walk it, // JSEntryStub; that could be done with a special prologue or other stub.
// relocate the code object if necessary, etc.
// This is pretty ugly and at the least should be moved up to helpers.
if (function.is_null()) { if (function.is_null()) {
function = function = FunctionTester::ForMachineGraph(this->graph());
v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast(CompileRun(
"(function() { 'use strict'; return 2.7123; })")));
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
CHECK_NE(NULL, info.scope());
Handle<ScopeInfo> scope_info =
ScopeInfo::Create(info.scope(), info.zone());
info.shared_info()->set_scope_info(*scope_info);
Pipeline pipeline(&info);
Linkage linkage(&info);
Handle<Code> code =
pipeline.GenerateCodeForMachineGraph(&linkage, this->graph());
CHECK(!code.is_null());
function->ReplaceCode(*code);
} }
Handle<Object>* args = NULL; Handle<Object>* args = NULL;
MaybeHandle<Object> result = MaybeHandle<Object> result =
......
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