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" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator-impl.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/pipeline.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CodeGenerator::JumpTable final : public ZoneObject { 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpTable(JumpTable* next, Label** targets, size_t target_count) 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : next_(next), targets_(targets), target_count_(target_count) {} 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* label() { return &label_; } 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpTable* next() const { return next_; } 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** targets() const { return targets_; } 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t target_count() const { return target_count_; } 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label label_; 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpTable* const next_; 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** const targets_; 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const target_count_; 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionSequence* code, CompilationInfo* info) 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : frame_access_state_(new (code->zone()) FrameAccessState(frame)), 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier linkage_(linkage), 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code_(code), 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier info_(info), 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_block_(RpoNumber::Invalid()), 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_source_position_(SourcePosition::Unknown()), 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kYes), 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolver_(this), 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints_(code->zone()), 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch handlers_(code->zone()), 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_states_(code->zone()), 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_literals_(code->zone()), 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_function_count_(0), 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translations_(code->zone()), 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_lazy_deopt_pc_(0), 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jump_tables_(nullptr), 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ools_(nullptr), 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch osr_pc_offset_(-1) { 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < code->InstructionBlockCount(); ++i) { 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new (&labels_[i]) Label; 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (code->ContainsCall()) { 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame->MarkNeedsFrame(); 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> CodeGenerator::GenerateCode() { 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CompilationInfo* info = this->info(); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Open a frame scope to indicate that there is a frame on the stack. The 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // MANUAL indicates that the scope shouldn't actually generate code to set up 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the frame (that is done in AssemblePrologue). 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame_scope(masm(), StackFrame::MANUAL); 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit a code line info recording start event. 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PositionsRecorder* recorder = masm()->positions_recorder(); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Place function entry hook if requested to do so. 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProfileEntryHookStub::MaybeCallEntryHook(masm()); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Architecture-specific, linkage-specific prologue. 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->set_prologue_offset(masm()->pc_offset()); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssemblePrologue(); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define deoptimization literals for all inlined functions. 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0u, deoptimization_literals_.size()); 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto& inlined : info->inlined_functions()) { 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!inlined.shared_info.is_identical_to(info->shared_info())) { 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DefineDeoptimizationLiteral(inlined.shared_info); 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_function_count_ = deoptimization_literals_.size(); 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define deoptimization literals for all unoptimized code objects of inlined 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // functions. This ensures unoptimized code is kept alive by optimized code. 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto& inlined : info->inlined_functions()) { 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!inlined.shared_info.is_identical_to(info->shared_info())) { 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DefineDeoptimizationLiteral(inlined.inlined_code_object_root); 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assemble all non-deferred blocks, followed by deferred ones. 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int deferred = 0; deferred < 2; ++deferred) { 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto const block : code()->instruction_blocks()) { 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (block->IsDeferred() == (deferred == 0)) { 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Align loop headers on 16-byte boundaries. 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (block->IsLoopHeader()) masm()->Align(16); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensure lazy deopt doesn't patch handler entry points. 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->IsHandler()) EnsureSpaceForLazyDeopt(); 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Bind a label for a block. 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_block_ = block->rpo_number(); 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_code_comments) { 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): these code comments are a giant memory leak. 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Vector<char> buffer = Vector<char>::New(200); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch char* buffer_start = buffer.start(); 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int next = SNPrintF( 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer, "-- B%d start%s%s%s%s", block->rpo_number().ToInt(), 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->IsDeferred() ? " (deferred)" : "", 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->needs_frame() ? "" : " (no frame)", 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->must_construct_frame() ? " (construct frame)" : "", 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->must_deconstruct_frame() ? " (deconstruct frame)" : ""); 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = buffer.SubVector(next, buffer.length()); 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->IsLoopHeader()) { 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next = 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(buffer, " (loop up to %d)", block->loop_end().ToInt()); 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = buffer.SubVector(next, buffer.length()); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->loop_header().IsValid()) { 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch next = 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt()); 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = buffer.SubVector(next, buffer.length()); 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(buffer, " --"); 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->RecordComment(buffer_start); 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm()->bind(GetLabel(current_block_)); 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = block->code_start(); i < block->code_end(); ++i) { 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AssembleInstruction(code()->InstructionAt(i)); 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Assemble all out-of-line code. 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ools_) { 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm()->RecordComment("-- Out of line code --"); 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm()->bind(ool->entry()); 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ool->Generate(); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ool->exit()->is_bound()) masm()->jmp(ool->exit()); 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Ensure there is space for lazy deoptimization in the code. 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->ShouldEnsureSpaceForLazyDeopt()) { 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (masm()->pc_offset() < target_offset) { 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm()->nop(); 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FinishCode(masm()); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit the jump tables. 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (jump_tables_) { 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->Align(kPointerSize); 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (JumpTable* table = jump_tables_; table; table = table->next()) { 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->bind(table->label()); 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleJumpTable(table->targets(), table->target_count()); 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch safepoints()->Emit(masm(), frame()->GetSpillSlotCount()); 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> result = 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::internal::CodeGenerator::MakeCodeEpilogue(masm(), info); 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_is_turbofanned(true); 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_stack_slots(frame()->GetSpillSlotCount()); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_safepoint_table_offset(safepoints()->GetCodeOffset()); 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit exception handler table. 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!handlers_.empty()) { 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HandlerTable> table = 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray( 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandlerTable::LengthForReturn(static_cast<int>(handlers_.size())), 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TENURED)); 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t i = 0; i < handlers_.size(); ++i) { 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position = handlers_[i].handler->pos(); 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandlerTable::CatchPrediction prediction = handlers_[i].caught_locally 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? HandlerTable::CAUGHT 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : HandlerTable::UNCAUGHT; 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch table->SetReturnOffset(static_cast<int>(i), handlers_[i].pc_offset); 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch table->SetReturnHandler(static_cast<int>(i), position, prediction); 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result->set_handler_table(*table); 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopulateDeoptimizationData(result); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Ensure there is space for lazy deoptimization in the relocation info. 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->ShouldEnsureSpaceForLazyDeopt()) { 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result); 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit a code line info recording stop event. 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* line_info = recorder->DetachJITHandlerData(); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info)); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code() 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->InstructionBlockAt(current_block_) 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->ao_number() 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch .IsNext(code()->InstructionBlockAt(block)->ao_number()); 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordSafepoint(ReferenceMap* references, 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Safepoint::Kind kind, int arguments, 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::DeoptMode deopt_mode) { 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint safepoint = 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode); 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int stackSlotToSpillSlotDelta = 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount(); 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto& operand : references->reference_operands()) { 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (operand.IsStackSlot()) { 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int index = LocationOperand::cast(operand).index(); 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(index >= 0); 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Safepoint table indices are 0-based from the beginning of the spill 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // slot area, adjust appropriately. 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch index -= stackSlotToSpillSlotDelta; 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch safepoint.DefinePointerSlot(index, zone()); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) { 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = LocationOperand::cast(operand).GetRegister(); 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoint.DefinePointerRegister(reg, zone()); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object, 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int* offset_return) { 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info()->has_context() && object.is_identical_to(info()->context()) && 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !info()->is_osr()) { 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *offset_return = StandardFrameConstants::kContextOffset; 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (object.is_identical_to(info()->closure())) { 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *offset_return = JavaScriptFrameConstants::kFunctionOffset; 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsMaterializableFromRoot( 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> object, Heap::RootListIndex* index_return) { 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallDescriptor* incoming_descriptor = 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch linkage()->GetIncomingDescriptor(); 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (incoming_descriptor->flags() & CallDescriptor::kCanUseRoots) { 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RootIndexMap map(isolate()); 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int root_index = map.Lookup(*object); 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (root_index != RootIndexMap::kInvalidRootIndex) { 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *index_return = static_cast<Heap::RootListIndex>(root_index); 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleInstruction(Instruction* instr) { 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleGaps(instr); 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleSourcePosition(instr); 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assemble architecture-specific code for the instruction. 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchInstruction(instr); 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsMode mode = FlagsModeField::decode(instr->opcode()); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kFlags_branch) { 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assemble a branch after this instruction. 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperandConverter i(this, instr); 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2); 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1); 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (true_rpo == false_rpo) { 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // redundant branch. 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsNextInAssemblyOrder(true_rpo)) { 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchJump(true_rpo); 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsNextInAssemblyOrder(true_rpo)) { 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // true block is next, can fall through if condition negated. 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::swap(true_rpo, false_rpo); 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch condition = NegateFlagsCondition(condition); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchInfo branch; 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch branch.condition = condition; 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch branch.true_label = GetLabel(true_rpo); 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch branch.false_label = GetLabel(false_rpo); 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch branch.fallthru = IsNextInAssemblyOrder(false_rpo); 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assemble architecture-specific branch. 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchBranch(instr, &branch); 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == kFlags_set) { 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assemble a boolean materialization after this instruction. 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchBoolean(instr, condition); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSourcePosition(Instruction* instr) { 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition source_position; 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!code()->GetSourcePosition(instr, &source_position)) return; 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (source_position == current_source_position_) return; 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current_source_position_ = source_position; 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source_position.IsUnknown()) return; 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int code_pos = source_position.raw(); 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->positions_recorder()->RecordPosition(code_pos); 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->positions_recorder()->WriteRecordedPositions(); 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_code_comments) { 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Vector<char> buffer = Vector<char>::New(256); 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationInfo* info = this->info(); 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int ln = Script::GetLineNumber(info->script(), code_pos); 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int cn = Script::GetColumnNumber(info->script(), code_pos); 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->script()->name()->IsString()) { 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> file(String::cast(info->script()->name())); 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::OS::SNPrintF(buffer.start(), buffer.length(), "-- %s:%d:%d --", 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch file->ToCString().get(), ln, cn); 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::OS::SNPrintF(buffer.start(), buffer.length(), 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "-- <unknown>:%d:%d --", ln, cn); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()->RecordComment(buffer.start()); 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleGaps(Instruction* instr) { 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = Instruction::FIRST_GAP_POSITION; 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i <= Instruction::LAST_GAP_POSITION; i++) { 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction::GapPosition inner_pos = 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<Instruction::GapPosition>(i); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ParallelMove* move = instr->GetParallelMove(inner_pos); 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (move != nullptr) resolver()->Resolve(move); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) { 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CompilationInfo* info = this->info(); 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int deopt_count = static_cast<int>(deoptimization_states_.size()); 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (deopt_count == 0 && !info->is_osr()) return; 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DeoptimizationInputData> data = 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationInputData::New(isolate(), deopt_count, TENURED); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ByteArray> translation_array = 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translations_.CreateByteArray(isolate()->factory()); 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetTranslationByteArray(*translation_array); 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetInlinedFunctionCount( 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Smi::FromInt(static_cast<int>(inlined_function_count_))); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetOptimizationId(Smi::FromInt(info->optimization_id())); 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->has_shared_info()) { 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetSharedFunctionInfo(*info->shared_info()); 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetSharedFunctionInfo(Smi::FromInt(0)); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> literals = isolate()->factory()->NewFixedArray( 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(deoptimization_literals_.size()), TENURED); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference copy_handles; 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < deoptimization_literals_.size(); i++) { 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literals->set(i, *deoptimization_literals_[i]); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetLiteralArray(*literals); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->is_osr()) { 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(osr_pc_offset_ >= 0); 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId osr_ast_id = BailoutId::None(); 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrAstId(Smi::FromInt(osr_ast_id.ToInt())); 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data->SetOsrPcOffset(Smi::FromInt(-1)); 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Populate deoptimization entries. 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < deopt_count; i++) { 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationState* deoptimization_state = deoptimization_states_[i]; 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetAstId(i, deoptimization_state->bailout_id()); 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(deoptimization_states_[i]); 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetTranslationIndex( 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i, Smi::FromInt(deoptimization_states_[i]->translation_id())); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetArgumentsStackHeight(i, Smi::FromInt(0)); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset())); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_object->set_deoptimization_data(*data); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLabel* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) { 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jump_tables_ = new (zone()) JumpTable(jump_tables_, targets, target_count); 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return jump_tables_->label(); 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordCallPosition(Instruction* instr) { 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallDescriptor::Flags flags(MiscField::decode(instr->opcode())); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordSafepoint( 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr->reference_map(), Safepoint::kSimple, 0, 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (flags & CallDescriptor::kHasExceptionHandler) { 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperandConverter i(this, instr); 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool caught = flags & CallDescriptor::kHasLocalCatchHandler; 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RpoNumber handler_rpo = i.InputRpo(instr->InputCount() - 1); 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch handlers_.push_back({caught, GetLabel(handler_rpo), masm()->pc_offset()}); 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (flags & CallDescriptor::kNeedsNopAfterCall) { 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddNopForSmiCodeInlining(); 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (needs_frame_state) { 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MarkLazyDeoptSite(); 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the frame state is present, it starts at argument 1 (just after the 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // code address). 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t frame_state_offset = 1; 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameStateDescriptor* descriptor = 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetFrameStateDescriptor(instr, frame_state_offset); 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pc_offset = masm()->pc_offset(); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch descriptor->state_combine()); 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the pre-call frame state differs from the post-call one, produce the 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pre-call frame state, too. 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jarin) We might want to avoid building the pre-call frame state 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // because it is only used to get locals and arguments (by the debugger and 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // f.arguments), and those are the same in the pre-call and post-call 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // states. 457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!descriptor->state_combine().IsOutputIgnored()) { 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutputFrameStateCombine::Ignore()); 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure all the values live in stack slots or they are immediates. 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (The values should not live in register because registers are clobbered 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // by calls.) 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < descriptor->GetSize(); i++) { 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(op->IsStackSlot() || op->IsDoubleStackSlot() || op->IsImmediate()); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = static_cast<int>(deoptimization_literals_.size()); 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (deoptimization_literals_[i].is_identical_to(literal)) return i; 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_literals_.push_back(literal); 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr, size_t frame_state_offset) { 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter i(this, instr); 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionSequence::StateId state_id = 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code()->GetFrameStateDescriptor(state_id); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateStateValueDescriptor( 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StateValueDescriptor* desc, Translation* translation, 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperandIterator* iter) { 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (desc->IsNested()) { 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->BeginCapturedObject(static_cast<int>(desc->size())); 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 0; index < desc->fields().size(); index++) { 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (desc->IsDuplicate()) { 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->DuplicateObject(static_cast<int>(desc->id())); 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(desc->IsPlain()); 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->type()); 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateFrameStateDescriptorOperands( 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameStateDescriptor* desc, InstructionOperandIterator* iter, 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine combine, Translation* translation) { 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 0; index < desc->GetSize(combine); index++) { 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (combine.kind()) { 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case OutputFrameStateCombine::kPushOutput: { 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t size_without_output = 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->GetSize(OutputFrameStateCombine::Ignore()); 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the index is past the existing stack items in values_. 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index >= size_without_output) { 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Materialize the result of the call instruction in this slot. 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddTranslationForOperand( 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation, iter->instruction(), 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter->instruction()->OutputAt(index - size_without_output), 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::AnyTagged()); 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch continue; 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case OutputFrameStateCombine::kPokeAt: 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The result of the call should be placed at position 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [index_from_top] in the stack (overwriting whatever was 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // previously there). 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index_from_top = 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index >= index_from_top && 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch index < index_from_top + iter->instruction()->OutputCount()) { 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddTranslationForOperand( 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation, iter->instruction(), 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter->instruction()->OutputAt(index - index_from_top), 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::AnyTagged()); 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter->Advance(); // We do not use this input, but we need to 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // advace, as the input got replaced. 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch continue; 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslateStateValueDescriptor(&value_desc->fields()[index], translation, 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter); 553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::BuildTranslationForFrameStateDescriptor( 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Translation* translation, OutputFrameStateCombine state_combine) { 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Outer-most state must be added to translation first. 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->outer_state() != nullptr) { 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation, 564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutputFrameStateCombine::Ignore()); 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared_info; 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!descriptor->shared_info().ToHandle(&shared_info)) { 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info()->has_shared_info()) { 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; // Stub with no SharedFunctionInfo. 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_info = info()->shared_info(); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int shared_info_id = DefineDeoptimizationLiteral(shared_info); 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (descriptor->type()) { 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kJavaScriptFunction: 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translation->BeginJSFrame( 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch descriptor->bailout_id(), shared_info_id, 580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<unsigned int>(descriptor->GetSize(state_combine) - 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (1 + descriptor->parameters_count()))); 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kInterpretedFunction: 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->BeginInterpretedFrame( 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch descriptor->bailout_id(), shared_info_id, 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<unsigned int>(descriptor->locals_count())); 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kArgumentsAdaptor: 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translation->BeginArgumentsAdaptorFrame( 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_info_id, 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<unsigned int>(descriptor->parameters_count())); 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FrameStateType::kConstructStub: 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->BeginConstructStubFrame( 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_info_id, 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<unsigned int>(descriptor->parameters_count())); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine, 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t frame_state_offset, 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OutputFrameStateCombine state_combine) { 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameStateDescriptor* descriptor = 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetFrameStateDescriptor(instr, frame_state_offset); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_state_offset++; 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Translation translation( 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &translations_, static_cast<int>(descriptor->GetFrameCount()), 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(descriptor->GetJSFrameCount()), zone()); 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperandIterator iter(instr, frame_state_offset); 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch state_combine); 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int deoptimization_id = static_cast<int>(deoptimization_states_.size()); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_states_.push_back(new (zone()) DeoptimizationState( 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch descriptor->bailout_id(), translation.index(), pc_offset)); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return deoptimization_id; 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AddTranslationForOperand(Translation* translation, 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr, 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* op, 631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MachineType type) { 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (op->IsStackSlot()) { 633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (type.representation() == MachineRepresentation::kBit) { 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreBoolStackSlot(LocationOperand::cast(op)->index()); 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Int8() || type == MachineType::Int16() || 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Int32()) { 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreInt32StackSlot(LocationOperand::cast(op)->index()); 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Uint32()) { 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreUint32StackSlot(LocationOperand::cast(op)->index()); 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type.representation() == MachineRepresentation::kTagged) { 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreStackSlot(LocationOperand::cast(op)->index()); 643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(false); 645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (op->IsDoubleStackSlot()) { 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFloatingPoint(type.representation())); 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index()); 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (op->IsRegister()) { 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter converter(this, instr); 651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (type.representation() == MachineRepresentation::kBit) { 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreBoolRegister(converter.ToRegister(op)); 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Int8() || type == MachineType::Int16() || 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Int32()) { 655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier translation->StoreInt32Register(converter.ToRegister(op)); 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type == MachineType::Uint32()) { 658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier translation->StoreUint32Register(converter.ToRegister(op)); 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (type.representation() == MachineRepresentation::kTagged) { 660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier translation->StoreRegister(converter.ToRegister(op)); 661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(false); 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (op->IsDoubleRegister()) { 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFloatingPoint(type.representation())); 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter converter(this, instr); 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (op->IsImmediate()) { 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandConverter converter(this, instr); 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Constant constant = converter.ToConstant(op); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant_object; 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (constant.type()) { 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Constant::kInt32: 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(type == MachineType::Int32() || type == MachineType::Uint32() || 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type.representation() == MachineRepresentation::kBit); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewNumberFromInt(constant.ToInt32()); 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat32: 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(type.representation() == MachineRepresentation::kFloat32 || 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type.representation() == MachineRepresentation::kTagged); 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant_object = isolate()->factory()->NewNumber(constant.ToFloat32()); 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Constant::kFloat64: 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(type.representation() == MachineRepresentation::kFloat64 || 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type.representation() == MachineRepresentation::kTagged); 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = isolate()->factory()->NewNumber(constant.ToFloat64()); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Constant::kHeapObject: 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(type.representation() == MachineRepresentation::kTagged); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = constant.ToHeapObject(); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(false); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constant_object.is_identical_to(info()->closure())) { 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreJSFrameFunction(); 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int literal_id = DefineDeoptimizationLiteral(constant_object); 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translation->StoreLiteral(literal_id); 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(false); 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::MarkLazyDeoptSite() { 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_lazy_deopt_pc_ = masm()->pc_offset(); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int spill_slots = frame()->GetSpillSlotCount(); 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Leave the PC on the stack on platforms that have that as part of their ABI 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int sp_slot_delta = 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0; 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Discard only slots that won't be used by new parameters. 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sp_slot_delta += stack_param_delta; 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return sp_slot_delta; 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::OutOfLineCode(CodeGenerator* gen) 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { 729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier gen->ools_ = this; 730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::~OutOfLineCode() {} 734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 738