1659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without 3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are 4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met: 5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// * Redistributions of source code must retain the above copyright 7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// notice, this list of conditions and the following disclaimer. 8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// * Redistributions in binary form must reproduce the above 9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// copyright notice, this list of conditions and the following 10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// disclaimer in the documentation and/or other materials provided 11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// with the distribution. 12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// * Neither the name of Google Inc. nor the names of its 13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// contributors may be used to endorse or promote products derived 14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// from this software without specific prior written permission. 15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "v8.h" 29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "codegen.h" 31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h" 32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "full-codegen.h" 33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "safepoint-table.h" 34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 { 36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal { 37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 38169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgconst int Deoptimizer::table_entry_size_ = 12; 39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 4131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.orgint Deoptimizer::patch_size() { 4231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org const int kCallInstructionSizeInWords = 3; 4331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return kCallInstructionSizeInWords * Assembler::kInstrSize; 4431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 4531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 4631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 47fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { 4827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Address code_start_address = code->instruction_start(); 49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Invalidate the relocation information, as it will become invalid by the 50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // code patching below, and is not needed any more. 51a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org code->InvalidateRelocation(); 52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // For each LLazyBailout instruction insert a call to the corresponding 5427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // deoptimization entry. 5527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org DeoptimizationInputData* deopt_data = 5627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org DeoptimizationInputData::cast(code->deoptimization_data()); 57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG 5827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Address prev_call_address = NULL; 59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 6027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org for (int i = 0; i < deopt_data->DeoptCount(); i++) { 6127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org if (deopt_data->Pc(i)->value() == -1) continue; 6227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Address call_address = code_start_address + deopt_data->Pc(i)->value(); 638432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); 64471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // We need calls to have a predictable size in the unoptimized code, but 65471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // this is optimized code, so we don't have to have a predictable size. 66471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org int call_size_in_bytes = 67471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org MacroAssembler::CallSizeNotPredictableCodeSize(deopt_entry, 6859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org RelocInfo::NONE32); 6927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; 7027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); 7127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(call_size_in_bytes <= patch_size()); 7227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org CodePatcher patcher(call_address, call_size_in_words); 7359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org patcher.masm()->Call(deopt_entry, RelocInfo::NONE32); 7427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(prev_call_address == NULL || 7527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org call_address >= prev_call_address + patch_size()); 7627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(call_address + patch_size() <= code->instruction_end()); 77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG 7827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org prev_call_address = call_address; 79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 8027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgstatic const int32_t kBranchBeforeInterrupt = 0x5a000004; 8588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org 86e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// The back edge bookkeeping code matches the pattern: 87e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 88e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// <decrement profiling counter> 89e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 2a 00 00 01 bpl ok 90e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// e5 9f c? ?? ldr ip, [pc, <interrupt stub address>] 91e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// e1 2f ff 3c blx ip 92e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// ok-label 93e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 94e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// We patch the code to the following form: 95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 96e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// <decrement profiling counter> 97e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// e1 a0 00 00 mov r0, r0 (NOP) 98e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// e5 9f c? ?? ldr ip, [pc, <on-stack replacement address>] 99e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// e1 2f ff 3c blx ip 100e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// ok-label 101e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 102e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Deoptimizer::PatchInterruptCodeAt(Code* unoptimized_code, 103e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Address pc_after, 104e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Code* interrupt_code, 105e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Code* replacement_code) { 106e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!InterruptCodeIsPatched(unoptimized_code, 107e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pc_after, 108e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org interrupt_code, 109e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org replacement_code)); 110e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static const int kInstrSize = Assembler::kInstrSize; 111e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Turn the jump into nops. 11249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org CodePatcher patcher(pc_after - 3 * kInstrSize, 1); 11349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org patcher.masm()->nop(); 114e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Replace the call address. 115e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t interrupt_address_offset = Memory::uint16_at(pc_after - 11649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 2 * kInstrSize) & 0xfff; 117e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Address interrupt_address_pointer = pc_after + interrupt_address_offset; 118e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::uint32_at(interrupt_address_pointer) = 11949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org reinterpret_cast<uint32_t>(replacement_code->entry()); 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 121394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( 122394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com unoptimized_code, pc_after - 2 * kInstrSize, replacement_code); 123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 126e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Deoptimizer::RevertInterruptCodeAt(Code* unoptimized_code, 127e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Address pc_after, 128e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Code* interrupt_code, 129e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Code* replacement_code) { 130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(InterruptCodeIsPatched(unoptimized_code, 131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pc_after, 132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org interrupt_code, 133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org replacement_code)); 134e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static const int kInstrSize = Assembler::kInstrSize; 135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Restore the original jump. 136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CodePatcher patcher(pc_after - 3 * kInstrSize, 1); 137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org patcher.masm()->b(4 * kInstrSize, pl); // ok-label is 4 instructions later. 138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT_EQ(kBranchBeforeInterrupt, 139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::int32_at(pc_after - 3 * kInstrSize)); 140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Restore the original call address. 141e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t interrupt_address_offset = Memory::uint16_at(pc_after - 142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 2 * kInstrSize) & 0xfff; 143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Address interrupt_address_pointer = pc_after + interrupt_address_offset; 144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::uint32_at(interrupt_address_pointer) = 145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reinterpret_cast<uint32_t>(interrupt_code->entry()); 146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 147e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( 148e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org unoptimized_code, pc_after - 2 * kInstrSize, interrupt_code); 149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef DEBUG 153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool Deoptimizer::InterruptCodeIsPatched(Code* unoptimized_code, 154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Address pc_after, 155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Code* interrupt_code, 15631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org Code* replacement_code) { 157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static const int kInstrSize = Assembler::kInstrSize; 15888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org ASSERT(Memory::int32_at(pc_after - kInstrSize) == kBlxIp); 15949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t interrupt_address_offset = 161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::uint16_at(pc_after - 2 * kInstrSize) & 0xfff; 162e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Address interrupt_address_pointer = pc_after + interrupt_address_offset; 16349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 164e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (Assembler::IsNop(Assembler::instr_at(pc_after - 3 * kInstrSize))) { 165e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(Assembler::IsLdrPcImmediateOffset( 166e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Assembler::instr_at(pc_after - 2 * kInstrSize))); 167e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(reinterpret_cast<uint32_t>(replacement_code->entry()) == 168e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::uint32_at(interrupt_address_pointer)); 169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 171e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(Assembler::IsLdrPcImmediateOffset( 172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Assembler::instr_at(pc_after - 2 * kInstrSize))); 173e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT_EQ(kBranchBeforeInterrupt, 174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::int32_at(pc_after - 3 * kInstrSize)); 175e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(reinterpret_cast<uint32_t>(interrupt_code->entry()) == 176e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Memory::uint32_at(interrupt_address_pointer)); 177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return false; 178e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 180e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // DEBUG 181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 183471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgstatic int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) { 184496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ByteArray* translations = data->TranslationByteArray(); 185496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int length = data->DeoptCount(); 186496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org for (int i = 0; i < length; i++) { 187471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (data->AstId(i) == ast_id) { 188496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org TranslationIterator it(translations, data->TranslationIndex(i)->value()); 189496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int value = it.Next(); 190496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value)); 191496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Read the number of frames. 192496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org value = it.Next(); 193496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org if (value == 1) return i; 194496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 195496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 196496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org UNREACHABLE(); 197496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org return -1; 198496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org} 199496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 200496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::DoComputeOsrOutputFrame() { 202496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org DeoptimizationInputData* data = DeoptimizationInputData::cast( 203a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org compiled_code_->deoptimization_data()); 204496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned ast_id = data->OsrAstId()->value(); 205496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 206471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org int bailout_id = LookupBailoutId(data, BailoutId(ast_id)); 207496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned translation_index = data->TranslationIndex(bailout_id)->value(); 208496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ByteArray* translations = data->TranslationByteArray(); 209496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 210496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org TranslationIterator iterator(translations, translation_index); 211496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Translation::Opcode opcode = 212496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static_cast<Translation::Opcode>(iterator.Next()); 213496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(Translation::BEGIN == opcode); 214496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org USE(opcode); 215496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int count = iterator.Next(); 216659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org iterator.Skip(1); // Drop JS frame count. 217496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(count == 1); 218496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org USE(count); 219496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 220496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org opcode = static_cast<Translation::Opcode>(iterator.Next()); 221496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org USE(opcode); 222659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ASSERT(Translation::JS_FRAME == opcode); 223496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned node_id = iterator.Next(); 224496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org USE(node_id); 225496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(node_id == ast_id); 2265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int closure_id = iterator.Next(); 2275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org USE(closure_id); 2285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 229496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned height = iterator.Next(); 230496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned height_in_bytes = height * kPointerSize; 231496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org USE(height_in_bytes); 232496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 233496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned fixed_size = ComputeFixedSize(function_); 234496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned input_frame_size = input_->GetFrameSize(); 235496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(fixed_size + height_in_bytes == input_frame_size); 236496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 237a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize; 238496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value(); 239496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned outgoing_size = outgoing_height * kPointerSize; 240496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size; 241496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call. 242496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 243496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org if (FLAG_trace_osr) { 244496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ", 245496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org reinterpret_cast<intptr_t>(function_)); 2464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org PrintFunctionName(); 247496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org PrintF(" => node=%u, frame=%d->%d]\n", 248496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ast_id, 249496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org input_frame_size, 250496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_frame_size); 251496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 252496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 253496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // There's only one output frame in the OSR case. 254496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_count_ = 1; 255496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_ = new FrameDescription*[1]; 256496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0] = new(output_frame_size) FrameDescription( 257496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_frame_size, function_); 258659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT); 259496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 260496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Clear the incoming parameters in the optimized frame to avoid 261496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // confusing the garbage collector. 262496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned output_offset = output_frame_size - kPointerSize; 263496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int parameter_count = function_->shared()->formal_parameter_count() + 1; 264496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org for (int i = 0; i < parameter_count; ++i) { 265496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetFrameSlot(output_offset, 0); 266496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_offset -= kPointerSize; 267496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 268496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 269496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Translate the incoming parameters. This may overwrite some of the 270496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // incoming argument slots we've just cleared. 271496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int input_offset = input_frame_size - kPointerSize; 272496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org bool ok = true; 273496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int limit = input_offset - (parameter_count * kPointerSize); 274496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org while (ok && input_offset > limit) { 275496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ok = DoOsrTranslateCommand(&iterator, &input_offset); 276496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 277496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 278496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // There are no translation commands for the caller's pc and fp, the 279496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // context, and the function. Set them up explicitly. 2807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org for (int i = StandardFrameConstants::kCallerPCOffset; 2817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ok && i >= StandardFrameConstants::kMarkerOffset; 2827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org i -= kPointerSize) { 283496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org uint32_t input_value = input_->GetFrameSlot(input_offset); 284496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org if (FLAG_trace_osr) { 2857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org const char* name = "UNKNOWN"; 2867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org switch (i) { 2877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org case StandardFrameConstants::kCallerPCOffset: 2887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org name = "caller's pc"; 2897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org break; 2907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org case StandardFrameConstants::kCallerFPOffset: 2917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org name = "fp"; 2927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org break; 2937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org case StandardFrameConstants::kContextOffset: 2947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org name = "context"; 2957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org break; 2967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org case StandardFrameConstants::kMarkerOffset: 2977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org name = "function"; 2987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org break; 2997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 3007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n", 301496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_offset, 302496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org input_value, 3037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org input_offset, 3047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org name); 305496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 3067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 307496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset)); 308496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org input_offset -= kPointerSize; 309496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_offset -= kPointerSize; 310496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 311496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 312496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Translate the rest of the frame. 313496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org while (ok && input_offset >= 0) { 314496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ok = DoOsrTranslateCommand(&iterator, &input_offset); 315496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 316496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 317496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // If translation of any command failed, continue using the input frame. 318496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org if (!ok) { 319496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org delete output_[0]; 320496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0] = input_; 321496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); 322496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } else { 323f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the frame pointer and the context pointer. 324496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code())); 325496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code())); 326496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 327496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org unsigned pc_offset = data->OsrPcOffset()->value(); 328496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org uint32_t pc = reinterpret_cast<uint32_t>( 329a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org compiled_code_->entry() + pc_offset); 330496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetPc(pc); 331496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 3327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR); 333496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org output_[0]->SetContinuation( 334496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org reinterpret_cast<uint32_t>(continuation->entry())); 335496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 336496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org if (FLAG_trace_osr) { 337496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 338496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ok ? "finished" : "aborted", 3395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org reinterpret_cast<intptr_t>(function_)); 3404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org PrintFunctionName(); 341496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); 342496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 3474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Set the register values. The values are not important as there are no 3484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // callee saved registers in JavaScript frames, so all registers are 3494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // spilled. Registers fp and sp are set to the correct values though. 3504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int i = 0; i < Register::kNumRegisters; i++) { 3524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org input_->SetRegister(i, i * 4); 3534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 3544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 3554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { 3574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org input_->SetDoubleRegister(i, 0.0); 3584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Fill the frame content from the actual data on the frame. 3614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 3624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 3634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 3644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org} 3654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3676e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid Deoptimizer::SetPlatformCompiledStubRegisters( 3686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { 3696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org ApiFunction function(descriptor->deoptimization_handler_); 3706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_); 3716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org intptr_t handler = reinterpret_cast<intptr_t>(xref.address()); 3726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org int params = descriptor->register_param_count_; 3736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (descriptor->stack_parameter_count_ != NULL) { 3746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org params++; 3756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 3766e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org output_frame->SetRegister(r0.code(), params); 3776e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org output_frame->SetRegister(r1.code(), handler); 3786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 3796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3806e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { 3826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) { 3836e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org double double_value = input_->GetDoubleRegister(i); 3846e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org output_frame->SetDoubleRegister(i, double_value); 3856e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 3866e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 3876e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3886e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3894e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgbool Deoptimizer::HasAlignmentPadding(JSFunction* function) { 3904e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // There is no dynamic alignment padding on ARM in the input frame. 3914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org return false; 3924e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 3934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 3944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 3954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#define __ masm()-> 396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// This code tries to be close to ia32 code so that any changes can be 398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// easily ported. 399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::EntryGenerator::Generate() { 400a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org GeneratePrologue(); 401ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Save all general purpose registers before messing with them. 403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const int kNumberOfRegisters = Register::kNumRegisters; 404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Everything but pc, lr and ip which will be saved but not restored. 406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit(); 407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const int kDoubleRegsSize = 409a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters; 410a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 411e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Save all allocatable VFP registers before messing with them. 412e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(kDoubleRegZero.code() == 14); 413e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(kScratchDoubleReg.code() == 15); 414003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 415e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Check CPU flags for number of registers, setting the Z condition flag. 416e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ CheckFor32DRegs(ip); 417003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 418e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Push registers d0-d13, and possibly d16-d31, on the stack. 419e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If d16-d31 are not pushed, decrease the stack pointer instead. 420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ vstm(db_w, sp, d16, d31, ne); 421e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq); 422e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ vstm(db_w, sp, d0, d13); 423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Push all 16 registers (needed to populate FrameDescription::registers_). 4254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps 4264acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // handle this a bit differently. 427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit()); 428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const int kSavedRegistersAreaSize = 430a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize; 431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Get the bailout id from the stack. 433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r2, MemOperand(sp, kSavedRegistersAreaSize)); 434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 435169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Get the address of the location in the code object (r3) (return 436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // address for lazy deoptimization) and compute the fp-to-sp delta in 437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // register r4. 438169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ mov(r3, lr); 439169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Correct one word for bailout id. 440169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ add(r4, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); 441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sub(r4, fp, r4); 442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Allocate a new deoptimizer object. 444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Pass four arguments in r0 to r3 and fifth argument on stack. 445c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ PrepareCallCFunction(6, r5); 446a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 447a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(r1, Operand(type())); // bailout type, 448a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // r2: bailout id already loaded. 449a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // r3: code address or 0 already loaded. 450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ str(r4, MemOperand(sp, 0 * kPointerSize)); // Fp-to-sp delta. 45132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ mov(r5, Operand(ExternalReference::isolate_address(isolate()))); 452c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ str(r5, MemOperand(sp, 1 * kPointerSize)); // Isolate. 453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Call Deoptimizer::New(). 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(masm()); 45632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); 457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Preserve "deoptimizer" object in register r0 and get the input 460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // frame descriptor pointer to r1 (deoptimizer->input_); 461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset())); 462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Copy core registers into FrameDescription::registers_[kNumRegisters]. 464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(Register::kNumRegisters == kNumberOfRegisters); 465c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org for (int i = 0; i < kNumberOfRegisters; i++) { 466c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 467c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org __ ldr(r2, MemOperand(sp, i * kPointerSize)); 468c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org __ str(r2, MemOperand(r1, offset)); 469c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org } 470a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Copy VFP registers to 472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] 473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int double_regs_offset = FrameDescription::double_registers_offset(); 474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) { 475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int dst_offset = i * kDoubleSize + double_regs_offset; 476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; 477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ vldr(d0, sp, src_offset); 478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ vstr(d0, r1, dst_offset); 479c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org } 480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 481169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Remove the bailout id and the saved registers from the stack. 482169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); 483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Compute a pointer to the unwinding limit in register r2; that is 485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the first stack slot not part of the input frame. 486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); 487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(r2, r2, sp); 488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Unwind the stack down to - but not including - the unwinding 490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // limit and copy the contents of the activation frame to the input 491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // frame description. 492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(r3, r1, Operand(FrameDescription::frame_content_offset())); 493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label pop_loop; 494a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label pop_loop_header; 495a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ b(&pop_loop_header); 496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&pop_loop); 497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(r4); 498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ str(r4, MemOperand(r3, 0)); 499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(r3, r3, Operand(sizeof(uint32_t))); 500a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&pop_loop_header); 501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(r2, sp); 502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ b(ne, &pop_loop); 503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Compute the output frame in the deoptimizer. 505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(r0); // Preserve deoptimizer object across call. 506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // r0: deoptimizer object; r1: scratch. 507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ PrepareCallCFunction(1, r1); 508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Call Deoptimizer::ComputeOutputFrames(). 509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(masm()); 511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallCFunction( 51232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::compute_output_frames_function(isolate()), 1); 513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(r0); // Restore deoptimizer object (class Deoptimizer). 515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Replace the current (input) frame with the output frames. 517a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label outer_push_loop, inner_push_loop, 518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org outer_loop_header, inner_loop_header; 519e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // Outer loop state: r4 = current "FrameDescription** output_", 520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // r1 = one past the last FrameDescription**. 521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset())); 522e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org __ ldr(r4, MemOperand(r0, Deoptimizer::output_offset())); // r4 is output_. 523e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org __ add(r1, r4, Operand(r1, LSL, 2)); 524a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ jmp(&outer_loop_header); 525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&outer_push_loop); 526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Inner loop state: r2 = current FrameDescription*, r3 = loop index. 527e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org __ ldr(r2, MemOperand(r4, 0)); // output_[ix] 528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset())); 529a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ jmp(&inner_loop_header); 530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&inner_push_loop); 531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sub(r3, r3, Operand(sizeof(uint32_t))); 532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(r6, r2, Operand(r3)); 533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset())); 534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(r7); 535a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&inner_loop_header); 53659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r3, Operand::Zero()); 537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ b(ne, &inner_push_loop); // test for gt? 538e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org __ add(r4, r4, Operand(kPointerSize)); 539a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&outer_loop_header); 540e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org __ cmp(r4, r1); 541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ b(lt, &outer_push_loop); 542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 543e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Check CPU flags for number of registers, setting the Z condition flag. 544e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ CheckFor32DRegs(ip); 54594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 546e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset())); 547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int src_offset = FrameDescription::double_registers_offset(); 548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) { 549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (i == kDoubleRegZero.code()) continue; 550e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (i == kScratchDoubleReg.code()) continue; 55194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const DwVfpRegister reg = DwVfpRegister::from_code(i); 553e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ vldr(reg, r1, src_offset, i < 16 ? al : ne); 554e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org src_offset += kDoubleSize; 555003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 556003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Push state, pc, and continuation from the last output frame. 558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (type() != OSR) { 559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r6, MemOperand(r2, FrameDescription::state_offset())); 560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(r6); 561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset())); 564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(r6); 565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset())); 566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(r6); 567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Push the registers from the last output frame. 569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 5700ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r6, MemOperand(r2, offset)); 572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(r6); 573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Restore the registers from the stack. 576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldm(ia_w, sp, restored_regs); // all but pc registers. 577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(ip); // remove sp 578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(ip); // remove lr 579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 580f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ InitializeRootRegister(); 581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(ip); // remove pc 583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(r7); // get continuation, leave pc on stack 584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(lr); 585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ Jump(r7); 586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ stop("Unreachable."); 587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Deoptimizer::TableEntryGenerator::GeneratePrologue() { 591169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Create a sequence of deoptimization entries. 592169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Note that registers are still live when jumping to an entry. 593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label done; 594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < count(); i++) { 595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int start = masm()->pc_offset(); 596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org USE(start); 597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ip, Operand(i)); 598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(ip); 599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ b(&done); 600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(masm()->pc_offset() - start == table_entry_size_); 601a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 602a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 605c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 606c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { 607c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org SetFrameSlot(offset, value); 608c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org} 609c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 610c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 611c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 612c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org SetFrameSlot(offset, value); 613c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org} 614c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 615c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef __ 617a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 618a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} } // namespace v8::internal 619