1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/address-map.h" 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/base/adapters.h" 9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator-impl.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/pipeline.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CodeGenerator::JumpTable final : public ZoneObject { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpTable(JumpTable* next, Label** targets, size_t target_count) 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : next_(next), targets_(targets), target_count_(target_count) {} 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* label() { return &label_; } 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpTable* next() const { return next_; } 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** targets() const { return targets_; } 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t target_count() const { return target_count_; } 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label label_; 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpTable* const next_; 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** const targets_; 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const target_count_; 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionSequence* code, CompilationInfo* info) 38bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : frame_access_state_(nullptr), 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier linkage_(linkage), 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code_(code), 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_(zone()), 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier info_(info), 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_block_(RpoNumber::Invalid()), 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_source_position_(SourcePosition::Unknown()), 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kNo), 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolver_(this), 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints_(code->zone()), 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch handlers_(code->zone()), 503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch deoptimization_exits_(code->zone()), 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_states_(code->zone()), 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_literals_(code->zone()), 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_function_count_(0), 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translations_(code->zone()), 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_lazy_deopt_pc_(0), 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jump_tables_(nullptr), 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ools_(nullptr), 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch osr_pc_offset_(-1), 5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch optimized_out_literal_id_(-1), 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch source_position_table_builder_(code->zone(), 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch info->SourcePositionRecordingMode()) { 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < code->InstructionBlockCount(); ++i) { 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new (&labels_[i]) Label; 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 65bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CreateFrameAccessState(frame); 66bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 67bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 68f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochIsolate* CodeGenerator::isolate() const { return info_->isolate(); } 69f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 70bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::CreateFrameAccessState(Frame* frame) { 71bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FinishFrame(frame); 72bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame_access_state_ = new (code()->zone()) FrameAccessState(frame); 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> CodeGenerator::GenerateCode() { 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CompilationInfo* info = this->info(); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Open a frame scope to indicate that there is a frame on the stack. The 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // MANUAL indicates that the scope shouldn't actually generate code to set up 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the frame (that is done in AssemblePrologue). 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame_scope(masm(), StackFrame::MANUAL); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (info->is_source_positions_enabled()) { 8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SourcePosition source_position(info->shared_info()->start_position()); 8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleSourcePosition(source_position); 8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Place function entry hook if requested to do so. 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProfileEntryHookStub::MaybeCallEntryHook(masm()); 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Architecture-specific, linkage-specific prologue. 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->set_prologue_offset(masm()->pc_offset()); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define deoptimization literals for all inlined functions. 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0u, deoptimization_literals_.size()); 98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (CompilationInfo::InlinedFunctionHolder& inlined : 993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch info->inlined_functions()) { 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!inlined.shared_info.is_identical_to(info->shared_info())) { 101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int index = DefineDeoptimizationLiteral(inlined.shared_info); 102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch inlined.RegisterInlinedFunctionId(index); 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_function_count_ = deoptimization_literals_.size(); 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define deoptimization literals for all unoptimized code objects of inlined 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // functions. This ensures unoptimized code is kept alive by optimized code. 1093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (const CompilationInfo::InlinedFunctionHolder& inlined : 1103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch info->inlined_functions()) { 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!inlined.shared_info.is_identical_to(info->shared_info())) { 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DefineDeoptimizationLiteral(inlined.inlined_code_object_root); 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.SetNumberOfInstructionBlocks( 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch code()->InstructionBlockCount()); 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assemble all non-deferred blocks, followed by deferred ones. 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int deferred = 0; deferred < 2; ++deferred) { 1213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (const InstructionBlock* block : code()->instruction_blocks()) { 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (block->IsDeferred() == (deferred == 0)) { 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Align loop headers on 16-byte boundaries. 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (block->IsLoopHeader()) masm()->Align(16); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensure lazy deopt doesn't patch handler entry points. 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->IsHandler()) EnsureSpaceForLazyDeopt(); 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Bind a label for a block. 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_block_ = block->rpo_number(); 131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.BeginInstructionBlock(masm()->pc_offset(), block); 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_code_comments) { 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): these code comments are a giant memory leak. 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Vector<char> buffer = Vector<char>::New(200); 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch char* buffer_start = buffer.start(); 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int next = SNPrintF( 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer, "-- B%d start%s%s%s%s", block->rpo_number().ToInt(), 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->IsDeferred() ? " (deferred)" : "", 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->needs_frame() ? "" : " (no frame)", 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->must_construct_frame() ? " (construct frame)" : "", 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->must_deconstruct_frame() ? " (deconstruct frame)" : ""); 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = buffer.SubVector(next, buffer.length()); 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->IsLoopHeader()) { 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next = 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(buffer, " (loop up to %d)", block->loop_end().ToInt()); 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = buffer.SubVector(next, buffer.length()); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->loop_header().IsValid()) { 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next = 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt()); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = buffer.SubVector(next, buffer.length()); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(buffer, " --"); 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->RecordComment(buffer_start); 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch frame_access_state()->MarkHasFrame(block->needs_frame()); 1613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm()->bind(GetLabel(current_block_)); 1633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (block->must_construct_frame()) { 164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AssembleConstructFrame(); 1653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // We need to setup the root register after we assemble the prologue, to 1663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // avoid clobbering callee saved registers in case of C linkage and 1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // using the roots. 1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // TODO(mtrofin): investigate how we can avoid doing this repeatedly. 1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) { 1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch masm()->InitializeRootRegister(); 1713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CodeGenResult result; 1753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (FLAG_enable_embedded_constant_pool && !block->needs_frame()) { 1763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConstantPoolUnavailableScope constant_pool_unavailable(masm()); 177bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch result = AssembleBlock(block); 1783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch result = AssembleBlock(block); 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (result != kSuccess) return Handle<Code>(); 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.EndInstructionBlock(block); 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assemble all out-of-line code. 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ools_) { 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm()->RecordComment("-- Out of line code --"); 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm()->bind(ool->entry()); 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ool->Generate(); 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ool->exit()->is_bound()) masm()->jmp(ool->exit()); 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Assemble all eager deoptimization exits. 1973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (DeoptimizationExit* exit : deoptimization_exits_) { 1983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch masm()->bind(exit->label()); 19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleDeoptimizerCall(exit->deoptimization_id(), exit->pos()); 2003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Ensure there is space for lazy deoptimization in the code. 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->ShouldEnsureSpaceForLazyDeopt()) { 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (masm()->pc_offset() < target_offset) { 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm()->nop(); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FinishCode(masm()); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit the jump tables. 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (jump_tables_) { 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->Align(kPointerSize); 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (JumpTable* table = jump_tables_; table; table = table->next()) { 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->bind(table->label()); 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleJumpTable(table->targets(), table->target_count()); 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch safepoints()->Emit(masm(), frame()->GetTotalFrameSlotCount()); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.Finish(masm()->pc_offset()); 224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Code> result = v8::internal::CodeGenerator::MakeCodeEpilogue( 226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm(), unwinding_info_writer_.eh_frame_writer(), info, Handle<Object>()); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_is_turbofanned(true); 228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch result->set_stack_slots(frame()->GetTotalFrameSlotCount()); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_safepoint_table_offset(safepoints()->GetCodeOffset()); 230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<ByteArray> source_positions = 231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch source_position_table_builder_.ToSourcePositionTable( 232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), Handle<AbstractCode>::cast(result)); 233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result->set_source_position_table(*source_positions); 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit exception handler table. 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!handlers_.empty()) { 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HandlerTable> table = 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray( 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandlerTable::LengthForReturn(static_cast<int>(handlers_.size())), 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TENURED)); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t i = 0; i < handlers_.size(); ++i) { 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch table->SetReturnOffset(static_cast<int>(i), handlers_[i].pc_offset); 243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch table->SetReturnHandler(static_cast<int>(i), handlers_[i].handler->pos()); 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result->set_handler_table(*table); 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopulateDeoptimizationData(result); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Ensure there is space for lazy deoptimization in the relocation info. 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->ShouldEnsureSpaceForLazyDeopt()) { 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code() 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->InstructionBlockAt(current_block_) 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->ao_number() 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch .IsNext(code()->InstructionBlockAt(block)->ao_number()); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordSafepoint(ReferenceMap* references, 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Safepoint::Kind kind, int arguments, 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::DeoptMode deopt_mode) { 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint safepoint = 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode); 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int stackSlotToSpillSlotDelta = 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount(); 2743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (const InstructionOperand& operand : references->reference_operands()) { 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (operand.IsStackSlot()) { 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int index = LocationOperand::cast(operand).index(); 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(index >= 0); 278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We might index values in the fixed part of the frame (i.e. the 279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // closure pointer or the context pointer); these are not spill slots 280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // and therefore don't work with the SafepointTable currently, but 281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // we also don't need to worry about them, since the GC has special 282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // knowledge about those fields anyway. 283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (index < stackSlotToSpillSlotDelta) continue; 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch safepoint.DefinePointerSlot(index, zone()); 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) { 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = LocationOperand::cast(operand).GetRegister(); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoint.DefinePointerRegister(reg, zone()); 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsMaterializableFromRoot( 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> object, Heap::RootListIndex* index_return) { 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallDescriptor* incoming_descriptor = 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch linkage()->GetIncomingDescriptor(); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (incoming_descriptor->flags() & CallDescriptor::kCanUseRoots) { 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RootIndexMap map(isolate()); 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int root_index = map.Lookup(*object); 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (root_index != RootIndexMap::kInvalidRootIndex) { 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *index_return = static_cast<Heap::RootListIndex>(root_index); 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleBlock( 308bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const InstructionBlock* block) { 3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = block->code_start(); i < block->code_end(); ++i) { 3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instruction* instr = code()->InstructionAt(i); 311bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CodeGenResult result = AssembleInstruction(instr, block); 312bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (result != kSuccess) return result; 3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 314bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CodeGenerator::IsValidPush(InstructionOperand source, 318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CodeGenerator::PushTypeFlags push_type) { 319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (source.IsImmediate() && 320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ((push_type & CodeGenerator::kImmediatePush) != 0)) { 321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if ((source.IsRegister() || source.IsStackSlot()) && 324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ((push_type & CodeGenerator::kScalarPush) != 0)) { 325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if ((source.IsFloatRegister() || source.IsFloatStackSlot()) && 328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ((push_type & CodeGenerator::kFloat32Push) != 0)) { 329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if ((source.IsDoubleRegister() || source.IsFloatStackSlot()) && 332f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ((push_type & CodeGenerator::kFloat64Push) != 0)) { 333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::GetPushCompatibleMoves(Instruction* instr, 339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PushTypeFlags push_type, 340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<MoveOperands*>* pushes) { 341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pushes->clear(); 342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (int i = Instruction::FIRST_GAP_POSITION; 343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i <= Instruction::LAST_GAP_POSITION; ++i) { 344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Instruction::GapPosition inner_pos = 345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static_cast<Instruction::GapPosition>(i); 346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ParallelMove* parallel_move = instr->GetParallelMove(inner_pos); 347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (parallel_move != nullptr) { 348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto move : *parallel_move) { 349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand source = move->source(); 350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand destination = move->destination(); 351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_push_compatible_index = 352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; 353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If there are any moves from slots that will be overridden by pushes, 354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // then the full gap resolver must be used since optimization with 355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // pushes don't participate in the parallel move and might clobber 356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // values needed for the gap resolve. 357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (source.IsStackSlot() && 358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand::cast(source).index() >= 359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_push_compatible_index) { 360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pushes->clear(); 361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(danno): Right now, only consider moves from the FIRST gap for 364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // pushes. Theoretically, we could extract pushes for both gaps (there 365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // are cases where this happens), but the logic for that would also have 366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // to check to make sure that non-memory inputs to the pushes from the 367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // LAST gap don't get clobbered in the FIRST gap. 368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (i == Instruction::FIRST_GAP_POSITION) { 369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (destination.IsStackSlot() && 370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand::cast(destination).index() >= 371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_push_compatible_index) { 372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int index = LocationOperand::cast(destination).index(); 373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsValidPush(source, push_type)) { 374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (index >= static_cast<int>(pushes->size())) { 375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pushes->resize(index + 1); 376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (*pushes)[index] = move; 378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // For now, only support a set of continuous pushes at the end of the list. 386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t push_count_upper_bound = pushes->size(); 387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t push_begin = push_count_upper_bound; 388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto move : base::Reversed(*pushes)) { 389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (move == nullptr) break; 390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch push_begin--; 391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t push_count = pushes->size() - push_begin; 393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::copy(pushes->begin() + push_begin, 394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pushes->begin() + push_begin + push_count, pushes->begin()); 395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pushes->resize(push_count); 396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 398bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleInstruction( 399bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Instruction* instr, const InstructionBlock* block) { 400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot; 40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsMode mode = FlagsModeField::decode(instr->opcode()); 40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (mode != kFlags_trap) { 40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleSourcePosition(instr); 40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 405f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool adjust_stack = 406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetSlotAboveSPBeforeTailCall(instr, &first_unused_stack_slot); 407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (adjust_stack) AssembleTailCallBeforeGap(instr, first_unused_stack_slot); 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleGaps(instr); 409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (adjust_stack) AssembleTailCallAfterGap(instr, first_unused_stack_slot); 4103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_IMPLIES( 4113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch block->must_deconstruct_frame(), 4123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr != code()->InstructionAt(block->last_instruction_index()) || 4133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr->IsRet() || instr->IsJump()); 4143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (instr->IsJump() && block->must_deconstruct_frame()) { 4153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 4163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assemble architecture-specific code for the instruction. 418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CodeGenResult result = AssembleArchInstruction(instr); 419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (result != kSuccess) return result; 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); 4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (mode) { 4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kFlags_branch: { 4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Assemble a branch after this instruction. 4253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionOperandConverter i(this, instr); 4263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2); 4273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1); 4283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (true_rpo == false_rpo) { 4303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // redundant branch. 4313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!IsNextInAssemblyOrder(true_rpo)) { 4323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleArchJump(true_rpo); 4333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 434bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 4363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsNextInAssemblyOrder(true_rpo)) { 4373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // true block is next, can fall through if condition negated. 4383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch std::swap(true_rpo, false_rpo); 4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch condition = NegateFlagsCondition(condition); 4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BranchInfo branch; 4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.condition = condition; 4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.true_label = GetLabel(true_rpo); 4443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.false_label = GetLabel(false_rpo); 4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.fallthru = IsNextInAssemblyOrder(false_rpo); 4463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Assemble architecture-specific branch. 4473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleArchBranch(instr, &branch); 4483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kFlags_deoptimize: { 4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Assemble a conditional eager deoptimization after this instruction. 4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionOperandConverter i(this, instr); 4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch size_t frame_state_offset = MiscField::decode(instr->opcode()); 4543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DeoptimizationExit* const exit = 4553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AddDeoptimizationExit(instr, frame_state_offset); 4563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label continue_label; 4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BranchInfo branch; 4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.condition = condition; 4593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.true_label = exit->label(); 4603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.false_label = &continue_label; 4613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch.fallthru = true; 4623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Assemble architecture-specific branch. 4633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleArchBranch(instr, &branch); 4643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch masm()->bind(&continue_label); 4653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kFlags_set: { 4683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Assemble a boolean materialization after this instruction. 4693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleArchBoolean(instr, condition); 4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kFlags_trap: { 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleArchTrap(instr, condition); 47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 4763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kFlags_none: { 4773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 480bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSourcePosition(Instruction* instr) { 484c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePosition source_position = SourcePosition::Unknown(); 48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (instr->IsNop() && instr->AreMovesRedundant()) return; 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!code()->GetSourcePosition(instr, &source_position)) return; 48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleSourcePosition(source_position); 48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 49062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleSourcePosition(SourcePosition source_position) { 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (source_position == current_source_position_) return; 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_source_position_ = source_position; 493c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!source_position.IsKnown()) return; 494c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch source_position_table_builder_.AddPosition(masm()->pc_offset(), 495c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch source_position, false); 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_code_comments) { 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationInfo* info = this->info(); 49813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!info->parse_info()) return; 499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::ostringstream buffer; 50062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch buffer << "-- "; 50162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_turbo) { 50262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch buffer << source_position; 50362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 50462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch buffer << source_position.InliningStack(info); 50562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 50662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch buffer << " --"; 507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch masm()->RecordComment(StrDup(buffer.str().c_str())); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CodeGenerator::GetSlotAboveSPBeforeTailCall(Instruction* instr, 512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int* slot) { 513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->IsTailCall()) { 514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperandConverter g(this, instr); 515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *slot = g.InputInt32(instr->InputCount() - 1); 516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleGaps(Instruction* instr) { 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = Instruction::FIRST_GAP_POSITION; 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i <= Instruction::LAST_GAP_POSITION; i++) { 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction::GapPosition inner_pos = 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<Instruction::GapPosition>(i); 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ParallelMove* move = instr->GetParallelMove(inner_pos); 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (move != nullptr) resolver()->Resolve(move); 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace { 533c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<PodArray<InliningPosition>> CreateInliningPositions( 535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CompilationInfo* info) { 536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const CompilationInfo::InlinedFunctionList& inlined_functions = 537c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch info->inlined_functions(); 538c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (inlined_functions.size() == 0) { 539c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Handle<PodArray<InliningPosition>>::cast( 540c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch info->isolate()->factory()->empty_byte_array()); 541c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<PodArray<InliningPosition>> inl_positions = 543c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch PodArray<InliningPosition>::New( 544c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch info->isolate(), static_cast<int>(inlined_functions.size()), TENURED); 545c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (size_t i = 0; i < inlined_functions.size(); ++i) { 546c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch inl_positions->set(static_cast<int>(i), inlined_functions[i].position); 547c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 548c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return inl_positions; 549c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 550c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 551c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} // namespace 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) { 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CompilationInfo* info = this->info(); 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int deopt_count = static_cast<int>(deoptimization_states_.size()); 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (deopt_count == 0 && !info->is_osr()) return; 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DeoptimizationInputData> data = 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationInputData::New(isolate(), deopt_count, TENURED); 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ByteArray> translation_array = 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translations_.CreateByteArray(isolate()->factory()); 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetTranslationByteArray(*translation_array); 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetInlinedFunctionCount( 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Smi::FromInt(static_cast<int>(inlined_function_count_))); 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetOptimizationId(Smi::FromInt(info->optimization_id())); 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->has_shared_info()) { 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetSharedFunctionInfo(*info->shared_info()); 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch data->SetSharedFunctionInfo(Smi::kZero); 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> literals = isolate()->factory()->NewFixedArray( 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(deoptimization_literals_.size()), TENURED); 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference copy_handles; 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < deoptimization_literals_.size(); i++) { 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literals->set(i, *deoptimization_literals_[i]); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetLiteralArray(*literals); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<PodArray<InliningPosition>> inl_pos = CreateInliningPositions(info); 585c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch data->SetInliningPositions(*inl_pos); 586c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->is_osr()) { 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(osr_pc_offset_ >= 0); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId osr_ast_id = BailoutId::None(); 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrAstId(Smi::FromInt(osr_ast_id.ToInt())); 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrPcOffset(Smi::FromInt(-1)); 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Populate deoptimization entries. 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < deopt_count; i++) { 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationState* deoptimization_state = deoptimization_states_[i]; 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetAstId(i, deoptimization_state->bailout_id()); 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(deoptimization_states_[i]); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetTranslationIndex( 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i, Smi::FromInt(deoptimization_states_[i]->translation_id())); 604c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch data->SetArgumentsStackHeight(i, Smi::kZero); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset())); 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_object->set_deoptimization_data(*data); 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLabel* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) { 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jump_tables_ = new (zone()) JumpTable(jump_tables_, targets, target_count); 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return jump_tables_->label(); 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordCallPosition(Instruction* instr) { 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallDescriptor::Flags flags(MiscField::decode(instr->opcode())); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState); 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordSafepoint( 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr->reference_map(), Safepoint::kSimple, 0, 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt); 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (flags & CallDescriptor::kHasExceptionHandler) { 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperandConverter i(this, instr); 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RpoNumber handler_rpo = i.InputRpo(instr->InputCount() - 1); 630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch handlers_.push_back({GetLabel(handler_rpo), masm()->pc_offset()}); 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (needs_frame_state) { 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkLazyDeoptSite(); 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the frame state is present, it starts at argument 1 (just after the 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // code address). 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t frame_state_offset = 1; 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameStateDescriptor* descriptor = 639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetDeoptimizationEntry(instr, frame_state_offset).descriptor(); 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pc_offset = masm()->pc_offset(); 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch descriptor->state_combine()); 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the pre-call frame state differs from the post-call one, produce the 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pre-call frame state, too. 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jarin) We might want to avoid building the pre-call frame state 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // because it is only used to get locals and arguments (by the debugger and 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // f.arguments), and those are the same in the pre-call and post-call 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // states. 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!descriptor->state_combine().IsOutputIgnored()) { 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutputFrameStateCombine::Ignore()); 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = static_cast<int>(deoptimization_literals_.size()); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (deoptimization_literals_[i].is_identical_to(literal)) return i; 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_literals_.push_back(literal); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry( 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr, size_t frame_state_offset) { 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter i(this, instr); 670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int const state_id = i.InputInt32(frame_state_offset); 671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return code()->GetDeoptimizationEntry(state_id); 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochDeoptimizeKind CodeGenerator::GetDeoptimizationKind( 67562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int deoptimization_id) const { 67662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t const index = static_cast<size_t>(deoptimization_id); 67762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_LT(index, deoptimization_states_.size()); 67862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return deoptimization_states_[index]->kind(); 67962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 68062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDeoptimizeReason CodeGenerator::GetDeoptimizationReason( 682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int deoptimization_id) const { 683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t const index = static_cast<size_t>(deoptimization_id); 684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_LT(index, deoptimization_states_.size()); 685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return deoptimization_states_[index]->reason(); 686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateStateValueDescriptor( 68962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StateValueDescriptor* desc, StateValueList* nested, 69062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Translation* translation, InstructionOperandIterator* iter) { 69162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Note: 69262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // If translation is null, we just skip the relevant instruction operands. 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (desc->IsNested()) { 69462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (translation != nullptr) { 69562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation->BeginCapturedObject(static_cast<int>(nested->size())); 69662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 69762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (auto field : *nested) { 69862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch TranslateStateValueDescriptor(field.desc, field.nested, translation, 69962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch iter); 70062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 70162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (desc->IsArguments()) { 70262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (translation != nullptr) { 70362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation->BeginArgumentsObject(0); 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (desc->IsDuplicate()) { 70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (translation != nullptr) { 70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation->DuplicateObject(static_cast<int>(desc->id())); 70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 70962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (desc->IsPlain()) { 71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand* op = iter->Advance(); 71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (translation != nullptr) { 71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddTranslationForOperand(translation, iter->instruction(), op, 71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch desc->type()); 71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 71662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(desc->IsOptimizedOut()); 71762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (translation != nullptr) { 71862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (optimized_out_literal_id_ == -1) { 71962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch optimized_out_literal_id_ = 72062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DefineDeoptimizationLiteral(isolate()->factory()->optimized_out()); 72162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 72262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation->StoreLiteral(optimized_out_literal_id_); 72362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateFrameStateDescriptorOperands( 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameStateDescriptor* desc, InstructionOperandIterator* iter, 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine combine, Translation* translation) { 73162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t index = 0; 73262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StateValueList* values = desc->GetStateValueDescriptors(); 73362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (StateValueList::iterator it = values->begin(); it != values->end(); 73462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ++it, ++index) { 73562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StateValueDescriptor* value_desc = (*it).desc; 73662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (combine.kind() == OutputFrameStateCombine::kPokeAt) { 73762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The result of the call should be placed at position 73862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // [index_from_top] in the stack (overwriting whatever was 73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // previously there). 74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t index_from_top = 74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); 74262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (index >= index_from_top && 74362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch index < index_from_top + iter->instruction()->OutputCount()) { 74462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NOT_NULL(translation); 74562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddTranslationForOperand( 74662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation, iter->instruction(), 74762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch iter->instruction()->OutputAt(index - index_from_top), 74862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineType::AnyTagged()); 74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Skip the instruction operands. 75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch TranslateStateValueDescriptor(value_desc, (*it).nested, nullptr, iter); 75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch continue; 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 75462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch TranslateStateValueDescriptor(value_desc, (*it).nested, translation, iter); 75562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 75662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(desc->GetSize(OutputFrameStateCombine::Ignore()), index); 75762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 75862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (combine.kind() == OutputFrameStateCombine::kPushOutput) { 75962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); 76062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t output = 0; output < combine.GetPushCount(); output++) { 76162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Materialize the result of the call instruction in this slot. 76262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddTranslationForOperand(translation, iter->instruction(), 76362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch iter->instruction()->OutputAt(output), 76462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineType::AnyTagged()); 76562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::BuildTranslationForFrameStateDescriptor( 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, 772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Translation* translation, OutputFrameStateCombine state_combine) { 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Outer-most state must be added to translation first. 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->outer_state() != nullptr) { 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation, 777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutputFrameStateCombine::Ignore()); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared_info; 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!descriptor->shared_info().ToHandle(&shared_info)) { 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info()->has_shared_info()) { 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; // Stub with no SharedFunctionInfo. 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_info = info()->shared_info(); 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int shared_info_id = DefineDeoptimizationLiteral(shared_info); 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (descriptor->type()) { 790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kJavaScriptFunction: 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translation->BeginJSFrame( 792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch descriptor->bailout_id(), shared_info_id, 793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<unsigned int>(descriptor->GetSize(state_combine) - 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (1 + descriptor->parameters_count()))); 795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kInterpretedFunction: 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->BeginInterpretedFrame( 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch descriptor->bailout_id(), shared_info_id, 799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static_cast<unsigned int>(descriptor->locals_count() + 1)); 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kArgumentsAdaptor: 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translation->BeginArgumentsAdaptorFrame( 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_info_id, 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<unsigned int>(descriptor->parameters_count())); 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case FrameStateType::kTailCallerFunction: 8073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch translation->BeginTailCallerFrame(shared_info_id); 8083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kConstructStub: 81062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(descriptor->bailout_id().IsValidForConstructStub()); 811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->BeginConstructStubFrame( 81262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch descriptor->bailout_id(), shared_info_id, 813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<unsigned int>(descriptor->parameters_count())); 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case FrameStateType::kGetterStub: 816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch translation->BeginGetterStubFrame(shared_info_id); 817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case FrameStateType::kSetterStub: 819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch translation->BeginSetterStubFrame(shared_info_id); 820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine, 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation); 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t frame_state_offset, 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OutputFrameStateCombine state_combine) { 831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizationEntry const& entry = 832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetDeoptimizationEntry(instr, frame_state_offset); 833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FrameStateDescriptor* const descriptor = entry.descriptor(); 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_state_offset++; 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Translation translation( 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &translations_, static_cast<int>(descriptor->GetFrameCount()), 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(descriptor->GetJSFrameCount()), zone()); 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperandIterator iter(instr, frame_state_offset); 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch state_combine); 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int deoptimization_id = static_cast<int>(deoptimization_states_.size()); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_states_.push_back(new (zone()) DeoptimizationState( 84662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch descriptor->bailout_id(), translation.index(), pc_offset, entry.kind(), 847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch entry.reason())); 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return deoptimization_id; 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AddTranslationForOperand(Translation* translation, 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr, 855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* op, 856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MachineType type) { 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (op->IsStackSlot()) { 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (type.representation() == MachineRepresentation::kBit) { 859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreBoolStackSlot(LocationOperand::cast(op)->index()); 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Int8() || type == MachineType::Int16() || 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Int32()) { 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreInt32StackSlot(LocationOperand::cast(op)->index()); 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || 864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Uint32()) { 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreUint32StackSlot(LocationOperand::cast(op)->index()); 866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 86762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK_EQ(MachineRepresentation::kTagged, type.representation()); 86862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation->StoreStackSlot(LocationOperand::cast(op)->index()); 869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 870bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (op->IsFPStackSlot()) { 87113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (type.representation() == MachineRepresentation::kFloat64) { 87213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index()); 87313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 87462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK_EQ(MachineRepresentation::kFloat32, type.representation()); 87513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch translation->StoreFloatStackSlot(LocationOperand::cast(op)->index()); 87613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (op->IsRegister()) { 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter converter(this, instr); 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (type.representation() == MachineRepresentation::kBit) { 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreBoolRegister(converter.ToRegister(op)); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Int8() || type == MachineType::Int16() || 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Int32()) { 883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier translation->StoreInt32Register(converter.ToRegister(op)); 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Uint32()) { 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier translation->StoreUint32Register(converter.ToRegister(op)); 887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK_EQ(MachineRepresentation::kTagged, type.representation()); 88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translation->StoreRegister(converter.ToRegister(op)); 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 891bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (op->IsFPRegister()) { 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter converter(this, instr); 89313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (type.representation() == MachineRepresentation::kFloat64) { 89413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); 89513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 89662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK_EQ(MachineRepresentation::kFloat32, type.representation()); 89713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch translation->StoreFloatRegister(converter.ToFloatRegister(op)); 89813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK(op->IsImmediate()); 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter converter(this, instr); 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Constant constant = converter.ToConstant(op); 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant_object; 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (constant.type()) { 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Constant::kInt32: 90662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (type.representation() == MachineRepresentation::kTagged) { 907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // When pointers are 4 bytes, we can use int32 constants to represent 908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Smis. 909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(4, kPointerSize); 910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch constant_object = 911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch handle(reinterpret_cast<Smi*>(constant.ToInt32()), isolate()); 912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(constant_object->IsSmi()); 913c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (type.representation() == MachineRepresentation::kBit) { 914c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (constant.ToInt32() == 0) { 915c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch constant_object = isolate()->factory()->false_value(); 916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(1, constant.ToInt32()); 918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch constant_object = isolate()->factory()->true_value(); 919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // TODO(jarin,bmeurer): We currently pass in raw pointers to the 922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // JSFunction::entry here. We should really consider fixing this. 923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(type == MachineType::Int32() || 924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type == MachineType::Uint32() || 925c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch type.representation() == MachineRepresentation::kWord32 || 926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type.representation() == MachineRepresentation::kNone); 927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(type.representation() != MachineRepresentation::kNone || 928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch constant.ToInt32() == FrameStateDescriptor::kImpossibleValue); 92962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (type == MachineType::Uint32()) { 93062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch constant_object = 93162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate()->factory()->NewNumberFromUint(constant.ToInt32()); 93262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 93362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch constant_object = 93462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate()->factory()->NewNumberFromInt(constant.ToInt32()); 93562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case Constant::kInt64: 939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // When pointers are 8 bytes, we can use int64 constants to represent 940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Smis. 941c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // TODO(jarin,bmeurer): We currently pass in raw pointers to the 942c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // JSFunction::entry here. We should really consider fixing this. 943c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(type.representation() == MachineRepresentation::kWord64 || 94462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch type.representation() == MachineRepresentation::kTagged); 945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(8, kPointerSize); 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = 947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch handle(reinterpret_cast<Smi*>(constant.ToInt64()), isolate()); 948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(constant_object->IsSmi()); 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat32: 95162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(type.representation() == MachineRepresentation::kFloat32 || 95262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch type.representation() == MachineRepresentation::kTagged); 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant_object = isolate()->factory()->NewNumber(constant.ToFloat32()); 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Constant::kFloat64: 95662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(type.representation() == MachineRepresentation::kFloat64 || 95762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch type.representation() == MachineRepresentation::kTagged); 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = isolate()->factory()->NewNumber(constant.ToFloat64()); 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Constant::kHeapObject: 96162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(MachineRepresentation::kTagged, type.representation()); 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = constant.ToHeapObject(); 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 96562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constant_object.is_identical_to(info()->closure())) { 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreJSFrameFunction(); 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int literal_id = DefineDeoptimizationLiteral(constant_object); 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreLiteral(literal_id); 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::MarkLazyDeoptSite() { 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_lazy_deopt_pc_ = masm()->pc_offset(); 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDeoptimizationExit* CodeGenerator::AddDeoptimizationExit( 9823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Instruction* instr, size_t frame_state_offset) { 9833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int const deoptimization_id = BuildTranslation( 9843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore()); 985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DeoptimizationExit* const exit = new (zone()) 986f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DeoptimizationExit(deoptimization_id, current_source_position_); 9873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch deoptimization_exits_.push_back(exit); 9883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return exit; 9893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::OutOfLineCode(CodeGenerator* gen) 992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { 993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier gen->ools_ = this; 994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::~OutOfLineCode() {} 998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 1002