| Index: test/cctest/compiler/test-codegen-deopt.cc
|
| diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc
|
| deleted file mode 100644
|
| index f20d7760c420edb95790f69d54abc9d59caa6bdb..0000000000000000000000000000000000000000
|
| --- a/test/cctest/compiler/test-codegen-deopt.cc
|
| +++ /dev/null
|
| @@ -1,300 +0,0 @@
|
| -// Copyright 2014 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "src/v8.h"
|
| -#include "test/cctest/cctest.h"
|
| -
|
| -#include "src/compiler/code-generator.h"
|
| -#include "src/compiler/common-operator.h"
|
| -#include "src/compiler/graph.h"
|
| -#include "src/compiler/instruction-selector.h"
|
| -#include "src/compiler/machine-operator.h"
|
| -#include "src/compiler/node.h"
|
| -#include "src/compiler/operator.h"
|
| -#include "src/compiler/raw-machine-assembler.h"
|
| -#include "src/compiler/register-allocator.h"
|
| -#include "src/compiler/schedule.h"
|
| -
|
| -#include "src/ast-numbering.h"
|
| -#include "src/full-codegen.h"
|
| -#include "src/parser.h"
|
| -#include "src/rewriter.h"
|
| -
|
| -#include "test/cctest/compiler/c-signature.h"
|
| -#include "test/cctest/compiler/function-tester.h"
|
| -
|
| -using namespace v8::internal;
|
| -using namespace v8::internal::compiler;
|
| -
|
| -
|
| -#if V8_TURBOFAN_TARGET
|
| -
|
| -typedef RawMachineAssembler::Label MLabel;
|
| -typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
|
| -
|
| -static Handle<JSFunction> NewFunction(const char* source) {
|
| - return v8::Utils::OpenHandle(
|
| - *v8::Handle<v8::Function>::Cast(CompileRun(source)));
|
| -}
|
| -
|
| -
|
| -class DeoptCodegenTester {
|
| - public:
|
| - explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src)
|
| - : scope_(scope),
|
| - function(NewFunction(src)),
|
| - parse_info(scope->main_zone(), function),
|
| - info(&parse_info),
|
| - bailout_id(-1),
|
| - tagged_type(1, kMachAnyTagged, zone()),
|
| - empty_types(zone()) {
|
| - CHECK(Parser::ParseStatic(&parse_info));
|
| - info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
|
| - CHECK(Compiler::Analyze(&parse_info));
|
| - CHECK(Compiler::EnsureDeoptimizationSupport(&info));
|
| -
|
| - DCHECK(info.shared_info()->has_deoptimization_support());
|
| -
|
| - graph = new (scope_->main_zone()) Graph(scope_->main_zone());
|
| - }
|
| -
|
| - virtual ~DeoptCodegenTester() {}
|
| -
|
| - void GenerateCodeFromSchedule(Schedule* schedule) {
|
| - OFStream os(stdout);
|
| - if (FLAG_trace_turbo) {
|
| - os << *schedule;
|
| - }
|
| - result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
|
| -#ifdef OBJECT_PRINT
|
| - if (FLAG_print_opt_code || FLAG_trace_turbo) {
|
| - result_code->Print();
|
| - }
|
| -#endif
|
| - }
|
| -
|
| - Zone* zone() { return scope_->main_zone(); }
|
| - Isolate* isolate() { return scope_->main_isolate(); }
|
| -
|
| - HandleAndZoneScope* scope_;
|
| - Handle<JSFunction> function;
|
| - ParseInfo parse_info;
|
| - CompilationInfo info;
|
| - BailoutId bailout_id;
|
| - Handle<Code> result_code;
|
| - TestInstrSeq* code;
|
| - Graph* graph;
|
| - ZoneVector<MachineType> tagged_type;
|
| - ZoneVector<MachineType> empty_types;
|
| -};
|
| -
|
| -
|
| -class TrivialDeoptCodegenTester : public DeoptCodegenTester {
|
| - public:
|
| - explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope)
|
| - : DeoptCodegenTester(scope,
|
| - "function foo() { deopt(); return 42; }; foo") {}
|
| -
|
| - void GenerateCode() {
|
| - GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
|
| - }
|
| -
|
| - Schedule* BuildGraphAndSchedule(Graph* graph) {
|
| - CommonOperatorBuilder common(zone());
|
| -
|
| - // Manually construct a schedule for the function below:
|
| - // function foo() {
|
| - // deopt();
|
| - // }
|
| -
|
| - CSignature1<Object*, Object*> sig;
|
| - RawMachineAssembler m(isolate(), graph, &sig);
|
| -
|
| - Handle<JSFunction> deopt_function =
|
| - NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
|
| - Unique<JSFunction> deopt_fun_constant =
|
| - Unique<JSFunction>::CreateUninitialized(deopt_function);
|
| - Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
|
| -
|
| - Handle<Context> caller_context(function->context(), CcTest::i_isolate());
|
| - Unique<Context> caller_context_constant =
|
| - Unique<Context>::CreateUninitialized(caller_context);
|
| - Node* caller_context_node =
|
| - m.NewNode(common.HeapConstant(caller_context_constant));
|
| -
|
| - bailout_id = GetCallBailoutId();
|
| - Node* parameters =
|
| - m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
|
| - Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
|
| - Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
|
| -
|
| - Node* state_node =
|
| - m.NewNode(common.FrameState(JS_FRAME, bailout_id,
|
| - OutputFrameStateCombine::Ignore()),
|
| - parameters, locals, stack, caller_context_node,
|
| - deopt_fun_node, m.UndefinedConstant());
|
| -
|
| - Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
|
| - Unique<Context> context_constant =
|
| - Unique<Context>::CreateUninitialized(context);
|
| - Node* context_node = m.NewNode(common.HeapConstant(context_constant));
|
| -
|
| - m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
|
| -
|
| - m.Return(m.UndefinedConstant());
|
| -
|
| - // Schedule the graph:
|
| - Schedule* schedule = m.Export();
|
| -
|
| - return schedule;
|
| - }
|
| -
|
| - BailoutId GetCallBailoutId() {
|
| - ZoneList<Statement*>* body = info.function()->body();
|
| - for (int i = 0; i < body->length(); i++) {
|
| - if (body->at(i)->IsExpressionStatement() &&
|
| - body->at(i)->AsExpressionStatement()->expression()->IsCall()) {
|
| - return body->at(i)->AsExpressionStatement()->expression()->id();
|
| - }
|
| - }
|
| - CHECK(false);
|
| - return BailoutId(-1);
|
| - }
|
| -};
|
| -
|
| -
|
| -TEST(TurboTrivialDeoptCodegen) {
|
| - HandleAndZoneScope scope;
|
| - InitializedHandleScope handles;
|
| -
|
| - FLAG_allow_natives_syntax = true;
|
| -
|
| - TrivialDeoptCodegenTester t(&scope);
|
| - t.GenerateCode();
|
| -
|
| - DeoptimizationInputData* data =
|
| - DeoptimizationInputData::cast(t.result_code->deoptimization_data());
|
| -
|
| - // TODO(jarin) Find a way to test the safepoint.
|
| -
|
| - // Check that we deoptimize to the right AST id.
|
| - CHECK_EQ(1, data->DeoptCount());
|
| - CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
|
| -}
|
| -
|
| -
|
| -TEST(TurboTrivialDeoptCodegenAndRun) {
|
| - HandleAndZoneScope scope;
|
| - InitializedHandleScope handles;
|
| -
|
| - FLAG_allow_natives_syntax = true;
|
| -
|
| - TrivialDeoptCodegenTester t(&scope);
|
| - t.GenerateCode();
|
| -
|
| - t.function->ReplaceCode(*t.result_code);
|
| - t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
|
| -
|
| - Isolate* isolate = scope.main_isolate();
|
| - Handle<Object> result;
|
| - bool has_pending_exception =
|
| - !Execution::Call(isolate, t.function,
|
| - isolate->factory()->undefined_value(), 0, NULL,
|
| - false).ToHandle(&result);
|
| - CHECK(!has_pending_exception);
|
| - CHECK(result->SameValue(Smi::FromInt(42)));
|
| -}
|
| -
|
| -
|
| -class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
|
| - public:
|
| - explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope)
|
| - : DeoptCodegenTester(
|
| - scope,
|
| - "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {}
|
| -
|
| - void GenerateCode() {
|
| - GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
|
| - }
|
| -
|
| - Schedule* BuildGraphAndSchedule(Graph* graph) {
|
| - CommonOperatorBuilder common(zone());
|
| -
|
| - // Manually construct a schedule for the function below:
|
| - // function foo() {
|
| - // %DeoptimizeFunction(foo);
|
| - // }
|
| -
|
| - CSignature1<Object*, Object*> sig;
|
| - RawMachineAssembler m(isolate(), graph, &sig);
|
| -
|
| - Unique<HeapObject> this_fun_constant =
|
| - Unique<HeapObject>::CreateUninitialized(function);
|
| - Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
|
| -
|
| - Handle<Context> context(function->context(), CcTest::i_isolate());
|
| - Unique<HeapObject> context_constant =
|
| - Unique<HeapObject>::CreateUninitialized(context);
|
| - Node* context_node = m.NewNode(common.HeapConstant(context_constant));
|
| -
|
| - bailout_id = GetCallBailoutId();
|
| - Node* parameters =
|
| - m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
|
| - Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
|
| - Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
|
| -
|
| - Node* state_node =
|
| - m.NewNode(common.FrameState(JS_FRAME, bailout_id,
|
| - OutputFrameStateCombine::Ignore()),
|
| - parameters, locals, stack, context_node, this_fun_node,
|
| - m.UndefinedConstant());
|
| -
|
| - m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
|
| - state_node);
|
| -
|
| - m.Return(m.UndefinedConstant());
|
| -
|
| - // Schedule the graph:
|
| - Schedule* schedule = m.Export();
|
| -
|
| - return schedule;
|
| - }
|
| -
|
| - BailoutId GetCallBailoutId() {
|
| - ZoneList<Statement*>* body = info.function()->body();
|
| - for (int i = 0; i < body->length(); i++) {
|
| - if (body->at(i)->IsExpressionStatement() &&
|
| - body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) {
|
| - return body->at(i)->AsExpressionStatement()->expression()->id();
|
| - }
|
| - }
|
| - CHECK(false);
|
| - return BailoutId(-1);
|
| - }
|
| -};
|
| -
|
| -
|
| -TEST(TurboTrivialRuntimeDeoptCodegenAndRun) {
|
| - HandleAndZoneScope scope;
|
| - InitializedHandleScope handles;
|
| -
|
| - FLAG_allow_natives_syntax = true;
|
| -
|
| - TrivialRuntimeDeoptCodegenTester t(&scope);
|
| - t.GenerateCode();
|
| -
|
| - t.function->ReplaceCode(*t.result_code);
|
| - t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
|
| -
|
| - Isolate* isolate = scope.main_isolate();
|
| - Handle<Object> result;
|
| - bool has_pending_exception =
|
| - !Execution::Call(isolate, t.function,
|
| - isolate->factory()->undefined_value(), 0, NULL,
|
| - false).ToHandle(&result);
|
| - CHECK(!has_pending_exception);
|
| - CHECK(result->SameValue(Smi::FromInt(42)));
|
| -}
|
| -
|
| -#endif
|
|
|