17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h" 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/cctest.h" 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/code-generator.h" 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/common-operator.h" 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/graph.h" 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/instruction-selector.h" 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/machine-operator.h" 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node.h" 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/operator.h" 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/raw-machine-assembler.h" 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/register-allocator.h" 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/schedule.h" 187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/full-codegen.h" 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/parser.h" 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/rewriter.h" 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 239aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org#include "test/cctest/compiler/c-signature.h" 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/compiler/function-tester.h" 257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgusing namespace v8::internal; 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgusing namespace v8::internal::compiler; 287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#if V8_TURBOFAN_TARGET 317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtypedef RawMachineAssembler::Label MLabel; 337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic Handle<JSFunction> NewFunction(const char* source) { 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return v8::Utils::OpenHandle( 367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *v8::Handle<v8::Function>::Cast(CompileRun(source))); 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass DeoptCodegenTester { 417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src) 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : scope_(scope), 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org function(NewFunction(src)), 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org info(function, scope->main_zone()), 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bailout_id(-1) { 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(Parser::Parse(&info)); 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code())); 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(Rewriter::Rewrite(&info)); 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(Scope::Analyze(&info)); 51a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org CHECK(Compiler::EnsureDeoptimizationSupport(&info)); 527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 53e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info.shared_info()->has_deoptimization_support()); 547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org graph = new (scope_->main_zone()) Graph(scope_->main_zone()); 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org virtual ~DeoptCodegenTester() { delete code; } 597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void GenerateCodeFromSchedule(Schedule* schedule) { 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org OFStream os(stdout); 629aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (FLAG_trace_turbo) { 639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org os << *schedule; 649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Initialize the codegen and generate code. 677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Linkage* linkage = new (scope_->main_zone()) Linkage(&info); 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org code = new v8::internal::compiler::InstructionSequence(linkage, graph, 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org schedule); 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SourcePositionTable source_positions(graph); 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionSelector selector(code, &source_positions); 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector.SelectInstructions(); 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (FLAG_trace_turbo) { 759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org os << "----- Instruction sequence before register allocation -----\n" 769aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org << *code; 779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org RegisterAllocator allocator(code); 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(allocator.Allocate()); 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 829aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (FLAG_trace_turbo) { 839aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org os << "----- Instruction sequence after register allocation -----\n" 849aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org << *code; 859aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org compiler::CodeGenerator generator(code); 887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org result_code = generator.GenerateCode(); 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 909aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org#ifdef OBJECT_PRINT 919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (FLAG_print_opt_code || FLAG_trace_turbo) { 929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org result_code->Print(); 939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Zone* zone() { return scope_->main_zone(); } 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org HandleAndZoneScope* scope_; 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSFunction> function; 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CompilationInfo info; 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BailoutId bailout_id; 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Code> result_code; 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org v8::internal::compiler::InstructionSequence* code; 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Graph* graph; 1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass TrivialDeoptCodegenTester : public DeoptCodegenTester { 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope) 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : DeoptCodegenTester(scope, 1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "function foo() { deopt(); return 42; }; foo") {} 1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void GenerateCode() { 1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org GenerateCodeFromSchedule(BuildGraphAndSchedule(graph)); 1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* BuildGraphAndSchedule(Graph* graph) { 1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CommonOperatorBuilder common(zone()); 1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Manually construct a schedule for the function below: 1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // function foo() { 1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // deopt(); 1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // } 1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1279aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org CSignature1<Object*, Object*> sig; 1289aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org RawMachineAssembler m(graph, &sig); 1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSFunction> deopt_function = 1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt"); 1321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object> deopt_fun_constant = 1331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object>::CreateUninitialized(deopt_function); 1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant)); 1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1361af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Context> caller_context(function->context(), CcTest::i_isolate()); 1371af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object> caller_context_constant = 1381af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object>::CreateUninitialized(caller_context); 1391af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Node* caller_context_node = 1401af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org m.NewNode(common.HeapConstant(caller_context_constant)); 1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bailout_id = GetCallBailoutId(); 1439aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant()); 1449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Node* locals = m.NewNode(common.StateValues(0)); 1459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Node* stack = m.NewNode(common.StateValues(0)); 1469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 147a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Node* state_node = m.NewNode( 148a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org common.FrameState(JS_FRAME, bailout_id, kIgnoreOutput), parameters, 149a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org locals, stack, caller_context_node, m.UndefinedConstant()); 1501af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org 1511af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Context> context(deopt_function->context(), CcTest::i_isolate()); 1521af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object> context_constant = 1531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object>::CreateUninitialized(context); 1541af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Node* context_node = m.NewNode(common.HeapConstant(context_constant)); 155ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 1569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node); 157ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 1589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m.Return(m.UndefinedConstant()); 1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Schedule the graph: 1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* schedule = m.Export(); 1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return schedule; 1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BailoutId GetCallBailoutId() { 1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ZoneList<Statement*>* body = info.function()->body(); 1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (int i = 0; i < body->length(); i++) { 1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (body->at(i)->IsExpressionStatement() && 1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org body->at(i)->AsExpressionStatement()->expression()->IsCall()) { 1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return body->at(i)->AsExpressionStatement()->expression()->id(); 1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(false); 1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return BailoutId(-1); 1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(TurboTrivialDeoptCodegen) { 1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org HandleAndZoneScope scope; 1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InitializedHandleScope handles; 1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FLAG_allow_natives_syntax = true; 1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FLAG_turbo_deoptimization = true; 1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TrivialDeoptCodegenTester t(&scope); 1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.GenerateCode(); 1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org DeoptimizationInputData* data = 1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org DeoptimizationInputData::cast(t.result_code->deoptimization_data()); 1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 193ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org // TODO(jarin) Find a way to test the safepoint. 1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Check that we deoptimize to the right AST id. 1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(1, data->DeoptCount()); 1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt()); 1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(TurboTrivialDeoptCodegenAndRun) { 2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org HandleAndZoneScope scope; 2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InitializedHandleScope handles; 2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FLAG_allow_natives_syntax = true; 2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FLAG_turbo_deoptimization = true; 2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TrivialDeoptCodegenTester t(&scope); 2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.GenerateCode(); 2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.function->ReplaceCode(*t.result_code); 2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.info.context()->native_context()->AddOptimizedCode(*t.result_code); 2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Isolate* isolate = scope.main_isolate(); 2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> result; 2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool has_pending_exception = 2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org !Execution::Call(isolate, t.function, 2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org isolate->factory()->undefined_value(), 0, NULL, 2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org false).ToHandle(&result); 2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(!has_pending_exception); 2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(result->SameValue(Smi::FromInt(42))); 2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester { 2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope) 2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : DeoptCodegenTester( 2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org scope, 2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {} 2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void GenerateCode() { 2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org GenerateCodeFromSchedule(BuildGraphAndSchedule(graph)); 2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* BuildGraphAndSchedule(Graph* graph) { 2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CommonOperatorBuilder common(zone()); 2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Manually construct a schedule for the function below: 2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // function foo() { 2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // %DeoptimizeFunction(foo); 2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // } 2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org CSignature1<Object*, Object*> sig; 2459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org RawMachineAssembler m(graph, &sig); 2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2471af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object> this_fun_constant = 2481af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object>::CreateUninitialized(function); 2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant)); 2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2519aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Handle<Context> context(function->context(), CcTest::i_isolate()); 2521af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object> context_constant = 2531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Unique<Object>::CreateUninitialized(context); 2549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* context_node = m.NewNode(common.HeapConstant(context_constant)); 2559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bailout_id = GetCallBailoutId(); 2579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant()); 2589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Node* locals = m.NewNode(common.StateValues(0)); 2599d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Node* stack = m.NewNode(common.StateValues(0)); 2609d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 261a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Node* state_node = m.NewNode( 262a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org common.FrameState(JS_FRAME, bailout_id, kIgnoreOutput), parameters, 263a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org locals, stack, context_node, m.UndefinedConstant()); 264ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 2659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node, 2669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org state_node); 267ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 2689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org m.Return(m.UndefinedConstant()); 2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Schedule the graph: 2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* schedule = m.Export(); 2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return schedule; 2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BailoutId GetCallBailoutId() { 2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ZoneList<Statement*>* body = info.function()->body(); 2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (int i = 0; i < body->length(); i++) { 2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (body->at(i)->IsExpressionStatement() && 2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) { 2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return body->at(i)->AsExpressionStatement()->expression()->id(); 2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(false); 2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return BailoutId(-1); 2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(TurboTrivialRuntimeDeoptCodegenAndRun) { 2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org HandleAndZoneScope scope; 2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InitializedHandleScope handles; 2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FLAG_allow_natives_syntax = true; 2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FLAG_turbo_deoptimization = true; 2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TrivialRuntimeDeoptCodegenTester t(&scope); 2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.GenerateCode(); 2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.function->ReplaceCode(*t.result_code); 3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org t.info.context()->native_context()->AddOptimizedCode(*t.result_code); 3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Isolate* isolate = scope.main_isolate(); 3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Object> result; 3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool has_pending_exception = 3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org !Execution::Call(isolate, t.function, 3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org isolate->factory()->undefined_value(), 0, NULL, 3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org false).ToHandle(&result); 3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(!has_pending_exception); 3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(result->SameValue(Smi::FromInt(42))); 3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif 314