1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h" 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 207be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// ------------------------------------------------------------------------- 217be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// MacroAssembler implementation. 227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 23c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) 24c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : Assembler(arg_isolate, buffer, size), 257276f14ca716596e0a0d17539516370c1f453847kasper.lund generating_stub_(false), 26c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com has_frame_(false) { 27c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (isolate() != NULL) { 283d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org // TODO(titzer): should we just use a null handle here instead? 29c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), 30c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org isolate()); 31c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 36935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(!r.IsDouble()); 37935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8()) { 38935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsx_b(dst, src); 39935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger8()) { 40935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movzx_b(dst, src); 41935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16()) { 42935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsx_w(dst, src); 43935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger16()) { 44935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movzx_w(dst, src); 45935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 46935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov(dst, src); 47935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 48935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 49935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 50935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 51935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::Store(Register src, const Operand& dst, Representation r) { 52935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(!r.IsDouble()); 53935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8() || r.IsUInteger8()) { 54935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov_b(dst, src); 55935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16() || r.IsUInteger16()) { 56935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov_w(dst, src); 57935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 58d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (r.IsHeapObject()) { 59d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org AssertNotSmi(src); 60d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } else if (r.IsSmi()) { 61d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org AssertSmi(src); 62d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 63935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov(dst, src); 64935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 65935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 66935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 67935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 68594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 69594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (isolate()->heap()->RootCanBeTreatedAsConstant(index)) { 70594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 71594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, value); 72594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 73594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 74594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 75594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 76594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, Immediate(index)); 77594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, Operand::StaticArray(destination, 78594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org times_pointer_size, 79594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org roots_array_start)); 80594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 81594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 82594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 83594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::StoreRoot(Register source, 84594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register scratch, 85594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 86594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(Heap::RootCanBeWrittenAfterInitialization(index)); 87594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 88594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 89594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(scratch, Immediate(index)); 90594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start), 91594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org source); 92594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 93594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 94594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 95594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(Register with, 96594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register scratch, 97594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 98594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 99594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 100594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(scratch, Immediate(index)); 101594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, Operand::StaticArray(scratch, 102594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org times_pointer_size, 103594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org roots_array_start)); 104594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 107594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 108594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(isolate()->heap()->RootCanBeTreatedAsConstant(index)); 109594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 110594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, value); 111594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 112594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 113594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 114594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(const Operand& with, 115594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 116594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(isolate()->heap()->RootCanBeTreatedAsConstant(index)); 117594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 118594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, value); 119594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 120594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 121594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InNewSpace( 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cc == equal || cc == not_equal); 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Immediate(~Page::kPageAlignmentMask)); 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 134ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that we can use a test_b. 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MemoryChunk::IN_FROM_SPACE < 8); 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MemoryChunk::IN_TO_SPACE < 8); 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask = (1 << MemoryChunk::IN_FROM_SPACE) 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com | (1 << MemoryChunk::IN_TO_SPACE); 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If non-zero, the page belongs to new-space. 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(scratch, MemoryChunk::kFlagsOffset), 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<uint8_t>(mask)); 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 145ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14630ce411529579186181838984710b0b0980857aaricow@chromium.org 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RememberedSetHelper( 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, // Only used for debug checks. 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler::RememberedSetFinalAction and_then) { 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 154000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load store buffer top. 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference store_buffer = 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::store_buffer_top(isolate()); 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Operand::StaticVariable(store_buffer)); 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store pointer to buffer. 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand(scratch, 0), addr); 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Increment buffer top. 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(scratch, Immediate(kPointerSize)); 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Write back new top of buffer. 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand::StaticVariable(store_buffer), scratch); 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call stub on end of buffer. 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for end of buffer. 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label buffer_overflowed; 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, &buffer_overflowed, Label::kNear); 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&buffer_overflowed); 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &done, Label::kNear); 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferOverflowStub store_buffer_overflow = 183f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StoreBufferOverflowStub(isolate(), save_fp); 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&store_buffer_overflow); 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 194c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 195c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister scratch_reg, 196c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register result_reg) { 197c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 19889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Label conv_failure; 199a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org xorps(scratch_reg, scratch_reg); 20046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cvtsd2si(result_reg, input_reg); 201c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org test(result_reg, Immediate(0xFFFFFF00)); 202c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 203a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmp(result_reg, Immediate(0x1)); 204a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(overflow, &conv_failure, Label::kNear); 20589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org mov(result_reg, Immediate(0)); 206a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org setcc(sign, result_reg); 20789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org sub(result_reg, Immediate(1)); 20889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org and_(result_reg, Immediate(255)); 20989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org jmp(&done, Label::kNear); 21089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org bind(&conv_failure); 211a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(result_reg, Immediate(0)); 21289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ucomisd(input_reg, scratch_reg); 21389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(below, &done, Label::kNear); 214a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(result_reg, Immediate(255)); 215c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 216c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 217c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 218c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 219c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampUint8(Register reg) { 220c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 221c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org test(reg, Immediate(0xFFFFFF00)); 222c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 223c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org setcc(negative, reg); // 1 if negative, 0 if positive. 224c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org dec_b(reg); // 0 if negative, 255 if positive. 225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 227c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 228c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2298fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::SlowTruncateToI(Register result_reg, 2308fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Register input_reg, 2318fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org int offset) { 232f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 233f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(stub.GetCode(), RelocInfo::CODE_TARGET); 2348fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 2358fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2368fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2378fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 2388fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org XMMRegister input_reg) { 2398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label done; 2408fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cvttsd2si(result_reg, Operand(input_reg)); 241a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmp(result_reg, 0x1); 242a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 2438fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2448fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(esp, Immediate(kDoubleSize)); 2450fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(MemOperand(esp, 0), input_reg); 2468fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, esp, 0); 2478fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(esp, Immediate(kDoubleSize)); 2488fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&done); 2498fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 2508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2528fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::DoubleToI(Register result_reg, 2538fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org XMMRegister input_reg, 2548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org XMMRegister scratch, 2558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org MinusZeroMode minus_zero_mode, 2568fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label* conversion_failed, 2578fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label::Distance dst) { 2588fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ASSERT(!input_reg.is(scratch)); 2598fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cvttsd2si(result_reg, Operand(input_reg)); 260528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtsi2sd(scratch, Operand(result_reg)); 2618fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ucomisd(scratch, input_reg); 2628fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_equal, conversion_failed, dst); 2638fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(parity_even, conversion_failed, dst); // NaN. 2648fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 265c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 266c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // The integer converted back is equal to the original. We 267c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // only have to test if we got -0 as an input. 2688fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org test(result_reg, Operand(result_reg)); 2698fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_zero, &done, Label::kNear); 2708fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org movmskpd(result_reg, input_reg); 271c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Bit 0 contains the sign of the double in input_reg. 272c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // If input was positive, we are ok and return 0, otherwise 273c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // jump to conversion_failed. 2748fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org and_(result_reg, 1); 2758fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_zero, conversion_failed, dst); 276c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 2778fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 2788fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 2798fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2808fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2818fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 2828fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Register input_reg) { 2838fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label done, slow_case; 2848fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2858fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (CpuFeatures::IsSupported(SSE3)) { 2868fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org CpuFeatureScope scope(this, SSE3); 2878fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label convert; 2888fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Use more powerful conversion when sse3 is available. 2898fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Load x87 register with heap number. 2908fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 2918fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Get exponent alone and check for too-big exponent. 2928fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org mov(result_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 2938fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org and_(result_reg, HeapNumber::kExponentMask); 2948fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org const uint32_t kTooBigExponent = 2958fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 2968fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cmp(Operand(result_reg), Immediate(kTooBigExponent)); 2978fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(greater_equal, &slow_case, Label::kNear); 2988fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2998fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Reserve space for 64 bit answer. 3008fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(Operand(esp), Immediate(kDoubleSize)); 3018fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Do conversion, which cannot fail because we checked the exponent. 3028fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fisttp_d(Operand(esp, 0)); 3038fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 3048fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(Operand(esp), Immediate(kDoubleSize)); 3058fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org jmp(&done, Label::kNear); 3068fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3078fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Slow case. 3088fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&slow_case); 3098fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (input_reg.is(result_reg)) { 3108fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Input is clobbered. Restore number from fpu stack 3118fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(Operand(esp), Immediate(kDoubleSize)); 3128fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fstp_d(Operand(esp, 0)); 3138fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, esp, 0); 3148fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(esp, Immediate(kDoubleSize)); 3158fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } else { 3168fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fstp(0); 3178fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, input_reg); 3188fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } else { 3200fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3218fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cvttsd2si(result_reg, Operand(xmm0)); 322a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmp(result_reg, 0x1); 323a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 3248fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Check if the input was 0x8000000 (kMinInt). 3258fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // If no, then we got an overflow and we deoptimize. 3268fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ExternalReference min_int = ExternalReference::address_of_min_int(); 3278fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ucomisd(xmm0, Operand::StaticVariable(min_int)); 3288fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_equal, &slow_case, Label::kNear); 3298fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(parity_even, &slow_case, Label::kNear); // NaN. 3308fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org jmp(&done, Label::kNear); 3318fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3328fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Slow case. 3338fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&slow_case); 3348fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (input_reg.is(result_reg)) { 3358fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Input is clobbered. Restore number from double scratch. 3368fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(esp, Immediate(kDoubleSize)); 3370fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(MemOperand(esp, 0), xmm0); 3388fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, esp, 0); 3398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(esp, Immediate(kDoubleSize)); 3408fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } else { 3418fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, input_reg); 3428fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3438fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3448fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&done); 3458fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 3468fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3478fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3488fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::TaggedToI(Register result_reg, 3498fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Register input_reg, 3508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org XMMRegister temp, 3518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org MinusZeroMode minus_zero_mode, 3528fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label* lost_precision) { 3538fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label done; 3548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ASSERT(!temp.is(xmm0)); 3558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3568fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3578fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org isolate()->factory()->heap_number_map()); 3588fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_equal, lost_precision, Label::kNear); 3598fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3603c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ASSERT(!temp.is(no_xmm_reg)); 3618fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3623c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3633c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org cvttsd2si(result_reg, Operand(xmm0)); 3643c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Cvtsi2sd(temp, Operand(result_reg)); 3653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ucomisd(xmm0, temp); 3663c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org RecordComment("Deferred TaggedToI: lost precision"); 3673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org j(not_equal, lost_precision, Label::kNear); 3683c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org RecordComment("Deferred TaggedToI: NaN"); 3693c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org j(parity_even, lost_precision, Label::kNear); 3703c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org test(result_reg, Operand(result_reg)); 3723c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org j(not_zero, &done, Label::kNear); 3733c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movmskpd(result_reg, xmm0); 3743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org and_(result_reg, 1); 3753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org RecordComment("Deferred TaggedToI: minus zero"); 3763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org j(not_zero, lost_precision, Label::kNear); 3778fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3788fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&done); 3798fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 3808fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3818fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 38246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::LoadUint32(XMMRegister dst, 3837e6132b924829c353864933f29124419916db550machenbach@chromium.org Register src) { 38446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Label done; 38546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cmp(src, Immediate(0)); 386b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ExternalReference uint32_bias = 387b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ExternalReference::address_of_uint32_bias(); 388528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtsi2sd(dst, src); 38946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org j(not_sign, &done, Label::kNear); 3907e6132b924829c353864933f29124419916db550machenbach@chromium.org addsd(dst, Operand::StaticVariable(uint32_bias)); 39146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org bind(&done); 39246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 39346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 39446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 395196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWriteArray( 396196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 397196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register value, 398196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register index, 399196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode save_fp, 400196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RememberedSetAction remembered_set_action, 401196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 402196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kSmiTag); 410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(value, Immediate(kSmiTagMask)); 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &done); 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Array access: calculate the destination address in the same manner as 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // into an array of words. 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst = index; 418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, Operand(object, index, times_half_pointer_size, 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FixedArray::kHeaderSize - kHeapObjectTag)); 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 421196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWrite(object, dst, value, save_fp, remembered_set_action, 422196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org OMIT_SMI_CHECK, pointers_to_here_check_for_value); 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // turned on to provoke errors. 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(value, Immediate(BitCast<int32_t>(kZapValue))); 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(index, Immediate(BitCast<int32_t>(kZapValue))); 43183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 43283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 43383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 43483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteField( 436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst, 440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 442196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 443196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 44430ce411529579186181838984710b0b0980857aaricow@chromium.org // First, check if a write barrier is even needed. The tests below 445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 44683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 448b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org // Skip barrier if writing a smi. 449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done, Label::kNear); 451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Although the object register is tagged, the offset is relative to the start 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the object, so so offset must be a multiple of kPointerSize. 455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(offset, kPointerSize)); 456e88a9edffbbdbc4ccc9872560ac4d9ea6b188fbdwhesse@chromium.org 457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, FieldOperand(object, offset)); 458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(dst, (1 << kPointerSizeLog2) - 1); 461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 466196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWrite(object, dst, value, save_fp, remembered_set_action, 467196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org OMIT_SMI_CHECK, pointers_to_here_check_for_value); 46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&done); 470b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 472b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // turned on to provoke errors. 473badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 474f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org mov(value, Immediate(BitCast<int32_t>(kZapValue))); 475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(dst, Immediate(BitCast<int32_t>(kZapValue))); 476b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid MacroAssembler::RecordWriteForMap( 4817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register object, 4827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map, 4837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register scratch1, 4847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register scratch2, 4857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org SaveFPRegsMode save_fp) { 4867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label done; 4877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register address = scratch1; 4897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register value = scratch2; 4907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (emit_debug_code()) { 4917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label ok; 4927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org lea(address, FieldOperand(object, HeapObject::kMapOffset)); 4937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test_b(address, (1 << kPointerSizeLog2) - 1); 4947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org j(zero, &ok, Label::kNear); 4957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int3(); 4967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bind(&ok); 4977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 4987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!object.is(value)); 5007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!object.is(address)); 5017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!value.is(address)); 502c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 5037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 5047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!FLAG_incremental_marking) { 5057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return; 5067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 5077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 508196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // Compute the address. 509196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org lea(address, FieldOperand(object, HeapObject::kMapOffset)); 510196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 511f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Count number of write barriers in generated code. 512f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 513f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 514f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 5157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // A single check of the map's pages interesting flag suffices, since it is 5167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // only set during incremental collection, and then it's also guaranteed that 5177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // the from object's page's interesting flag is also set. This optimization 5187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // relies on the fact that maps can never be in new space. 5197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!isolate()->heap()->InNewSpace(*map)); 5207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CheckPageFlagForMap(map, 5217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 5227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zero, 5237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org &done, 5247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::kNear); 5257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 526f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET, 527f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org save_fp); 5287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CallStub(&stub); 5297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 5307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bind(&done); 5317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 5327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Clobber clobbered input registers when running with the debug-code flag 5337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // turned on to provoke errors. 5347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (emit_debug_code()) { 5357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(value, Immediate(BitCast<int32_t>(kZapValue))); 5367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(scratch1, Immediate(BitCast<int32_t>(kZapValue))); 5377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(scratch2, Immediate(BitCast<int32_t>(kZapValue))); 5387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 5397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org} 5407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 5417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 542196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWrite( 543196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 544196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register address, 545196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register value, 546196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode fp_mode, 547196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RememberedSetAction remembered_set_action, 548196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 549196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(value)); 551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(address)); 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!value.is(address)); 553c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (remembered_set_action == OMIT_REMEMBERED_SET && 556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !FLAG_incremental_marking) { 557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 560000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(value, Operand(address, 0)); 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &ok, Label::kNear); 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 568f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Count number of write barriers in generated code. 569f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 570f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 571f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 57269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // First, check if a write barrier is even needed. The tests below 57369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // catch stores of Smis and stores into young gen. 57469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Label done; 57569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done, Label::kNear); 579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 580c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 581196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 582196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org CheckPageFlag(value, 583196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org value, // Used as scratch. 584196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 585196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org zero, 586196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org &done, 587196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label::kNear); 588196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(object, 590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersFromHereAreInterestingMask, 592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 596f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 597f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org fp_mode); 598c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&stub); 59969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 60069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org bind(&done); 60169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered registers when running with the debug-code flag 60369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // turned on to provoke errors. 604badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 60569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org mov(address, Immediate(BitCast<int32_t>(kZapValue))); 60669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org mov(value, Immediate(BitCast<int32_t>(kZapValue))); 60769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 60869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 60969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 61069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 6115c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::DebugBreak() { 612a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(eax, Immediate(0)); 613ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak, isolate()))); 614f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), 1); 615f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 6165c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 61743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 618d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 619528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) { 620528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xorps(dst, dst); 621528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cvtsi2sd(dst, src); 622528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 623528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 624528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 6257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgbool MacroAssembler::IsUnsafeImmediate(const Immediate& x) { 6267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static const int kMaxImmediateBits = 17; 6274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (!RelocInfo::IsNone(x.rmode_)) return false; 6287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return !is_intn(x.x_, kMaxImmediateBits); 6297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 6307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 632a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid MacroAssembler::SafeMove(Register dst, const Immediate& x) { 6337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 634a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(dst, Immediate(x.x_ ^ jit_cookie())); 6357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org xor_(dst, jit_cookie()); 6367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 637a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(dst, x); 6387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 6407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid MacroAssembler::SafePush(const Immediate& x) { 6437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 6447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org push(Immediate(x.x_ ^ jit_cookie())); 6457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org xor_(Operand(esp, 0), Immediate(jit_cookie())); 6467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 6477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org push(x); 6487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 6507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6527be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid MacroAssembler::CmpObjectType(Register heap_object, 6537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org InstanceType type, 6547be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org Register map) { 6557be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 6567be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpInstanceType(map, type); 6577be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 6587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6597be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6607be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 6617be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 6627be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org static_cast<int8_t>(type)); 6637be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 6647be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6657be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 666d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comvoid MacroAssembler::CheckFastElements(Register map, 667d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 668d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance) { 669830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 670830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 671830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 672830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 674830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleyElementValue); 675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 678c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckFastObjectElements(Register map, 680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 682830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 683830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 684830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 685830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 686c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 687830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleySmiElementValue); 688c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(below_equal, fail, distance); 689d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 690830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleyElementValue); 691d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com j(above, fail, distance); 692d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com} 693d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 694d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 695830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid MacroAssembler::CheckFastSmiElements(Register map, 696830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 697830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance) { 698830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 699830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 700c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 701830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleySmiElementValue); 702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 704c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 706c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::StoreNumberToDoubleElements( 707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register maybe_number, 708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register key, 710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister scratch2, 712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 713fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset) { 714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label smi_value, done, maybe_nan, not_nan, is_nan, have_double_value; 715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(maybe_number, &smi_value, Label::kNear); 716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 717c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckMap(maybe_number, 718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate()->factory()->heap_number_map(), 719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fail, 720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DONT_DO_SMI_CHECK); 721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Double value, canonicalize NaN. 723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); 724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(FieldOperand(maybe_number, offset), 725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kNaNOrInfinityLowerBoundUpper32)); 726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater_equal, &maybe_nan, Label::kNear); 727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_nan); 729c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference canonical_nan_reference = 730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::address_of_canonical_non_hole_nan(); 7313c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(scratch2, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 7323c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org bind(&have_double_value); 7333c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(FieldOperand(elements, key, times_4, 7343c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 7353c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org scratch2); 736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&done); 737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&maybe_nan); 739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise 740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // it's an Infinity, and the non-NaN code path applies. 741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater, &is_nan, Label::kNear); 742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); 743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_nan); 744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_nan); 7453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(scratch2, Operand::StaticVariable(canonical_nan_reference)); 746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&have_double_value, Label::kNear); 747c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&smi_value); 749c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a smi. Convert to a double and store. 750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve original value. 751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch1, maybe_number); 752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiUntag(scratch1); 7533c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Cvtsi2sd(scratch2, scratch1); 7543c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(FieldOperand(elements, key, times_4, 7553c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 7563c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org scratch2); 757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 761935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 762f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 763f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 764f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 765f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 7665c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CheckMap(Register obj, 7675c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 7685c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 769a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type) { 77040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (smi_check_type == DO_SMI_CHECK) { 771c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org JumpIfSmi(obj, fail); 7725c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 773f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 774935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CompareMap(obj, map); 7755c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, fail); 7765c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 779ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgvoid MacroAssembler::DispatchMap(Register obj, 7802bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 781ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 782ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 783ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type) { 784ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label fail; 785560b07baefe6e8699f1ca093711f8298c43a01f9ager@chromium.org if (smi_check_type == DO_SMI_CHECK) { 786ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org JumpIfSmi(obj, &fail); 787ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 788ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map)); 789ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org j(equal, success); 790ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 791ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org bind(&fail); 792ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 793ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 794ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 7950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgCondition MacroAssembler::IsObjectStringType(Register heap_object, 7960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Register map, 7970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Register instance_type) { 7980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 7990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 80080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 8010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org test(instance_type, Immediate(kIsNotStringMask)); 8020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return zero; 8030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 8040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 8050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 806750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCondition MacroAssembler::IsObjectNameType(Register heap_object, 807750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 808750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type) { 809750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 810750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 811750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org cmpb(instance_type, static_cast<uint8_t>(LAST_NAME_TYPE)); 812750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return below_equal; 813750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 814750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 815750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 8161af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid MacroAssembler::IsObjectJSObjectType(Register heap_object, 8171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register map, 8181af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register scratch, 8191af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Label* fail) { 8201af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 8211af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org IsInstanceJSObjectType(map, scratch, fail); 8221af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 8231af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 8241af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 8251af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid MacroAssembler::IsInstanceJSObjectType(Register map, 8261af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register scratch, 8271af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Label* fail) { 8281af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org movzx_b(scratch, FieldOperand(map, Map::kInstanceTypeOffset)); 829c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(scratch, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 830d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org cmp(scratch, 831d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org LAST_NONCALLABLE_SPEC_OBJECT_TYPE - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 8321af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org j(above, fail); 8331af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 8341af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 8351af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 83643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::FCmp() { 8371e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org fucomip(); 8381e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org fstp(0); 83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 84043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 84143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 842c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNumber(Register object) { 843c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 844c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Label ok; 845c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org JumpIfSmi(object, &ok); 846c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org cmp(FieldOperand(object, HeapObject::kMapOffset), 847c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate()->factory()->heap_number_map()); 848594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandNotANumber); 849c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org bind(&ok); 850c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 8515c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8535c838251403b0be9a882540f1922577abba4c872ager@chromium.org 854c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(Register object) { 855c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 856c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 857594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandIsNotASmi); 858c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 859f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org} 860f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 861f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 862c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertString(Register object) { 863c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 864c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 865594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAString); 866c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org push(object); 867c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org mov(object, FieldOperand(object, HeapObject::kMapOffset)); 868c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CmpInstanceType(object, FIRST_NONSTRING_TYPE); 869c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org pop(object); 870594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kOperandIsNotAString); 871c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 872d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 873d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 874d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 875750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid MacroAssembler::AssertName(Register object) { 876750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (emit_debug_code()) { 877750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org test(object, Immediate(kSmiTagMask)); 878594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAName); 879750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org push(object); 880750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org mov(object, FieldOperand(object, HeapObject::kMapOffset)); 881750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CmpInstanceType(object, LAST_NAME_TYPE); 882750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org pop(object); 883594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below_equal, kOperandIsNotAName); 884750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 885750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 886750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 887750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 8882904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 8892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org if (emit_debug_code()) { 8902904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Label done_checking; 8912904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org AssertNotSmi(object); 8922904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org cmp(object, isolate()->factory()->undefined_value()); 8932904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org j(equal, &done_checking); 8942904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org cmp(FieldOperand(object, 0), 8952904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Immediate(isolate()->factory()->allocation_site_map())); 8962904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Assert(equal, kExpectedUndefinedOrCell); 8972904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org bind(&done_checking); 8982904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 8992904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org} 9002904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 9012904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 902c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNotSmi(Register object) { 903c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 904c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 905594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmi); 906c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 90726c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org} 90826c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org 90926c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org 910285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::StubPrologue() { 911285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(ebp); // Caller's frame pointer. 912285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org mov(ebp, esp); 913285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(esi); // Callee's context. 914285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(Immediate(Smi::FromInt(StackFrame::STUB))); 915285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org} 916285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org 917285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org 918285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::Prologue(bool code_pre_aging) { 919285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org PredictableCodeSizeScope predictible_code_size_scope(this, 920285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org kNoCodeAgeSequenceLength); 921285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org if (code_pre_aging) { 922285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org // Pre-age the code. 923285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 924285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org RelocInfo::CODE_AGE_SEQUENCE); 925285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org Nop(kNoCodeAgeSequenceLength - Assembler::kCallInstructionLength); 926285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org } else { 927c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(ebp); // Caller's frame pointer. 928c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org mov(ebp, esp); 929c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(esi); // Callee's context. 930285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(edi); // Callee's JS function. 931c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 932c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 933c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 934c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 9357c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 93643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(ebp); 937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ebp, esp); 93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(esi); 93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(Immediate(Smi::FromInt(type))); 940061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org push(Immediate(CodeObject())); 941badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 9427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); 943594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kCodeObjectNotProperlyPatched); 944061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org } 94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 94643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9487c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 949badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), 95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Immediate(Smi::FromInt(type))); 952594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kStackFrameTypesMustMatch); 95343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen leave(); 95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 957d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 958d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::EnterExitFramePrologue() { 959f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the frame structure on the stack. 960eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 961236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 962236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 963236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org push(ebp); 964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ebp, esp); 965236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 966d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Reserve room for entry stack pointer and push the code object. 967236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 9685c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(0)); // Saved entry sp, patched before call. 9695c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. 970236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 971236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Save the frame pointer and the context in top. 972cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); 973cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 974236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(c_entry_fp_address), ebp); 975236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(context_address), esi); 976c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 977236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 978236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 979a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { 980a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Optionally save all XMM registers. 981a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (save_doubles) { 9821e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org int space = XMMRegister::kMaxNumRegisters * kDoubleSize + 9831e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org argc * kPointerSize; 984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(space)); 9850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int offset = -2 * kPointerSize; 9861e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = XMMRegister::from_code(i); 9880fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); 989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 990a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 991c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(argc * kPointerSize)); 992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 993236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 994236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Get the required frame alignment for the OS. 995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int kFrameAlignment = OS::ActivationFrameAlignment(); 996236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (kFrameAlignment > 0) { 997236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(IsPowerOf2(kFrameAlignment)); 998236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org and_(esp, -kFrameAlignment); 999236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } 1000236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1001236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Patch the saved entry sp. 1002236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); 1003236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 1004236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1005236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::EnterExitFrame(bool save_doubles) { 1007d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(); 1008c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1009f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up argc and argv in callee-saved registers. 1010c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 1011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(edi, eax); 1012c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org lea(esi, Operand(ebp, eax, times_4, offset)); 1013c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1014ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Reserve space for argc, argv and isolate. 1015ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org EnterExitFrameEpilogue(3, save_doubles); 1016c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 1017c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1018c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 10194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::EnterApiExitFrame(int argc) { 1020d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(); 1021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EnterExitFrameEpilogue(argc, false); 1022c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 1023c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1024c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::LeaveExitFrame(bool save_doubles) { 1026a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Optionally restore all XMM registers. 1027a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (save_doubles) { 10280ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int offset = -2 * kPointerSize; 10291e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 1030a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = XMMRegister::from_code(i); 10310fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); 1032a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1035236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Get the return address from the stack and restore the frame pointer. 1036236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(ecx, Operand(ebp, 1 * kPointerSize)); 1037236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(ebp, Operand(ebp, 0 * kPointerSize)); 1038236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1039236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Pop the arguments and the receiver from the caller stack. 1040236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org lea(esp, Operand(esi, 1 * kPointerSize)); 1041236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 10424a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Push the return address to get ready to return. 10434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com push(ecx); 10444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(true); 10464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 10474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1048e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1049528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 1050236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Restore current context from top and clear it in debug mode. 105183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 1052528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 1053528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(esi, Operand::StaticVariable(context_address)); 1054528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 105565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef DEBUG 105665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org mov(Operand::StaticVariable(context_address), Immediate(0)); 105765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 1058236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1059236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Clear the top frame. 106083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 1061ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 1062236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); 1063236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 1064236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1065236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1066528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 1067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(esp, ebp); 10684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com pop(ebp); 10694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1070528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(restore_context); 10714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 10724a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 10734a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 107478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid MacroAssembler::PushTryHandler(StackHandler::Kind kind, 107504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_index) { 1076eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Adjust this code if not the case. 10774acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 10784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 107904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 108004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 108104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 108204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 108304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 108404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // We will build up the handler from the bottom by pushing on the stack. 108578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // First push the frame pointer and context. 108678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (kind == StackHandler::JS_ENTRY) { 108704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The frame pointer does not point to a JS frame so we save NULL for 108804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // ebp. We expect the code throwing an exception to check ebp before 108904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // dereferencing it to restore the context. 1090eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(Immediate(0)); // NULL frame pointer. 10914acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org push(Immediate(Smi::FromInt(0))); // No context. 109278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 109378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(ebp); 109478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(esi); 109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 109604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push the state and the code object. 109778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org unsigned state = 109878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::IndexField::encode(handler_index) | 109978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::KindField::encode(kind); 110004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Immediate(state)); 110164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Push(CodeObject()); 110204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 110304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Link the current handler as the next handler. 110404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 110504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Operand::StaticVariable(handler_address)); 110604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Set this new handler as the current one. 110704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(Operand::StaticVariable(handler_address), esp); 110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::PopTryHandler() { 11124acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 111304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 111404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(Operand::StaticVariable(handler_address)); 1115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 111613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 111713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 111813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 111904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid MacroAssembler::JumpToHandlerEntry() { 112004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Compute the handler entry address and jump to it. The handler table is 112104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // a fixed array of (smi-tagged) code offsets. 112204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // eax = exception, edi = code object, edx = state. 112304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(ebx, FieldOperand(edi, Code::kHandlerTableOffset)); 112404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org shr(edx, StackHandler::kKindWidth); 112504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(edx, FieldOperand(ebx, edx, times_4, FixedArray::kHeaderSize)); 112604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org SmiUntag(edx); 112704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); 112804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org jmp(edi); 112904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org} 113004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 113104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 113249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgvoid MacroAssembler::Throw(Register value) { 113349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Adjust this code if not the case. 11344acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 11354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 113604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 113704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 113804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 113904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 114004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 114104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The exception is expected in eax. 114249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (!value.is(eax)) { 114349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org mov(eax, value); 114449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 114504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Drop the stack pointer to the top of the top handler. 114604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 114749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org mov(esp, Operand::StaticVariable(handler_address)); 114804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the next handler. 114949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pop(Operand::StaticVariable(handler_address)); 115004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 115104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in edi. 115204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edi); // Code object. 115304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edx); // Index and state. 115404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 115504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the context and frame pointer. 11564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(esi); // Context. 11574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(ebp); // Frame pointer. 115849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 11594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // If the handler is a JS frame, restore the context to the frame. 116004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either 116104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // ebp or esi. 116283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label skip; 116304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org test(esi, esi); 116404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(zero, &skip, Label::kNear); 11654acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 116649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org bind(&skip); 116749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 116804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 116949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 117049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 117149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 117265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.orgvoid MacroAssembler::ThrowUncatchable(Register value) { 117349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Adjust this code if not the case. 11744acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 11754acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 117604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 117704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 117804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 117904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 118049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 1181c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // The exception is expected in eax. 118265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value.is(eax)) { 1183c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(eax, value); 118449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 1185c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Drop the stack pointer to the top of the top stack handler. 1186c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 1187c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(esp, Operand::StaticVariable(handler_address)); 1188c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1189c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Unwind the handlers until the top ENTRY handler is found. 1190c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Label fetch_next, check_kind; 1191c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org jmp(&check_kind, Label::kNear); 1192c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&fetch_next); 1193c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(esp, Operand(esp, StackHandlerConstants::kNextOffset)); 1194c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1195c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&check_kind); 119678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org STATIC_ASSERT(StackHandler::JS_ENTRY == 0); 119704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org test(Operand(esp, StackHandlerConstants::kStateOffset), 119804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Immediate(StackHandler::KindField::kMask)); 119904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(not_zero, &fetch_next); 1200c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1201c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Set the top handler address to next handler past the top ENTRY handler. 1202c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(Operand::StaticVariable(handler_address)); 120349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 120404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in edi. 120504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edi); // Code object. 120604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edx); // Index and state. 120704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 120804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Clear the context pointer and frame pointer (0 was saved in the handler). 1209c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(esi); 121049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pop(ebp); 121149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 121204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 121349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 121449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 121549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 12165a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 1217e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch1, 1218e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch2, 1219e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org Label* miss) { 12205a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Label same_contexts; 12215a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1222e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!holder_reg.is(scratch1)); 1223e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!holder_reg.is(scratch2)); 1224e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!scratch1.is(scratch2)); 122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12265a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Load current lexical context from the stack frame. 1227e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, Operand(ebp, StandardFrameConstants::kContextOffset)); 12285a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12295a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // When generating debug code, make sure the lexical context is set. 1230badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1231e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, Immediate(0)); 1232594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 123446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context of the current context. 123546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org int offset = 123646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 1237e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, offset)); 1238e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, GlobalObject::kNativeContextOffset)); 12395a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 124046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 1241badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 124246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map. 1243e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(FieldOperand(scratch1, HeapObject::kMapOffset), 1244e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->native_context_map()); 1245594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 12465a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 12475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12485a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Check if both contexts are the same. 1249e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 12507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(equal, &same_contexts); 12515a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12525a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Compare security tokens, save holder_reg on the stack so we can use it 12535a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // as a temporary register. 12545a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // 125543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that the security token in the calling global object is 125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // compatible with the security token in the receiving global 125743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // object. 1258e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch2, 125946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 12605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 126146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 1262badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1263e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch2, isolate()->factory()->null_value()); 1264594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 12655a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 126646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map(), 1267e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(FieldOperand(scratch2, HeapObject::kMapOffset), 1268e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->native_context_map()); 1269594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 12705a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 12715a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12725a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org int token_offset = Context::kHeaderSize + 12735a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Context::SECURITY_TOKEN_INDEX * kPointerSize; 1274e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, token_offset)); 1275e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, FieldOperand(scratch2, token_offset)); 12767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, miss); 12775a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12785a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org bind(&same_contexts); 127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1282ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// Compute the hash code from the untagged key. This must be kept in sync with 1283ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in 1284ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// code-stub-hydrogen.cc 1285f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// 1286f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Note: r0 will contain hash code 1287f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 1288f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Xor original key with a seed. 1289874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (serializer_enabled()) { 1290f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExternalReference roots_array_start = 1291f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExternalReference::roots_array_start(isolate()); 1292f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, Immediate(Heap::kHashSeedRootIndex)); 1293f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, 1294f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Operand::StaticArray(scratch, times_pointer_size, roots_array_start)); 1295f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiUntag(scratch); 1296f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1297f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } else { 1298f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com int32_t seed = isolate()->heap()->HashSeed(); 1299f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, Immediate(seed)); 1300f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 1301f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1302f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = ~hash + (hash << 15); 1303f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1304f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com not_(r0); 1305f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shl(scratch, 15); 1306f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com add(r0, scratch); 1307f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 12); 1308f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1309f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 12); 1310f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1311f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash + (hash << 2); 1312f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com lea(r0, Operand(r0, r0, times_4, 0)); 1313f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 4); 1314f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1315f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 4); 1316f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1317f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash * 2057; 1318f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com imul(r0, r0, 2057); 1319f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 16); 1320f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1321f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 16); 1322f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1323f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 1324f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1325f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1326f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 13276db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 13286db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 13296db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 13306db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 13316db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 13326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 13336db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result) { 13346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Register use: 13356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // elements - holds the slow-case elements of the receiver and is unchanged. 13376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // key - holds the smi key on entry and is unchanged. 13396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scratch registers: 13416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r0 - holds the untagged key on entry and holds the hash once computed. 13436db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r1 - used to hold the capacity mask of the dictionary 13456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r2 - used for the index into the dictionary. 13476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13486db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // result - holds the result on exit if the load succeeds and we fall through. 13496db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13506db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Label done; 13516db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1352f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com GetNumberHash(r0, r1); 13536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13546db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute capacity mask. 1355f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset)); 13566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org shr(r1, kSmiTagSize); // convert smi to int 13576db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org dec(r1); 13586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13596db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Generate an unrolled loop that performs a few probes before giving up. 1360ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org for (int i = 0; i < kNumberDictionaryProbes; i++) { 13616db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Use r2 for index calculations and keep the hash intact in r0. 13626db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org mov(r2, r0); 13636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute the masked index: (hash + i + i * i) & mask. 13646db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (i > 0) { 1365f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com add(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 13666db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(r2, r1); 13686db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13696db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scale the index by multiplying by the entry size. 1370f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(SeededNumberDictionary::kEntrySize == 3); 13716db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 13726db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13736db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check if the key matches. 13746db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org cmp(key, FieldOperand(elements, 13756db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org r2, 13766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org times_pointer_size, 1377f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset)); 1378ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (i != (kNumberDictionaryProbes - 1)) { 13796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(equal, &done); 13806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } else { 13816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_equal, miss); 13826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 13836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 13846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org bind(&done); 13866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check that the value is a normal propety. 13876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kDetailsOffset = 1388f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 13896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org ASSERT_EQ(NORMAL, 0); 13906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 139183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); 13926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_zero, miss); 13936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Get the value at the masked, scaled index. 13956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kValueOffset = 1396f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + kPointerSize; 13976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 13986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 13996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 14006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1401a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid MacroAssembler::LoadAllocationTopHelper(Register result, 1402a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Register scratch, 1403a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags) { 14042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 14052bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 140618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 140718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Just return if allocation top is already known. 1408a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & RESULT_CONTAINS_TOP) != 0) { 140918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // No use of scratch if allocation top is provided. 141018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(scratch.is(no_reg)); 1411a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG 1412a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Assert that result actually contains top on entry. 14132bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org cmp(result, Operand::StaticVariable(allocation_top)); 1414594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kUnexpectedAllocationTop); 1415a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 141618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 141718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 141818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 141918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Move address of new object to result. Use scratch register if available. 142018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (scratch.is(no_reg)) { 14212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(result, Operand::StaticVariable(allocation_top)); 142218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 14232bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(scratch, Immediate(allocation_top)); 142418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(result, Operand(scratch, 0)); 142518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 142618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 142718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 142818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 142918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 14302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 14312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 1432badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1433ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org test(result_end, Immediate(kObjectAlignmentMask)); 1434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kUnalignedAllocationInNewSpace); 1435ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 1436ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 14372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 14382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 143918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 144018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update new top. Use scratch if available. 144118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (scratch.is(no_reg)) { 14422bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(Operand::StaticVariable(allocation_top), result_end); 144318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 144418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(Operand(scratch, 0), result_end); 144518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 144618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 144718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1448a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 14492bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid MacroAssembler::Allocate(int object_size, 14502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 14512bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 14522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 14532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 14542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 14554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1456ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); 1457303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1458badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1459303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1460303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1461303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result_end.is_valid()) { 1462303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1463303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1464303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1465303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1466303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1467303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1468303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1469303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1470303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 147118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 147218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 147318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1474beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 147518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1476f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org ExternalReference allocation_limit = 1477f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1478f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org 14794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 1480f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 14814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 14822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 14834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 14844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label aligned; 14854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 14864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org j(zero, &aligned, Label::kNear); 1487f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1488f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1489f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org j(above_equal, gc_required); 1490f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org } 14914cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org mov(Operand(result, 0), 14924cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 14934cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org add(result, Immediate(kDoubleSize / 2)); 14944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bind(&aligned); 14954cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 14964cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 14972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // Calculate new top and bail out if space is exhausted. 1498f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org Register top_reg = result_end.is_valid() ? result_end : result; 1499d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (!top_reg.is(result)) { 1500d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com mov(top_reg, result); 1501a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(top_reg, Immediate(object_size)); 15037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(carry, gc_required); 15042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org cmp(top_reg, Operand::StaticVariable(allocation_limit)); 15057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(above, gc_required); 15060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 15070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 15082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(top_reg, scratch, flags); 1509c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1510c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Tag result if requested. 15114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bool tag_result = (flags & TAG_OBJECT) != 0; 1512c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (top_reg.is(result)) { 15134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (tag_result) { 1514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(result, Immediate(object_size - kHeapObjectTag)); 1515c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 1516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(result, Immediate(object_size)); 1517c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 15184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else if (tag_result) { 15194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kHeapObjectTag == 1); 15204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org inc(result); 1521c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 152218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 152318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 152418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1525f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(int header_size, 1526f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 1527f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 1528f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org RegisterValueType element_count_type, 1529f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1530f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1531f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1532f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1533f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 15344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & SIZE_IN_WORDS) == 0); 1535303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1536badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1537303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1538303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1539303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1540303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1541303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1542303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1543303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Register element_count is not modified by the function. 1544303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1545303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1546303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1547303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 154818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 154918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 155018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1551beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 155218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1553f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org ExternalReference allocation_limit = 1554f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1555f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org 15564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 1557f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 15584cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1559f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 15604cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 15614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label aligned; 15624cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 15634cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org j(zero, &aligned, Label::kNear); 1564f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1565f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1566f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org j(above_equal, gc_required); 1567f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org } 15684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org mov(Operand(result, 0), 15694cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 15704cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org add(result, Immediate(kDoubleSize / 2)); 15714cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bind(&aligned); 15724cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 15734cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 1574f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Calculate new top and bail out if space is exhausted. 1575d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // We assume that element_count*element_size + header_size does not 1576d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // overflow. 15774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (element_count_type == REGISTER_VALUE_IS_SMI) { 15784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_2 - 1) == times_1); 15794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_4 - 1) == times_2); 15804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_8 - 1) == times_4); 15814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(element_size >= times_2); 15824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kSmiTagSize == 1); 15834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org element_size = static_cast<ScaleFactor>(element_size - 1); 15844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else { 15854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(element_count_type == REGISTER_VALUE_IS_INT32); 15864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 1587d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com lea(result_end, Operand(element_count, element_size, header_size)); 1588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(result_end, result); 1589d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 1590f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp(result_end, Operand::StaticVariable(allocation_limit)); 159118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 159218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1593a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 15944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kHeapObjectTag == 1); 15954cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org inc(result); 1596a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 15970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 15980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 15992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 160018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 160118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 160218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1603f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(Register object_size, 1604f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1605f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1606f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1607f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1608f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 160994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1610303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1611badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1612303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1613303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1614303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1615303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1616303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1617303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1618303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // object_size is left unchanged by this function. 1619303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1620303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1621303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1622303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 162318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 162418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 162518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1626beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 162718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1628f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org ExternalReference allocation_limit = 1629f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1630f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org 163194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Align the next allocation. Storing the filler map without checking top is 1632f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 163394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1634f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 163594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 163694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Label aligned; 163794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 163894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org j(zero, &aligned, Label::kNear); 1639f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1640f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1641f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org j(above_equal, gc_required); 1642f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org } 164394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org mov(Operand(result, 0), 164494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 164594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org add(result, Immediate(kDoubleSize / 2)); 164694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org bind(&aligned); 164794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 164894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1649f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Calculate new top and bail out if space is exhausted. 165018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (!object_size.is(result_end)) { 165118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(result_end, object_size); 165218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 1653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(result_end, result); 16547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(carry, gc_required); 1655f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp(result_end, Operand::StaticVariable(allocation_limit)); 16567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(above, gc_required); 165718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1658a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Tag result if requested. 1659a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 166094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(kHeapObjectTag == 1); 166194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org inc(result); 1662a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 16630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 16640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 16652bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 166618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 166718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 166818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 166918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UndoAllocationInNewSpace(Register object) { 167018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference new_space_allocation_top = 1671ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 167218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 167318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Make sure the object has no tag before resetting top. 1674c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(object, Immediate(~kHeapObjectTagMask)); 167518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef DEBUG 167618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org cmp(object, Operand::StaticVariable(new_space_allocation_top)); 1677594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kUndoAllocationOfNonAllocatedMemory); 167818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 167918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(Operand::StaticVariable(new_space_allocation_top), object); 168018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 168118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 168218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 16833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgvoid MacroAssembler::AllocateHeapNumber(Register result, 16843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch1, 16853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch2, 16863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label* gc_required) { 16873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate heap number in new space. 16882bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, 16892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 16903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 16913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Set the map. 16923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 16937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->heap_number_map())); 16943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 16953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 16963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1697ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateTwoByteString(Register result, 1698ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register length, 1699ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1700ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1701ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch3, 1702ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1703ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Calculate the number of bytes needed for the characters in the string while 1704ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // observing object alignment. 1705ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 1706ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org ASSERT(kShortSize == 2); 170713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // scratch1 = length * 2 + kObjectAlignmentMask. 170813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); 1709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, Immediate(~kObjectAlignmentMask)); 1710ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1711ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate two byte string in new space. 1712f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqTwoByteString::kHeaderSize, 1713f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 1714f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 1715f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_INT32, 1716f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 1717f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 1718f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 1719f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 1720f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 1721ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1722ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map, length and hash field. 1723ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->string_map())); 1725ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(scratch1, length); 1726ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org SmiTag(scratch1); 1727ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(FieldOperand(result, String::kLengthOffset), scratch1); 1728ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 1729ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Immediate(String::kEmptyHashField)); 1730ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1731ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1732ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1733ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result, 1734ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register length, 1735ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1736ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1737ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch3, 1738ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1739ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Calculate the number of bytes needed for the characters in the string while 1740ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // observing object alignment. 1741fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); 1742ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(scratch1, length); 1743ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org ASSERT(kCharSize == 1); 1744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(scratch1, Immediate(kObjectAlignmentMask)); 1745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, Immediate(~kObjectAlignmentMask)); 1746ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 17472efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allocate ASCII string in new space. 1748f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqOneByteString::kHeaderSize, 1749f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 1750f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 1751f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_INT32, 1752f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 1753f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 1754f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 1755f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 1756f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 1757ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1758ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map, length and hash field. 1759ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->ascii_string_map())); 1761ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(scratch1, length); 1762ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org SmiTag(scratch1); 1763ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(FieldOperand(result, String::kLengthOffset), scratch1); 1764ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 1765ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Immediate(String::kEmptyHashField)); 1766ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1767ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1768ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 17693cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result, 17703cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org int length, 17713cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Register scratch1, 17723cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Register scratch2, 17733cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Label* gc_required) { 17743cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org ASSERT(length > 0); 17753cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17762efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allocate ASCII string in new space. 17772bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, 17782bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org gc_required, TAG_OBJECT); 17793cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17803cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org // Set the map, length and hash field. 17813cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->ascii_string_map())); 17833cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, String::kLengthOffset), 17843cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Immediate(Smi::FromInt(length))); 17853cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 17863cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Immediate(String::kEmptyHashField)); 17873cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org} 17883cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17893cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17901805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteConsString(Register result, 1791ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1792ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1793ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1794ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate heap number in new space. 17952bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 17962bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 1797ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1798ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map. The other fields are left uninitialized. 1799ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 18007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->cons_string_map())); 1801ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1802ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1803ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1804ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateAsciiConsString(Register result, 1805ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1806ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1807ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 180857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 180957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 181057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 181157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 181257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 18137e6132b924829c353864933f29124419916db550machenbach@chromium.org TAG_OBJECT); 1814ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1815ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map. The other fields are left uninitialized. 1816ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 18177979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->cons_ascii_string_map())); 1818ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1819ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1820c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 18211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 182280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch1, 182380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch2, 182480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Label* gc_required) { 182580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Allocate heap number in new space. 18262bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 18272bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 182880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 182980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Set the map. The other fields are left uninitialized. 183080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 183180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Immediate(isolate()->factory()->sliced_string_map())); 183280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 183380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 183480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 183580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.orgvoid MacroAssembler::AllocateAsciiSlicedString(Register result, 183680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch1, 183780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch2, 183880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Label* gc_required) { 183980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Allocate heap number in new space. 18402bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 18412bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 184280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 184380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Set the map. The other fields are left uninitialized. 184480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 184580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Immediate(isolate()->factory()->sliced_ascii_string_map())); 184680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 184780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 184880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 1849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Copy memory, byte-by-byte, from source to destination. Not optimized for 1850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// long or aligned copies. The contents of scratch and length are destroyed. 1851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Source and destination are incremented by length. 1852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Many variants of movsb, loop unrolling, word moves, and indexed operands 1853c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// have been tried here already, and this is fastest. 1854c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// A simpler loop is faster on small copies, but 30% slower on large ones. 1855c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// The cld() instruction must have been emitted, to set the direction flag(), 1856c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// before calling this function. 1857c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid MacroAssembler::CopyBytes(Register source, 1858c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register destination, 1859c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register length, 1860c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register scratch) { 18610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label short_loop, len4, len8, len12, done, short_string; 1862c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(source.is(esi)); 1863c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(destination.is(edi)); 1864c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(length.is(ecx)); 18650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(4)); 18660cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below, &short_string, Label::kNear); 1867c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1868c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Because source is 4-byte aligned in our uses of this function, 1869c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // we keep source aligned for the rep_movs call by copying the odd bytes 1870c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // at the end of the ranges. 1871c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(scratch, Operand(source, length, times_1, -4)); 1872c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(Operand(destination, length, times_1, -4), scratch); 18730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 18740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(8)); 18750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len4, Label::kNear); 18760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(12)); 18770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len8, Label::kNear); 18780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(16)); 18790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len12, Label::kNear); 18800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 1881c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(scratch, ecx); 1882c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org shr(ecx, 2); 1883c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org rep_movs(); 1884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(0x3)); 1885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(destination, scratch); 18860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 18870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 18880cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len12); 18890cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(scratch, Operand(source, 8)); 18900cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(Operand(destination, 8), scratch); 18910cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len8); 18920cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(scratch, Operand(source, 4)); 18930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(Operand(destination, 4), scratch); 18940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len4); 18950cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(scratch, Operand(source, 0)); 18960cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(Operand(destination, 0), scratch); 18970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org add(destination, length); 18980cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 1899c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1900c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&short_string); 1901c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(length, length); 19020cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(zero, &done, Label::kNear); 1903c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1904c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&short_loop); 1905c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov_b(scratch, Operand(source, 0)); 1906c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov_b(Operand(destination, 0), scratch); 1907c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inc(source); 1908c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inc(destination); 1909c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org dec(length); 1910c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org j(not_zero, &short_loop); 1911c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1912c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&done); 191321b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org} 191421b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 1915ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InitializeFieldsWithFiller(Register start_offset, 1917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 1918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler) { 1919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 1920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&entry); 1921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&loop); 1922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand(start_offset, 0), filler); 1923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(start_offset, Immediate(kPointerSize)); 1924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&entry); 1925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(start_offset, end_offset); 1926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(less, &loop); 1927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1930394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MacroAssembler::BooleanBitTest(Register object, 1931394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int field_offset, 1932394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int bit_index) { 1933394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bit_index += kSmiTagSize + kSmiShiftSize; 1934394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(IsPowerOf2(kBitsPerByte)); 1935394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_index = bit_index / kBitsPerByte; 1936394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_bit_index = bit_index & (kBitsPerByte - 1); 1937394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com test_b(FieldOperand(object, field_offset + byte_index), 1938394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static_cast<byte>(1 << byte_bit_index)); 1939394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1940394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1941394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1942394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 194343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::NegativeZeroTest(Register result, 194443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op, 194543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label* then_label) { 194643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label ok; 1947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(result, result); 19487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &ok); 1949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(op, op); 19507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(sign, then_label); 195143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&ok); 195243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::NegativeZeroTest(Register result, 195643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op1, 195743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op2, 195843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register scratch, 195943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label* then_label) { 196043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label ok; 1961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(result, result); 19627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &ok); 1963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, op1); 1964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(scratch, op2); 19657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(sign, then_label); 196643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&ok); 196743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 196843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19707c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::TryGetFunctionPrototype(Register function, 19717c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Register result, 19727c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Register scratch, 1973394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 1974394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function) { 19757c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Check that the receiver isn't a smi. 19767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org JumpIfSmi(function, miss); 19777c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19787c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Check that the function really is a function. 19797be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpObjectType(function, JS_FUNCTION_TYPE, result); 19807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, miss); 19817c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 1982394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (miss_on_bound_function) { 1983394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If a bound function, go to miss label. 1984394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com mov(scratch, 1985394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 1986394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com BooleanBitTest(scratch, SharedFunctionInfo::kCompilerHintsOffset, 1987394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SharedFunctionInfo::kBoundFunction); 1988394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com j(not_zero, miss); 1989394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1990394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 19917c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Make sure that the function has an instance prototype. 19927c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Label non_instance; 19937c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset)); 19947c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); 19957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &non_instance); 19967c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19977c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Get the prototype or initial map from the function. 19987c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, 19997c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 20007c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 20017c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // If the prototype or initial map is the hole, don't return it and 20027c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // simply miss the cache instead. This will allow us to allocate a 20037c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // prototype object on-demand in the runtime system. 2004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(result, Immediate(isolate()->factory()->the_hole_value())); 20057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(equal, miss); 20067c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 20077c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // If the function does not have an initial map, we're done. 20087c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Label done; 20097be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpObjectType(result, MAP_TYPE, scratch); 20107c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org j(not_equal, &done); 20117c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 20127c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Get the prototype from the initial map. 20137c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, FieldOperand(result, Map::kPrototypeOffset)); 20147c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org jmp(&done); 20157c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 20167c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Non-instance prototype: Fetch prototype from constructor field 20177c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // in initial map. 20187c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org bind(&non_instance); 20197c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, FieldOperand(result, Map::kConstructorOffset)); 20207c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 20217c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // All done. 20227c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org bind(&done); 20237c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org} 20247c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 20257c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 2026471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 2027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs. 2028f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 202943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 203043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 203143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2032ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::TailCallStub(CodeStub* stub) { 2033f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org jmp(stub->GetCode(), RelocInfo::CODE_TARGET); 2034ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 2035ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2036ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 203743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::StubReturn(int argc) { 203843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(argc >= 1 && generating_stub()); 203943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ret((argc - 1) * kPointerSize); 204043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 204143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 204243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 20448a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org return has_frame_ || !stub->SometimesSetsUpAFrame(); 2045c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2046c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2047c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2048d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 2049d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The assert checks that the constants for the maximum number of digits 2050d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // for an array index cached in the hash field and the number of bits 2051d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // reserved for it does not conflict. 2052d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 2053d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org (1 << String::kArrayIndexValueBits)); 2054d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org if (!index.is(hash)) { 2055d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(index, hash); 2056d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 2057d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DecodeFieldToSmi<String::ArrayIndexValueBits>(index); 2058d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2059d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2060d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2061ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 2062fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int num_arguments, 2063fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles) { 206431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // If the expected number of arguments of the runtime function is 206531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // constant, we check that the actual number of arguments match the 206631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // expectation. 206729699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org CHECK(f->nargs < 0 || f->nargs == num_arguments); 206843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2069b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // TODO(1236192): Most runtime routines don't need the number of 2070b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // arguments passed in because it is constant. At some point we 2071b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // should remove this need and make the runtime routine entry code 2072b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // smarter. 2073a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(eax, Immediate(num_arguments)); 2074ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(f, isolate()))); 20753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org CEntryStub ces(isolate(), 1, save_doubles); 2076b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallStub(&ces); 207743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 207843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 207943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2080e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.orgvoid MacroAssembler::CallExternalReference(ExternalReference ref, 2081e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int num_arguments) { 2082e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org mov(eax, Immediate(num_arguments)); 2083e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org mov(ebx, Immediate(ref)); 2084e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 2085f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub stub(isolate(), 1); 2086e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org CallStub(&stub); 2087e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 2088e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 2089e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 2090ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 2091ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 2092ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 209331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // TODO(1236192): Most runtime routines don't need the number of 209431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // arguments passed in because it is constant. At some point we 209531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // should remove this need and make the runtime routine entry code 209631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // smarter. 2097a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(eax, Immediate(num_arguments)); 2098ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org JumpToExternalReference(ext); 2099ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2100ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2101ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2102ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 2103ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 2104ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 2105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TailCallExternalReference(ExternalReference(fid, isolate()), 2106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org num_arguments, 2107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result_size); 210843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 210943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 211043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2111662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgOperand ApiParameterOperand(int index) { 2112662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org return Operand(esp, index * kPointerSize); 2113c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 2114c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2115c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2116662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PrepareCallApiFunction(int argc) { 2117662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org EnterApiExitFrame(argc); 2118662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (emit_debug_code()) { 2119662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org mov(esi, Immediate(BitCast<int32_t>(kZapValue))); 2120303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 21214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 21224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 21232d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 2124528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::CallApiFunctionAndReturn( 2125e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Register function_address, 2126a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org ExternalReference thunk_ref, 2127528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand thunk_last_arg, 2128528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org int stack_space, 2129528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand return_value_operand, 2130528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand* context_restore_operand) { 2131303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference next_address = 213209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_next_address(isolate()); 2133303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference limit_address = 213409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_limit_address(isolate()); 2135303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference level_address = 213609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_level_address(isolate()); 21372d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 2138e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org ASSERT(edx.is(function_address)); 2139303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Allocate HandleScope in callee-save registers. 2140303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(ebx, Operand::StaticVariable(next_address)); 2141303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(edi, Operand::StaticVariable(limit_address)); 2142303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org add(Operand::StaticVariable(level_address), Immediate(1)); 2143303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 214483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 214583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 214683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 2147ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1, eax); 2148ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org mov(Operand(esp, 0), 2149ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2150ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 215183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 215283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 215383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 2154b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2155b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label profiler_disabled; 2156b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label end_profiler_check; 2157a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org mov(eax, Immediate(ExternalReference::is_profiling_address(isolate()))); 2158b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org cmpb(Operand(eax, 0), 0); 2159b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org j(zero, &profiler_disabled); 2160b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2161b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Additional parameter is the address of the actual getter function. 2162e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org mov(thunk_last_arg, function_address); 2163b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Call the api function. 2164a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org mov(eax, Immediate(thunk_ref)); 2165a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org call(eax); 2166b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org jmp(&end_profiler_check); 2167b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2168b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&profiler_disabled); 2169c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Call the api function. 2170e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org call(function_address); 2171b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&end_profiler_check); 21722d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 217383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 217483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 217583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 2176ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1, eax); 2177ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org mov(Operand(esp, 0), 2178ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2179ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); 218083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 218183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 218283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 2183303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label prologue; 2184bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Load the value from ReturnValue 2185528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(eax, return_value_operand); 2186bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org 2187303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label promote_scheduled_exception; 2188528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label exception_handled; 2189303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label delete_allocated_handles; 2190303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label leave_exit_frame; 2191303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 2192303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&prologue); 2193303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // No more valid handles (the result handle was the last one). Restore 2194303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // previous handle scope. 2195303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(Operand::StaticVariable(next_address), ebx); 2196303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org sub(Operand::StaticVariable(level_address), Immediate(1)); 2197594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(above_equal, kInvalidHandleScopeLevel); 2198303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmp(edi, Operand::StaticVariable(limit_address)); 21997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, &delete_allocated_handles); 2200303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&leave_exit_frame); 2201303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 2202303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Check if the function scheduled an exception. 2203303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference scheduled_exception_address = 2204ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::scheduled_exception_address(isolate()); 2205303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmp(Operand::StaticVariable(scheduled_exception_address), 2206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Immediate(isolate()->factory()->the_hole_value())); 22077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, &promote_scheduled_exception); 2208528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&exception_handled); 220967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 221067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#if ENABLE_EXTRA_CHECKS 221167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org // Check if the function returned a valid JavaScript value. 221267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Label ok; 221367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register return_value = eax; 221467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register map = ecx; 221567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 221667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org JumpIfSmi(return_value, &ok, Label::kNear); 221767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org mov(map, FieldOperand(return_value, HeapObject::kMapOffset)); 221867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 221967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_NONSTRING_TYPE); 222067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(below, &ok, Label::kNear); 222167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 222267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 222367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(above_equal, &ok, Label::kNear); 222467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 222567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(map, isolate()->factory()->heap_number_map()); 222667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 222767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 222867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->undefined_value()); 222967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 223067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 223167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->true_value()); 223267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 223367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 223467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->false_value()); 223567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 223667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 223767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->null_value()); 223867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 223967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 2240594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kAPICallReturnedInvalidObject); 224167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 224267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org bind(&ok); 224367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#endif 224467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 2245528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool restore_context = context_restore_operand != NULL; 2246528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 2247528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(esi, *context_restore_operand); 2248528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 2249528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveApiExitFrame(!restore_context); 22504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com ret(stack_space * kPointerSize); 2251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2252b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org bind(&promote_scheduled_exception); 2253528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org { 2254528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FrameScope frame(this, StackFrame::INTERNAL); 2255895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime(Runtime::kHiddenPromoteScheduledException, 0); 2256528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 2257528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&exception_handled); 2258b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org 2259303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // HandleScope limit has changed. Delete allocated extensions. 2260ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference delete_extensions = 2261ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::delete_handle_scope_extensions(isolate()); 2262303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&delete_allocated_handles); 2263303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(Operand::StaticVariable(limit_address), edi); 2264303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(edi, eax); 226532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org mov(Operand(esp, 0), 226632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2267ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(eax, Immediate(delete_extensions)); 2268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com call(eax); 2269303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(eax, edi); 2270303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(&leave_exit_frame); 2271c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 2272c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2273c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2274ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 227543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the entry point and jump to the C entry runtime stub. 22763bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(ebx, Immediate(ext)); 2277f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), 1); 2278f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 227943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 228143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 228243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 228343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 228443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> code_constant, 228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const Operand& code_operand, 228683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 22872efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 2288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 228983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance done_near, 2290e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool definitely_matches = false; 22922efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = false; 229343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label invoke; 229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expected.is_immediate()) { 229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(actual.is_immediate()); 229643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expected.immediate() == actual.immediate()) { 229743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen definitely_matches = true; 229843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 229943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(eax, actual.immediate()); 2300b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; 2301b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (expected.immediate() == sentinel) { 2302b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Don't worry about adapting arguments for builtins that 2303b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // don't want that done. Skip adaption code by making it look 2304b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // like we have a match between expected and actual number of 2305b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // arguments. 2306b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org definitely_matches = true; 2307b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 23082efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = true; 2309b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org mov(ebx, expected.immediate()); 2310b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 231143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 231243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 231343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (actual.is_immediate()) { 231443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expected is in register, actual is immediate. This is the 231543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // case when we invoke function values without going through the 231643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IC mechanism. 231743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cmp(expected.reg(), actual.immediate()); 231843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen j(equal, &invoke); 231943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(expected.reg().is(ebx)); 232043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(eax, actual.immediate()); 232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (!expected.reg().is(actual.reg())) { 232243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Both expected and actual are in (different) registers. This 232343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is the case when we invoke functions using call and apply. 2324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(expected.reg(), actual.reg()); 232543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen j(equal, &invoke); 232643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(actual.reg().is(eax)); 232743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(expected.reg().is(ebx)); 232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 232943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 233043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!definitely_matches) { 233243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> adaptor = 23337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->builtins()->ArgumentsAdaptorTrampoline(); 233443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!code_constant.is_null()) { 23353bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(edx, Immediate(code_constant)); 2336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 233743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (!code_operand.is_reg(edx)) { 233843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(edx, code_operand); 233943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 234043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (flag == CALL_FUNCTION) { 2342fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); 2343236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org call(adaptor, RelocInfo::CODE_TARGET); 2344fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org call_wrapper.AfterCall(); 23452efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!*definitely_mismatches) { 23462efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(done, done_near); 23472efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 234843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 2349236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org jmp(adaptor, RelocInfo::CODE_TARGET); 235043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 235143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&invoke); 235243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 235343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 235443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeCode(const Operand& code, 235743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& expected, 235843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2360e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 2361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 236483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 23652efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 2366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokePrologue(expected, actual, Handle<Code>::null(), code, 23672efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org &done, &definitely_mismatches, flag, Label::kNear, 2368e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org call_wrapper); 23692efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 23702efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 23712efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code)); 23722efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call(code); 23732efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 23742efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 23752efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(flag == JUMP_FUNCTION); 23762efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(code); 23772efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 23782efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 237943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 238043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 238243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 238343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeFunction(Register fun, 238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2386e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 2387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 239043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(fun.is(edi)); 239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 239343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 239430ce411529579186181838984710b0b0980857aaricow@chromium.org SmiUntag(ebx); 239543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParameterCount expected(ebx); 2397145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2398e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org expected, actual, flag, call_wrapper); 239943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 240043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24028a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Register fun, 240332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 24045c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 2405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2406e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 2407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 24108a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org ASSERT(fun.is(edi)); 24115c838251403b0be9a882540f1922577abba4c872ager@chromium.org mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2414e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org expected, actual, flag, call_wrapper); 24155c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 24165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 24175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 24188a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 24198a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& expected, 24208a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& actual, 24218a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org InvokeFlag flag, 2422e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 24238a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org LoadHeapObject(edi, function); 2424e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InvokeFunction(edi, expected, actual, flag, call_wrapper); 24258a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org} 24268a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 24278a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 2428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 2429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2430fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper) { 2431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a builtin without a valid frame. 2432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 243343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Rely on the assertion to check that the number of provided 243543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // arguments match the expected number of arguments. Fake a 243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parameter count to avoid emitting code to do the check. 243743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParameterCount expected(0); 2438145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(edi, id); 2439145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2440e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org expected, expected, flag, call_wrapper); 244143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 244243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2444145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinFunction(Register target, 2445145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com Builtins::JavaScript id) { 2446145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the JavaScript builtin function from the builtins object. 244746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 2448c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 2449145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com mov(target, FieldOperand(target, 2450145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com JSBuiltinsObject::OffsetOfFunctionWithId(id))); 2451145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com} 2452c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2454145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 2455145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com ASSERT(!target.is(edi)); 24565c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Load the JavaScript builtin function from the builtins object. 2457145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(edi, id); 2458145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the code entry point from the function into the target register. 2459145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 246043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 246243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2463ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 2464ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org if (context_chain_length > 0) { 2465ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Move up the chain of contexts to the context containing the slot. 24666d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org mov(dst, Operand(esi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2467ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int i = 1; i < context_chain_length; i++) { 24686d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org mov(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2469ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 247083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 247183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Slot is in the current function context. Move it into the 247283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // destination register in case we store into it (the write barrier 247383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // cannot be allowed to destroy the context in esi). 247483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org mov(dst, esi); 247583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 247683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 24774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // We should not have found a with context by walking the context chain 24784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // (i.e., the static scope chain and runtime context chain do not agree). 24794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // A variable occurring in such a scope should have slot type LOOKUP and 24804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // not CONTEXT. 2481badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 24823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org cmp(FieldOperand(dst, HeapObject::kMapOffset), 24833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org isolate()->factory()->with_context_map()); 2484594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kVariableResolvedToWithContext); 2485ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 2486ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 2487ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2488ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 24891145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadTransitionedArrayMapConditional( 24901145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 24911145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 24921145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 24931145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 24941145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match) { 24951145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Load the global or builtins object from the current context. 249646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(scratch, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 249746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 24981145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24991145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Check that the function's map is the same as the expected cached map. 2500830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org mov(scratch, Operand(scratch, 2501830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); 2502830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 2503830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org size_t offset = expected_kind * kPointerSize + 2504830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 2505830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org cmp(map_in_out, FieldOperand(scratch, offset)); 25061145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org j(not_equal, no_map_match); 25071145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 25081145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Use the transitioned cached map. 2509830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org offset = transitioned_kind * kPointerSize + 2510830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 2511830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org mov(map_in_out, FieldOperand(scratch, offset)); 25121145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org} 25131145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 25141145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 2515d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::LoadGlobalFunction(int index, Register function) { 2516d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Load the global or builtins object from the current context. 251746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(function, 251846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 251946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 25204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org mov(function, 25214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org FieldOperand(function, GlobalObject::kNativeContextOffset)); 252246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 2523d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(function, Operand(function, Context::SlotOffset(index))); 2524d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2525d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2526d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2527d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 2528d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Register map) { 2529d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Load the initial map. The global functions all have initial maps. 2530d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2531badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 2532d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label ok, fail; 2533c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 2534d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org jmp(&ok); 2535d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org bind(&fail); 2536594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kGlobalFunctionsMustHaveInitialMap); 2537d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org bind(&ok); 2538d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 2539d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2540d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2541ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 25423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// Store the value in register src in the safepoint register stack 25433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// slot for register dst. 25443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 25453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(SafepointRegisterSlot(dst), src); 25463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Immediate src) { 25503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(SafepointRegisterSlot(dst), src); 25513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 25553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(dst, SafepointRegisterSlot(src)); 25563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 25603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return Operand(esp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 25613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint MacroAssembler::SafepointRegisterStackIndex(int reg_code) { 2565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // The registers are pushed starting with the lowest encoding, 2566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // which means that lowest encodings are furthest away from 2567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the stack pointer. 2568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); 2569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return kNumSafepointRegisters - reg_code - 1; 2570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 257364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MacroAssembler::LoadHeapObject(Register result, 257464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<HeapObject> object) { 257579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference embedding_raw_address; 257664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 257741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 257841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org mov(result, Operand::ForCell(cell)); 257964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 258064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org mov(result, object); 258164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 258264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 258364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 258464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 2585a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) { 258679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 2587a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 258841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 258941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org cmp(reg, Operand::ForCell(cell)); 2590a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 2591a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org cmp(reg, object); 2592a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 2593a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 2594a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 2595a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 259664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MacroAssembler::PushHeapObject(Handle<HeapObject> object) { 259779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 259864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 259941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 260041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org push(Operand::ForCell(cell)); 260164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 260264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Push(object); 260364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 260464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 260564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 260664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 260743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::Ret() { 260843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ret(0); 260943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 261043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 261143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2612d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2613d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (is_uint16(bytes_dropped)) { 2614d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(bytes_dropped); 2615d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 2616d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com pop(scratch); 2617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(bytes_dropped)); 2618d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com push(scratch); 2619d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(0); 2620d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 2621d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 2622d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 2623d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 262413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::Drop(int stack_elements) { 262513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org if (stack_elements > 0) { 2626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(stack_elements * kPointerSize)); 262713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } 262813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 262913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 263013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 26314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid MacroAssembler::Move(Register dst, Register src) { 26324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!dst.is(src)) { 26334a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org mov(dst, src); 26344a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 26354a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 26364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 26374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 2638a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid MacroAssembler::Move(Register dst, const Immediate& x) { 2639a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (x.is_zero()) { 2640a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org xor_(dst, dst); // Shorter than mov of 32-bit immediate 0. 2641486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else { 2642a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org mov(dst, x); 2643486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 2644486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org} 2645486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 2646486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 2647a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid MacroAssembler::Move(const Operand& dst, const Immediate& x) { 2648a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org mov(dst, x); 2649a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org} 2650a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 2651a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 2652fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgvoid MacroAssembler::Move(XMMRegister dst, double val) { 2653fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // TODO(titzer): recognize double constants with ExternalReferences. 2654fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org uint64_t int_val = BitCast<uint64_t, double>(val); 2655fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (int_val == 0) { 2656fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org xorps(dst, dst); 2657fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } else { 2658fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int32_t lower = static_cast<int32_t>(int_val); 2659fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); 2660fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org push(Immediate(upper)); 2661fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org push(Immediate(lower)); 2662fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org movsd(dst, Operand(esp, 0)); 2663fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org add(esp, Immediate(kDoubleSize)); 2664fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 2665fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org} 2666fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 2667fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 266843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 266943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 267043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(Operand::StaticVariable(ExternalReference(counter)), Immediate(value)); 267143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 267243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 267343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 267643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(value > 0); 267743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 267843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Operand operand = Operand::StaticVariable(ExternalReference(counter)); 267943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value == 1) { 268043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inc(operand); 268143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 268243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen add(operand, Immediate(value)); 268343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 268443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 268543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 268643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 268943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(value > 0); 269043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 269143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Operand operand = Operand::StaticVariable(ExternalReference(counter)); 269243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value == 1) { 269343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dec(operand); 269443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 269543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen sub(operand, Immediate(value)); 269643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 269743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 269843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 269943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2701b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::IncrementCounter(Condition cc, 2702b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org StatsCounter* counter, 2703b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int value) { 2704b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(value > 0); 2705b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 2706b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label skip; 2707b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(NegateCondition(cc), &skip); 2708b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org pushfd(); 2709b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org IncrementCounter(counter, value); 2710b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org popfd(); 2711b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bind(&skip); 2712b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2713b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2714b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2715b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2716b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::DecrementCounter(Condition cc, 2717b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org StatsCounter* counter, 2718b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int value) { 2719b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(value > 0); 2720b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 2721b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label skip; 2722b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(NegateCondition(cc), &skip); 2723b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org pushfd(); 2724b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DecrementCounter(counter, value); 2725b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org popfd(); 2726b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bind(&skip); 2727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2728b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2729b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2730b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2731594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 2732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (emit_debug_code()) Check(cc, reason); 273343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 273443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27360b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MacroAssembler::AssertFastElements(Register elements) { 2737badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 27387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Factory* factory = isolate()->factory(); 27390b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Label ok; 27400b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 27417979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(factory->fixed_array_map())); 27420b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org j(equal, &ok); 27430b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 274484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org Immediate(factory->fixed_double_array_map())); 274584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org j(equal, &ok); 274684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 27477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(factory->fixed_cow_array_map())); 27480b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org j(equal, &ok); 2749594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kJSObjectWithFastElementsMapHasSlowElements); 27500b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org bind(&ok); 27510b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 27520b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org} 27530b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 27540b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 2755594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 275643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label L; 27577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(cc, &L); 2758594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(reason); 275943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will not return here 276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&L); 276143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 276243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 276343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2764c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgvoid MacroAssembler::CheckStackAlignment() { 2765c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 2766c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment_mask = frame_alignment - 1; 2767c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org if (frame_alignment > kPointerSize) { 2768c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 2769c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org Label alignment_as_expected; 2770c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org test(esp, Immediate(frame_alignment_mask)); 2771c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org j(zero, &alignment_as_expected); 2772c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Abort if stack is not aligned. 2773c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int3(); 2774c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org bind(&alignment_as_expected); 2775c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 2776c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org} 2777c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2778c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2779594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Abort(BailoutReason reason) { 2780052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org#ifdef DEBUG 2781f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const char* msg = GetBailoutReason(reason); 278243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (msg != NULL) { 278343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RecordComment("Abort message: "); 278443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RecordComment(msg); 278543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 27861e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 27871e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (FLAG_trap_on_abort) { 27881e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int3(); 27891e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return; 27901e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 279143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 2792ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2793f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(reason)))); 2794c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Disable stub call restrictions to always allow calls to abort. 2795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!has_frame_) { 2796c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't actually want to generate a pile of code for this, so just 2797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // claim there is a stack frame, without generating one. 2798c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(this, StackFrame::NONE); 2799f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(Runtime::kAbort, 1); 2800c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2801f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(Runtime::kAbort, 1); 2802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will not return here 2804ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org int3(); 280543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 280643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::LoadInstanceDescriptors(Register map, 280940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Register descriptors) { 281089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org mov(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 281140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 281240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 281340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 281406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 281506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org mov(dst, FieldOperand(map, Map::kBitField3Offset)); 281606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 281706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org} 281806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 281906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 2820c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::LoadPowerOf2(XMMRegister dst, 2821c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register scratch, 2822c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org int power) { 2823c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org ASSERT(is_uintn(power + HeapNumber::kExponentBias, 2824c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org HeapNumber::kExponentBits)); 2825c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org mov(scratch, Immediate(power + HeapNumber::kExponentBias)); 2826c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movd(dst, scratch); 2827c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org psllq(dst, HeapNumber::kMantissaBits); 2828c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 2829c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 2830c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 2831528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LookupNumberStringCache(Register object, 2832528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register result, 2833528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch1, 2834528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch2, 2835528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label* not_found) { 2836528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Use of registers. Register result is used as a temporary. 2837528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register number_string_cache = result; 2838528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register mask = scratch1; 2839528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch = scratch2; 2840528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2841528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Load the number string cache. 2842528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 2843528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Make the hash mask from the length of the number string cache. It 2844528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // contains two elements (number and string) for each cache entry. 2845528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 2846528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org shr(mask, kSmiTagSize + 1); // Untag length and divide it by two. 2847528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org sub(mask, Immediate(1)); // Make mask. 2848528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2849528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Calculate the entry in the number string cache. The hash value in the 2850528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // number string cache for smis is just the smi value, and the hash for 2851528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // doubles is the xor of the upper and lower words. See 2852528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Heap::GetNumberStringCache. 2853528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label smi_hash_calculated; 2854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label load_result_from_cache; 2855528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label not_smi; 2856528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 2857528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfNotSmi(object, ¬_smi, Label::kNear); 2858528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(scratch, object); 2859528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmiUntag(scratch); 2860528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&smi_hash_calculated, Label::kNear); 2861528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(¬_smi); 2862528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cmp(FieldOperand(object, HeapObject::kMapOffset), 2863528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org isolate()->factory()->heap_number_map()); 2864528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); 2865528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(8 == kDoubleSize); 2866528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 2867528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 2868528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Object is heap number and hash is now in scratch. Calculate cache index. 2869528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org and_(scratch, mask); 2870528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register index = scratch; 2871528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register probe = mask; 2872528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(probe, 2873528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2874528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2875528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_twice_pointer_size, 2876528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2877528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfSmi(probe, not_found); 28783c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 28793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); 2880528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(parity_even, not_found); // Bail out if NaN is involved. 2881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); // The cache did not contain this value. 2882528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&load_result_from_cache, Label::kNear); 2883528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2884528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&smi_hash_calculated); 2885528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Object is smi and hash is now in scratch. Calculate cache index. 2886528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org and_(scratch, mask); 2887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the entry is the smi we are looking for. 2888528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cmp(object, 2889528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2890528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2891528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_twice_pointer_size, 2892528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2893528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); 2894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2895528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Get the result from the cache. 2896528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&load_result_from_cache); 2897528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(result, 2898528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2899528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2900528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_twice_pointer_size, 2901528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize + kPointerSize)); 2902528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org IncrementCounter(isolate()->counters()->number_to_string_native(), 1); 2903528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 2904528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2905528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 29065c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( 29075c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register instance_type, 29085c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch, 2909cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org Label* failure) { 29105c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (!scratch.is(instance_type)) { 29115c838251403b0be9a882540f1922577abba4c872ager@chromium.org mov(scratch, instance_type); 29125c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 29135c838251403b0be9a882540f1922577abba4c872ager@chromium.org and_(scratch, 29145c838251403b0be9a882540f1922577abba4c872ager@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 2915e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org cmp(scratch, kStringTag | kSeqStringTag | kOneByteStringTag); 29165c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, failure); 29175c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 29185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 29195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2920b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register object1, 2921b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register object2, 2922b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register scratch1, 2923b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register scratch2, 2924b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label* failure) { 2925b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check that both objects are not smis. 292680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 2927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch1, object1); 2928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, object2); 29297b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org JumpIfSmi(scratch1, failure); 2930b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2931b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Load instance type for both strings. 2932b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org mov(scratch1, FieldOperand(object1, HeapObject::kMapOffset)); 2933b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org mov(scratch2, FieldOperand(object2, HeapObject::kMapOffset)); 2934b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzx_b(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2935b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzx_b(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2936b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 29372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check that both are flat ASCII strings. 293846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org const int kFlatAsciiStringMask = 293946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2940c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org const int kFlatAsciiStringTag = 2941c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 2942b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Interleave bits from both instance types and compare them in one check. 294346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 2944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org and_(scratch1, kFlatAsciiStringMask); 2945b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org and_(scratch2, kFlatAsciiStringMask); 294646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org lea(scratch1, Operand(scratch1, scratch2, times_8, 0)); 294746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 3)); 2948b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(not_equal, failure); 2949b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2950b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2951b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 29521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Operand operand, 29531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 29541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 2955ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2956ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label succeed; 2957ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org test(operand, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2958ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(zero, &succeed); 2959ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cmpb(operand, static_cast<uint8_t>(SYMBOL_TYPE)); 2960ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(not_equal, not_unique_name, distance); 2961ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2962ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org bind(&succeed); 29631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 29641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 29651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 29669af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 29679af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index, 29689af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value, 29699af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org uint32_t encoding_mask) { 29709af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Label is_object; 29719af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org JumpIfNotSmi(string, &is_object, Label::kNear); 297205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Abort(kNonObject); 29739af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org bind(&is_object); 29749af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29759af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org push(value); 29769af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org mov(value, FieldOperand(string, HeapObject::kMapOffset)); 29779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); 29789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29799af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 29809af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmp(value, Immediate(encoding_mask)); 29819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org pop(value); 298205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(equal, kUnexpectedStringType); 29839af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29849af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // The index is assumed to be untagged coming in, tag it to compare with the 29859af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // string length without using a temp register, it is restored at the end of 29869af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // this function. 29879af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiTag(index); 298805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(no_overflow, kIndexIsTooLarge); 29899af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29909af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmp(index, FieldOperand(string, String::kLengthOffset)); 299105150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(less, kIndexIsTooLarge); 29929af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29939af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmp(index, Immediate(Smi::FromInt(0))); 299405150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(greater_equal, kIndexIsNegative); 29959af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29969af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // Restore the index 29979af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiUntag(index); 29989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org} 29999af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 30009af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 3001ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { 3002c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 3003c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (frame_alignment != 0) { 3004ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Make stack end at alignment and make room for num_arguments words 3005ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // and the original value of esp. 3006ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(scratch, esp); 3007c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate((num_arguments + 1) * kPointerSize)); 3008c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 3009c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org and_(esp, -frame_alignment); 3010ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(Operand(esp, num_arguments * kPointerSize), scratch); 3011ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 3012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(num_arguments * kPointerSize)); 3013ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 3014ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 3015ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3016ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3017ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::CallCFunction(ExternalReference function, 3018ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments) { 3019ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Trashing eax is ok as it will be the return value. 3020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(eax, Immediate(function)); 3021ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org CallCFunction(eax, num_arguments); 3022ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 3023ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3024ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3025ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::CallCFunction(Register function, 3026ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments) { 3027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(has_frame()); 3028c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check stack alignment. 3029badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 3030c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org CheckStackAlignment(); 3031c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 3032c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 3033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com call(function); 3034ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (OS::ActivationFrameAlignment() != 0) { 3035ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(esp, Operand(esp, num_arguments * kPointerSize)); 3036ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 3037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(num_arguments * kPointerSize)); 3038ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 3039ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 3040ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3041ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4) { 3043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r2)) return true; 3044c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r3)) return true; 3045c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r4)) return true; 3046c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r3)) return true; 3047c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r4)) return true; 3048c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r3.is(r4)) return true; 3049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 3050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3052c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 305343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCodePatcher::CodePatcher(byte* address, int size) 3054c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : address_(address), 3055c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_(size), 3056212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org masm_(NULL, address, size + Assembler::kGap) { 30573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Create a new macro assembler pointing to the address of the code to patch. 305843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The size is adjusted with kGap on order for the assembler to generate size 305943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bytes of instructions without failing with buffer size constraints. 306043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 306143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 306243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 306343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 306443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCodePatcher::~CodePatcher() { 306543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Indicate that code has changed. 306643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CPU::FlushICache(address_, size_); 306743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 306843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that the code was patched as expected. 306943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(masm_.pc_ == address_ + size_); 307043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 307143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 307243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 307343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckPageFlag( 3075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 3076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 3077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 3078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 3079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 3080c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 3081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cc == zero || cc == not_zero); 3082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 3083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 3084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Immediate(~Page::kPageAlignmentMask)); 3086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 3087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mask < (1 << kBitsPerByte)) { 3089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(scratch, MemoryChunk::kFlagsOffset), 3090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<uint8_t>(mask)); 3091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 3093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 30957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org} 30967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 30977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 30987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid MacroAssembler::CheckPageFlagForMap( 30997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map, 31007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int mask, 31017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Condition cc, 31027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label* condition_met, 31037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::Distance condition_met_distance) { 31047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(cc == zero || cc == not_zero); 31057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Page* page = Page::FromAddress(map->address()); 31067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference reference(ExternalReference::page_flags(page)); 31077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // The inlined static address check of the page's flags relies 31087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // on maps never being compacted. 31097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!isolate()->heap()->mark_compact_collector()-> 31107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org IsOnEvacuationCandidate(*map)); 31117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (mask < (1 << kBitsPerByte)) { 31127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test_b(Operand::StaticVariable(reference), static_cast<uint8_t>(mask)); 31137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 31147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test(Operand::StaticVariable(reference), Immediate(mask)); 31157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 31167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org j(cc, condition_met, condition_met_distance); 3117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3120f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid MacroAssembler::CheckMapDeprecated(Handle<Map> map, 3121f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 3122f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated) { 3123f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (map->CanBeDeprecated()) { 3124f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org mov(scratch, map); 3125f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org mov(scratch, FieldOperand(scratch, Map::kBitField3Offset)); 31263c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org and_(scratch, Immediate(Map::Deprecated::kMask)); 3127f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org j(not_zero, if_deprecated); 3128f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 3129f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 3130f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 3131f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 3132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfBlack(Register object, 3133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0, 3134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 3135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 3136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_near) { 3137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HasColor(object, scratch0, scratch1, 3138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com on_black, on_black_near, 3139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 0); // kBlackBitPattern. 3140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 3141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::HasColor(Register object, 3145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 3146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 3147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* has_color, 3148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance has_color_distance, 3149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int first_bit, 3150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int second_bit) { 3151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object, bitmap_scratch, mask_scratch, ecx)); 3152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(object, bitmap_scratch, mask_scratch); 3154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label other_color, word_boundary; 3156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(first_bit == 1 ? zero : not_zero, &other_color, Label::kNear); 3158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(mask_scratch, mask_scratch); // Shift left 1 by adding. 3159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &word_boundary, Label::kNear); 3160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); 3162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&other_color, Label::kNear); 3163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&word_boundary); 3165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize), 1); 3166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); 3168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&other_color); 3169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::GetMarkBits(Register addr_reg, 3173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 3174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg) { 3175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(addr_reg, mask_reg, bitmap_reg, ecx)); 3176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 3177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_reg, addr_reg); 3178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ecx, addr_reg); 3179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int shift = 3180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 3181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(ecx, shift); 3182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(ecx, 3183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (Page::kPageAlignmentMask >> shift) & ~(Bitmap::kBytesPerCell - 1)); 3184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(bitmap_reg, ecx); 3186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ecx, addr_reg); 3187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(ecx, kPointerSizeLog2); 3188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(ecx, (1 << Bitmap::kBitsPerCellLog2) - 1); 3189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(mask_reg, Immediate(1)); 3190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shl_cl(mask_reg); 3191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::EnsureNotWhite( 3195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 3196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 3197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 3198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* value_is_white_and_not_data, 3199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 3200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, ecx)); 3201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(value, bitmap_scratch, mask_scratch); 3202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the value is black or grey we don't need to do anything. 3204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 3205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 3206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 3207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 3208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 3210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Since both black and grey have a 1 in the first position and white does 3212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not have a 1 there we only need to check one bit. 3213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, &done, Label::kNear); 3215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3216000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 3217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for impossible bit pattern. 3218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 3219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com push(mask_scratch); 3220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // shl. May overflow making the check conservative. 3221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(mask_scratch, mask_scratch); 3222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 3224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 3225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 3226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pop(mask_scratch); 3227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is white. We check whether it is data that doesn't need scanning. 3230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Currently only checks for HeapNumber and non-cons strings. 3231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register map = ecx; // Holds map while checking type. 3232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register length = ecx; // Holds length of object after checking type. 3233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_heap_number; 3234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 3235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for heap-number 3237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(map, FieldOperand(value, HeapObject::kMapOffset)); 3238d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org cmp(map, isolate()->factory()->heap_number_map()); 3239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, ¬_heap_number, Label::kNear); 3240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Immediate(HeapNumber::kSize)); 3241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 3242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_heap_number); 3244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for strings. 3245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 3246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 3247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 3248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 3249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register instance_type = ecx; 3250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 3251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(instance_type, kIsIndirectStringMask | kIsNotStringMask); 3252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, value_is_white_and_not_data); 3253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It's a non-indirect (non-cons and non-slice) string. 3254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's external, the length is just ExternalString::kSize. 3255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). 3256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_external; 3257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // External strings are the only ones with the kExternalStringTag bit 3258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // set. 3259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); 3260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 3261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(instance_type, kExternalStringTag); 3262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_external, Label::kNear); 3263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Immediate(ExternalString::kSize)); 3264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 3265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_external); 3267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sequential string, either ASCII or UC16. 3268e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(kOneByteStringTag == 0x04); 3269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(kStringEncodingMask)); 3270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xor_(length, Immediate(kStringEncodingMask)); 3271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(length, Immediate(0x04)); 3272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value now either 4 (if ASCII) or 8 (if UC16), i.e., char-size shifted 3273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // by 2. If we multiply the string length as smi by this, it still 3274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // won't overflow a 32-bit value. 3275fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT_EQ(SeqOneByteString::kMaxSize, SeqTwoByteString::kMaxSize); 3276fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT(SeqOneByteString::kMaxSize <= 3277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<int>(0xffffffffu >> (2 + kSmiTagSize))); 3278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com imul(length, FieldOperand(value, String::kLengthOffset)); 3279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(length, 2 + kSmiTagSize + kSmiShiftSize); 3280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 3281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(~kObjectAlignmentMask)); 3282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 3284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a data object, and it is white. Mark it black. Since we know 3285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that the object is white we can make it black by flipping one bit. 3286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 3287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 3289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), 3290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com length); 3291000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 3292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset)); 3293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); 3294594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(less_equal, kLiveBytesCountOverflowChunkSize); 3295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 3298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3300be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3301355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid MacroAssembler::EnumLength(Register dst, Register map) { 3302355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3303355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(dst, FieldOperand(map, Map::kBitField3Offset)); 33043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org and_(dst, Immediate(Map::EnumLengthBits::kMask)); 33053c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org SmiTag(dst); 3306355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 3307355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3308355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3309be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid MacroAssembler::CheckEnumCache(Label* call_runtime) { 3310355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label next, start; 3311be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ecx, eax); 3312be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3313355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check if the enum length field is properly initialized, indicating that 3314355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // there is an enum cache. 3315be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 3316be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3317355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(edx, ebx); 3318af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org cmp(edx, Immediate(Smi::FromInt(kInvalidEnumCacheSentinel))); 3319de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org j(equal, call_runtime); 3320de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 3321355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org jmp(&start); 3322355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3323355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&next); 3324355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 3325be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3326be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For all objects but the receiver, check that the cache is empty. 3327355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(edx, ebx); 3328355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(edx, Immediate(Smi::FromInt(0))); 3329355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org j(not_equal, call_runtime); 3330355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3331355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&start); 3332355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3333355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check that there are no elements. Register rcx contains the current JS 3334355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // object we've reached through the prototype chain. 33356d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Label no_elements; 3336355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset)); 3337355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(ecx, isolate()->factory()->empty_fixed_array()); 33386d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org j(equal, &no_elements); 33396d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org 33406d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org // Second chance, the object may be using the empty slow element dictionary. 33416d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org cmp(ecx, isolate()->factory()->empty_slow_element_dictionary()); 3342be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, call_runtime); 3343be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 33446d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bind(&no_elements); 3345be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 3346be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org cmp(ecx, isolate()->factory()->null_value()); 3347be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, &next); 3348be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 3349be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 335059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 3351ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MacroAssembler::TestJSArrayForAllocationMemento( 335259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Register receiver_reg, 3353b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Register scratch_reg, 3354b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label* no_memento_found) { 335559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_start = 335659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_start(isolate()); 335759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_allocation_top = 335859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 335959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 336059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org lea(scratch_reg, Operand(receiver_reg, 3361ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); 336259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmp(scratch_reg, Immediate(new_space_start)); 3363b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(less, no_memento_found); 336459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmp(scratch_reg, Operand::StaticVariable(new_space_allocation_top)); 3365b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(greater, no_memento_found); 3366ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), 3367528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Immediate(isolate()->factory()->allocation_memento_map())); 336859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 336959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 337059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 3371e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 3372e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register object, 3373e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch0, 3374e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch1, 3375e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* found) { 3376e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!scratch1.is(scratch0)); 3377e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Factory* factory = isolate()->factory(); 3378e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register current = scratch0; 3379e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label loop_again; 3380e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 3381e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // scratch contained elements pointer. 3382e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(current, object); 3383e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 3384e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loop based on the map going up the prototype chain. 3385e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&loop_again); 3386e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(current, FieldOperand(current, HeapObject::kMapOffset)); 3387e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(scratch1, FieldOperand(current, Map::kBitField2Offset)); 3388d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DecodeField<Map::ElementsKindBits>(scratch1); 3389e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org cmp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 3390e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(equal, found); 3391e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(current, FieldOperand(current, Map::kPrototypeOffset)); 3392e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org cmp(current, Immediate(factory->null_value())); 3393e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(not_equal, &loop_again); 3394e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 3395e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 3396bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 3397763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 3398bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(!dividend.is(eax)); 3399bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(!dividend.is(edx)); 3400bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org MultiplierAndShift ms(divisor); 3401bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org mov(eax, Immediate(ms.multiplier())); 3402bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org imul(dividend); 3403bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor > 0 && ms.multiplier() < 0) add(edx, dividend); 3404bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor < 0 && ms.multiplier() > 0) sub(edx, dividend); 3405bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (ms.shift() > 0) sar(edx, ms.shift()); 3406763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org mov(eax, dividend); 3407763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org shr(eax, 31); 3408763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org add(edx, eax); 3409bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 3410bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 3411bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 341243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 34139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 3415