13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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#if V8_TARGET_ARCH_IA32 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ia32/frames-ia32.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h" 13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochconst int Deoptimizer::table_entry_size_ = 10; 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockint Deoptimizer::patch_size() { 211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return Assembler::kCallInstructionLength; 221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { 2644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = code->GetIsolate(); 2744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate); 2844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Compute the size of relocation information needed for the code 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // patching in Deoptimizer::PatchCodeForDeoptimization below. 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int min_reloc_size = 0; 322b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int prev_pc_offset = 0; 332b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch DeoptimizationInputData* deopt_data = 342b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch DeoptimizationInputData::cast(code->deoptimization_data()); 352b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch for (int i = 0; i < deopt_data->DeoptCount(); i++) { 362b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int pc_offset = deopt_data->Pc(i)->value(); 372b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch if (pc_offset == -1) continue; 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(pc_offset, prev_pc_offset); 392b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int pc_delta = pc_offset - prev_pc_offset; 402b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes 412b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // if encodable with small pc delta encoding and up to 6 bytes 422b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // otherwise. 432b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch if (pc_delta <= RelocInfo::kMaxSmallPCDelta) { 442b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch min_reloc_size += 2; 452b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch } else { 462b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch min_reloc_size += 6; 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 482b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch prev_pc_offset = pc_offset; 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // If the relocation information is not big enough we create a new 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // relocation info object that is padded with comments to make it 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // big enough for lazy doptimization. 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block int reloc_length = code->relocation_info()->length(); 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_reloc_size > reloc_length) { 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block int comment_reloc_size = RelocInfo::kMinRelocCommentSize; 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Padding needed. 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block int min_padding = min_reloc_size - reloc_length; 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Number of comments needed to take up at least that much space. 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block int additional_comments = 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block (min_padding + comment_reloc_size - 1) / comment_reloc_size; 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Actual padding size. 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block int padding = additional_comments * comment_reloc_size; 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Allocate new relocation info and copy old relocation to the end 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // of the new relocation info array because relocation info is 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // written and read backwards. 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate->factory(); 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<ByteArray> new_reloc = 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block factory->NewByteArray(reloc_length + padding, TENURED); 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemCopy(new_reloc->GetDataStartAddress() + padding, 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->relocation_info()->GetDataStartAddress(), reloc_length); 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Create a relocation writer to write the comments in the padding 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // space. Use position 0 for everything to ensure short encoding. 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block RelocInfoWriter reloc_info_writer( 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block new_reloc->GetDataStartAddress() + padding, 0); 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t comment_string 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo rinfo(isolate, 0, RelocInfo::COMMENT, comment_string, NULL); 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < additional_comments; ++i) { 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block byte* pos_before = reloc_info_writer.pos(); 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block reloc_info_writer.Write(&rinfo); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::kMinRelocCommentSize == 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block pos_before - reloc_info_writer.pos()); 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Replace relocation information on the code object. 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block code->set_relocation_info(*new_reloc); 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { 941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Address code_start_address = code->instruction_start(); 951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_zap_code_space) { 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fail hard and early if we enter this code object again. 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte* pointer = code->FindCodeAgeSequence(); 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pointer != NULL) { 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pointer += kNoCodeAgeSequenceLength; 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pointer = code->instruction_start(); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodePatcher patcher(isolate, pointer, 1); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch patcher.masm()->int3(); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationInputData* data = 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationInputData::cast(code->deoptimization_data()); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int osr_offset = data->OsrPcOffset()->value(); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (osr_offset > 0) { 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_patcher.masm()->int3(); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // We will overwrite the code's relocation info in-place. Relocation info 1181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // is written backward. The relocation info is the payload of a byte 1191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // array. Later on we will slide this to the start of the byte array and 1201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // create a filler object in the remaining space. 1211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ByteArray* reloc_info = code->relocation_info(); 1221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Address reloc_end_address = reloc_info->address() + reloc_info->Size(); 1231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block RelocInfoWriter reloc_info_writer(reloc_end_address, code_start_address); 1241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1252b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // Since the call is a relative encoding, write new 1261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // reloc info. We do not need any of the existing reloc info because the 1271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // existing code will not be used again (we zap it in debug builds). 1282b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // 1292b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // Emit call to lazy deoptimization at all lazy deopt points. 1302b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch DeoptimizationInputData* deopt_data = 1312b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch DeoptimizationInputData::cast(code->deoptimization_data()); 1322b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch#ifdef DEBUG 1332b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Address prev_call_address = NULL; 1342b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch#endif 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For each LLazyBailout instruction insert a call to the corresponding 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deoptimization entry. 1372b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch for (int i = 0; i < deopt_data->DeoptCount(); i++) { 1382b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch if (deopt_data->Pc(i)->value() == -1) continue; 1392b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // Patch lazy deoptimization entry. 1402b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Address call_address = code_start_address + deopt_data->Pc(i)->value(); 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodePatcher patcher(isolate, call_address, patch_size()); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch patcher.masm()->call(deopt_entry, RelocInfo::NONE32); 1442b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch // We use RUNTIME_ENTRY for deoptimization bailouts. 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo rinfo(isolate, call_address + 1, // 1 after the call opcode. 1462b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch RelocInfo::RUNTIME_ENTRY, 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<intptr_t>(deopt_entry), NULL); 1482b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch reloc_info_writer.Write(&rinfo); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(reloc_info_writer.pos(), 1502b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch reloc_info->address() + ByteArray::kHeaderSize); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prev_call_address == NULL || 1522b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch call_address >= prev_call_address + patch_size()); 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_address + patch_size() <= code->instruction_end()); 1542b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch#ifdef DEBUG 1552b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch prev_call_address = call_address; 1562b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch#endif 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Move the relocation info to the beginning of the byte array. 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int new_reloc_length = reloc_end_address - reloc_info_writer.pos(); 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemMove(code->relocation_start(), reloc_info_writer.pos(), new_reloc_length); 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Right trim the relocation info to free up remaining space. 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int delta = reloc_info->length() - new_reloc_length; 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (delta > 0) { 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->heap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reloc_info, delta); 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set the register values. The values are not important as there are no 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // callee saved registers in JavaScript frames, so all registers are 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // spilled. Registers ebp and esp are set to the correct values though. 1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < Register::kNumRegisters; i++) { 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch input_->SetRegister(i, i * 4); 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp())); 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp())); 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch input_->SetDoubleRegister(i, 0.0); 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Fill the frame content from the actual data on the frame. 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 1883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::SetPlatformCompiledStubRegisters( 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameDescription* output_frame, CodeStubDescriptor* descriptor) { 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t handler = 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t>(descriptor->deoptimization_handler()); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int params = descriptor->GetHandlerParameterCount(); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch output_frame->SetRegister(eax.code(), params); 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch output_frame->SetRegister(ebx.code(), handler); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; ++i) { 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double double_value = input_->GetDoubleRegister(i); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch output_frame->SetDoubleRegister(i, double_value); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Deoptimizer::HasAlignmentPadding(JSFunction* function) { 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parameter_count = 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->shared()->internal_formal_parameter_count() + 1; 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned input_frame_size = input_->GetFrameSize(); 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned alignment_state_offset = 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_frame_size - parameter_count * kPointerSize - 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StandardFrameConstants::kFixedFrameSize - 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointerSize; 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(JavaScriptFrameConstants::kDynamicAlignmentStateOffset == 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JavaScriptFrameConstants::kLocal0Offset); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset); 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (alignment_state == kAlignmentPaddingPushed); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define __ masm()-> 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Deoptimizer::TableEntryGenerator::Generate() { 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GeneratePrologue(); 23044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Save all general purpose registers before messing with them. 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int kNumberOfRegisters = Register::kNumRegisters; 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kDoubleRegsSize = kDoubleSize * XMMRegister::kMaxNumRegisters; 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(esp, Immediate(kDoubleRegsSize)); 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegisterConfiguration* config = 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int code = config->GetAllocatableDoubleCode(i); 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister xmm_reg = XMMRegister::from_code(code); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = code * kDoubleSize; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(Operand(esp, offset), xmm_reg); 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ pushad(); 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(Operand::StaticVariable(c_entry_fp_address), ebp); 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize + 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kDoubleRegsSize; 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the bailout id from the stack. 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(ebx, Operand(esp, kSavedRegistersAreaSize)); 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the address of the location in the code object 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and compute the fp-to-sp delta in register edx. 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ecx, Operand(esp, kSavedRegistersAreaSize + 1 * kPointerSize)); 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lea(edx, Operand(esp, kSavedRegistersAreaSize + 2 * kPointerSize)); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(edx, ebp); 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ neg(edx); 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Allocate a new deoptimizer object. 2658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch __ PrepareCallCFunction(6, eax); 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(Operand(esp, 0 * kPointerSize), eax); // Function. 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(Operand(esp, 1 * kPointerSize), Immediate(type())); // Bailout type. 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(Operand(esp, 2 * kPointerSize), ebx); // Bailout id. 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(Operand(esp, 3 * kPointerSize), ecx); // Code address or 0. 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(Operand(esp, 4 * kPointerSize), edx); // Fp-to-sp delta. 2728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch __ mov(Operand(esp, 5 * kPointerSize), 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(ExternalReference::isolate_address(isolate()))); 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllowExternalCallThatCantCauseGC scope(masm()); 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Preserve deoptimizer object in register eax and get the input 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // frame descriptor pointer. 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(ebx, Operand(eax, Deoptimizer::input_offset())); 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fill in the input registers. 2841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 2851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block __ pop(Operand(ebx, offset)); 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int double_regs_offset = FrameDescription::double_registers_offset(); 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fill in the double input registers. 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int code = config->GetAllocatableDoubleCode(i); 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int dst_offset = code * kDoubleSize + double_regs_offset; 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int src_offset = code * kDoubleSize; 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(xmm0, Operand(esp, src_offset)); 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(Operand(ebx, dst_offset), xmm0); 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clear FPU all exceptions. 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(ulan): Find out why the TOP register is not zero here in some cases, 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and check that the generated code never deoptimizes with unbalanced stack. 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fnclex(); 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove the bailout id, return address and the double registers. 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize)); 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compute a pointer to the unwinding limit in register ecx; that is 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the first stack slot not part of the input frame. 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add(ecx, esp); 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Unwind the stack down to - but not including - the unwinding 313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // limit and copy the contents of the activation frame to the input 314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // frame description. 315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label pop_loop_header; 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&pop_loop_header); 318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label pop_loop; 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&pop_loop); 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ pop(Operand(edx, 0)); 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add(edx, Immediate(sizeof(uint32_t))); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&pop_loop_header); 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(ecx, esp); 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ j(not_equal, &pop_loop); 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compute the output frame in the deoptimizer. 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ push(eax); 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ PrepareCallCFunction(1, ebx); 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(Operand(esp, 0 * kPointerSize), eax); 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllowExternalCallThatCantCauseGC scope(masm()); 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallCFunction( 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::compute_output_frames_function(isolate()), 1); 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ pop(eax); 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If frame was dynamically aligned, pop padding. 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label no_padding; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(0)); 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ j(equal, &no_padding); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pop(ecx); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cmp(ecx, Immediate(kAlignmentZapValue)); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Assert(equal, kAlignmentMarkerExpected); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&no_padding); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Replace the current frame with the output frames. 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label outer_push_loop, inner_push_loop, 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_loop_header, inner_loop_header; 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Outer loop state: eax = current FrameDescription**, edx = one past the 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // last FrameDescription**. 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(eax, Operand(eax, Deoptimizer::output_offset())); 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ lea(edx, Operand(eax, edx, times_4, 0)); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&outer_loop_header); 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&outer_push_loop); 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Inner loop state: ebx = current FrameDescription*, ecx = loop index. 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(ebx, Operand(eax, 0)); 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&inner_loop_header); 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&inner_push_loop); 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(ecx, Immediate(sizeof(uint32_t))); 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset())); 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&inner_loop_header); 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ test(ecx, ecx); 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ j(not_zero, &inner_push_loop); 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add(eax, Immediate(kPointerSize)); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&outer_loop_header); 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(eax, edx); 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ j(below, &outer_push_loop); 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In case of a failed STUB, we have to restore the XMM registers. 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int code = config->GetAllocatableDoubleCode(i); 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister xmm_reg = XMMRegister::from_code(code); 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int src_offset = code * kDoubleSize + double_regs_offset; 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(xmm_reg, Operand(ebx, src_offset)); 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Push state, pc, and continuation from the last output frame. 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(Operand(ebx, FrameDescription::state_offset())); 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ push(Operand(ebx, FrameDescription::pc_offset())); 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ push(Operand(ebx, FrameDescription::continuation_offset())); 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Push the registers from the last output frame. 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < kNumberOfRegisters; i++) { 3901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ push(Operand(ebx, offset)); 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Restore the registers from the stack. 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ popad(); 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return to the continuation point. 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ ret(0); 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Deoptimizer::TableEntryGenerator::GeneratePrologue() { 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a sequence of deoptimization entries. 404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label done; 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < count(); i++) { 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int start = masm()->pc_offset(); 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch USE(start); 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ push_imm32(i); 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&done); 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm()->pc_offset() - start == table_entry_size_); 411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&done); 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetFrameSlot(offset, value); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetFrameSlot(offset, value); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No embedded constant pool support. 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef __ 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 437b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 438b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif // V8_TARGET_ARCH_IA32 439