1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "bootstrapper.h" 3344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h" 34c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h" 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "runtime.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "serialize.h" 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 427be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// ------------------------------------------------------------------------- 437be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// MacroAssembler implementation. 447be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 45c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) 46c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : Assembler(arg_isolate, buffer, size), 477276f14ca716596e0a0d17539516370c1f453847kasper.lund generating_stub_(false), 48c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com allow_stub_calls_(true), 49c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com has_frame_(false) { 50c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (isolate() != NULL) { 51c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), 52c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org isolate()); 53c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 57594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 58594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (isolate()->heap()->RootCanBeTreatedAsConstant(index)) { 59594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 60594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, value); 61594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 62594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 63594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 64594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 65594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, Immediate(index)); 66594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, Operand::StaticArray(destination, 67594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org times_pointer_size, 68594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org roots_array_start)); 69594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 70594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 71594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 72594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::StoreRoot(Register source, 73594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register scratch, 74594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 75594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(Heap::RootCanBeWrittenAfterInitialization(index)); 76594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 77594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 78594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(scratch, Immediate(index)); 79594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start), 80594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org source); 81594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 82594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 83594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 84594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(Register with, 85594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register scratch, 86594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex 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 cmp(with, Operand::StaticArray(scratch, 91594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org times_pointer_size, 92594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org roots_array_start)); 93594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 94594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 95594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 96594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 97594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(isolate()->heap()->RootCanBeTreatedAsConstant(index)); 98594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 99594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, value); 100594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 101594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 102594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 103594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(const Operand& with, 104594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(isolate()->heap()->RootCanBeTreatedAsConstant(index)); 106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 107594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, value); 108594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 109594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 110594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InNewSpace( 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cc == equal || cc == not_equal); 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Immediate(~Page::kPageAlignmentMask)); 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 123ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that we can use a test_b. 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MemoryChunk::IN_FROM_SPACE < 8); 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MemoryChunk::IN_TO_SPACE < 8); 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask = (1 << MemoryChunk::IN_FROM_SPACE) 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com | (1 << MemoryChunk::IN_TO_SPACE); 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If non-zero, the page belongs to new-space. 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(scratch, MemoryChunk::kFlagsOffset), 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<uint8_t>(mask)); 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 134ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 13530ce411529579186181838984710b0b0980857aaricow@chromium.org 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RememberedSetHelper( 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, // Only used for debug checks. 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler::RememberedSetFinalAction and_then) { 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 143000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load store buffer top. 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference store_buffer = 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::store_buffer_top(isolate()); 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Operand::StaticVariable(store_buffer)); 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store pointer to buffer. 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand(scratch, 0), addr); 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Increment buffer top. 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(scratch, Immediate(kPointerSize)); 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Write back new top of buffer. 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand::StaticVariable(store_buffer), scratch); 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call stub on end of buffer. 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for end of buffer. 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label buffer_overflowed; 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, &buffer_overflowed, Label::kNear); 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&buffer_overflowed); 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &done, Label::kNear); 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferOverflowStub store_buffer_overflow = 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferOverflowStub(save_fp); 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&store_buffer_overflow); 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 183c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 184c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister scratch_reg, 185c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register result_reg) { 186c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 18789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Label conv_failure; 18889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org pxor(scratch_reg, scratch_reg); 18946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cvtsd2si(result_reg, input_reg); 190c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org test(result_reg, Immediate(0xFFFFFF00)); 191c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 19289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org cmp(result_reg, Immediate(0x80000000)); 19389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(equal, &conv_failure, Label::kNear); 19489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org mov(result_reg, Immediate(0)); 19589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org setcc(above, result_reg); 19689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org sub(result_reg, Immediate(1)); 19789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org and_(result_reg, Immediate(255)); 19889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org jmp(&done, Label::kNear); 19989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org bind(&conv_failure); 20089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Set(result_reg, Immediate(0)); 20189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ucomisd(input_reg, scratch_reg); 20289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(below, &done, Label::kNear); 203c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Set(result_reg, Immediate(255)); 204c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 205c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 206c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 207c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 208c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampUint8(Register reg) { 209c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 210c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org test(reg, Immediate(0xFFFFFF00)); 211c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 212c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org setcc(negative, reg); // 1 if negative, 0 if positive. 213c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org dec_b(reg); // 0 if negative, 255 if positive. 214c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 215c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 216c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 217c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 21846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic double kUint32Bias = 21946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1; 22046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 22146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 22246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::LoadUint32(XMMRegister dst, 22346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Register src, 22446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org XMMRegister scratch) { 22546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Label done; 22646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cmp(src, Immediate(0)); 22746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movdbl(scratch, 22859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Operand(reinterpret_cast<int32_t>(&kUint32Bias), RelocInfo::NONE32)); 22946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cvtsi2sd(dst, src); 23046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org j(not_sign, &done, Label::kNear); 23146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org addsd(dst, scratch); 23246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org bind(&done); 23346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 23446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 23546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteArray(Register object, 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register index, 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check) { 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kSmiTag); 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(value, Immediate(kSmiTagMask)); 250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &done); 251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Array access: calculate the destination address in the same manner as 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // into an array of words. 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst = index; 257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, Operand(object, index, times_half_pointer_size, 258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FixedArray::kHeaderSize - kHeapObjectTag)); 259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWrite( 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // turned on to provoke errors. 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(value, Immediate(BitCast<int32_t>(kZapValue))); 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(index, Immediate(BitCast<int32_t>(kZapValue))); 27083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 27183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 27283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 27383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteField( 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst, 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check) { 28230ce411529579186181838984710b0b0980857aaricow@chromium.org // First, check if a write barrier is even needed. The tests below 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 28483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 286b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org // Skip barrier if writing a smi. 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done, Label::kNear); 289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Although the object register is tagged, the offset is relative to the start 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the object, so so offset must be a multiple of kPointerSize. 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(offset, kPointerSize)); 294e88a9edffbbdbc4ccc9872560ac4d9ea6b188fbdwhesse@chromium.org 295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, FieldOperand(object, offset)); 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(dst, (1 << kPointerSizeLog2) - 1); 299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWrite( 305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&done); 308b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 310b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // turned on to provoke errors. 311badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 312f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org mov(value, Immediate(BitCast<int32_t>(kZapValue))); 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(dst, Immediate(BitCast<int32_t>(kZapValue))); 314b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid MacroAssembler::RecordWriteForMap( 3197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register object, 3207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map, 3217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register scratch1, 3227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register scratch2, 3237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org SaveFPRegsMode save_fp) { 3247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label done; 3257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register address = scratch1; 3277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register value = scratch2; 3287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (emit_debug_code()) { 3297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label ok; 3307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org lea(address, FieldOperand(object, HeapObject::kMapOffset)); 3317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test_b(address, (1 << kPointerSizeLog2) - 1); 3327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org j(zero, &ok, Label::kNear); 3337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int3(); 3347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bind(&ok); 3357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 3367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!object.is(value)); 3387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!object.is(address)); 3397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!value.is(address)); 340c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 3417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!FLAG_incremental_marking) { 3437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return; 3447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 3457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3467028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // A single check of the map's pages interesting flag suffices, since it is 3477028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // only set during incremental collection, and then it's also guaranteed that 3487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // the from object's page's interesting flag is also set. This optimization 3497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // relies on the fact that maps can never be in new space. 3507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!isolate()->heap()->InNewSpace(*map)); 3517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CheckPageFlagForMap(map, 3527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 3537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zero, 3547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org &done, 3557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::kNear); 3567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Delay the initialization of |address| and |value| for the stub until it's 3587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // known that the will be needed. Up until this point their values are not 3597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // needed since they are embedded in the operands of instructions that need 3607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // them. 3617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org lea(address, FieldOperand(object, HeapObject::kMapOffset)); 3627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(value, Immediate(map)); 3637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org RecordWriteStub stub(object, value, address, OMIT_REMEMBERED_SET, save_fp); 3647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CallStub(&stub); 3657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bind(&done); 3677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Clobber clobbered input registers when running with the debug-code flag 3697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // turned on to provoke errors. 3707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (emit_debug_code()) { 3717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(value, Immediate(BitCast<int32_t>(kZapValue))); 3727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(scratch1, Immediate(BitCast<int32_t>(kZapValue))); 3737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org mov(scratch2, Immediate(BitCast<int32_t>(kZapValue))); 3747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 3757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org} 3767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 3777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 37869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid MacroAssembler::RecordWrite(Register object, 37969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register address, 380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode fp_mode, 382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check) { 384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(value)); 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(address)); 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!value.is(address)); 387c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (remembered_set_action == OMIT_REMEMBERED_SET && 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !FLAG_incremental_marking) { 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 394000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(value, Operand(address, 0)); 397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &ok, Label::kNear); 398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 40269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // First, check if a write barrier is even needed. The tests below 40369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // catch stores of Smis and stores into young gen. 40469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Label done; 40569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done, Label::kNear); 409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(value, 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersToHereAreInterestingMask, 414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(object, 418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersFromHereAreInterestingMask, 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode); 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&stub); 42669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 42769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org bind(&done); 42869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered registers when running with the debug-code flag 43069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // turned on to provoke errors. 431badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 43269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org mov(address, Immediate(BitCast<int32_t>(kZapValue))); 43369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org mov(value, Immediate(BitCast<int32_t>(kZapValue))); 43469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 43569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 43669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 43769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 43865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 4395c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::DebugBreak() { 4405c838251403b0be9a882540f1922577abba4c872ager@chromium.org Set(eax, Immediate(0)); 441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak, isolate()))); 4425c838251403b0be9a882540f1922577abba4c872ager@chromium.org CEntryStub ces(1); 4438432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK); 4445c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 44565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 447d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::Set(Register dst, const Immediate& x) { 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (x.is_zero()) { 450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xor_(dst, dst); // Shorter than mov. 45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 4523bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(dst, x); 45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::Set(const Operand& dst, const Immediate& x) { 45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(dst, x); 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgbool MacroAssembler::IsUnsafeImmediate(const Immediate& x) { 4637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static const int kMaxImmediateBits = 17; 4644cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (!RelocInfo::IsNone(x.rmode_)) return false; 4657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return !is_intn(x.x_, kMaxImmediateBits); 4667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 4677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid MacroAssembler::SafeSet(Register dst, const Immediate& x) { 4707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 4717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Set(dst, Immediate(x.x_ ^ jit_cookie())); 4727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org xor_(dst, jit_cookie()); 4737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 4747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Set(dst, x); 4757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 4777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid MacroAssembler::SafePush(const Immediate& x) { 4807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 4817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org push(Immediate(x.x_ ^ jit_cookie())); 4827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org xor_(Operand(esp, 0), Immediate(jit_cookie())); 4837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 4847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org push(x); 4857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 4877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4897be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid MacroAssembler::CmpObjectType(Register heap_object, 4907be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org InstanceType type, 4917be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org Register map) { 4927be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 4937be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpInstanceType(map, type); 4947be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 4957be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 4967be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 4977be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 4987be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 4997be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org static_cast<int8_t>(type)); 5007be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 5017be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 5027be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 503d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comvoid MacroAssembler::CheckFastElements(Register map, 504d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 505d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance) { 506830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 507830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 508830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 509830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 511830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleyElementValue); 512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckFastObjectElements(Register map, 517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 519830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 520830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 521830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 522830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 524830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleySmiElementValue); 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(below_equal, fail, distance); 526d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 527830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleyElementValue); 528d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com j(above, fail, distance); 529d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com} 530d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 531d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 532830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid MacroAssembler::CheckFastSmiElements(Register map, 533830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 534830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance) { 535830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 536830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 538830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleySmiElementValue); 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::StoreNumberToDoubleElements( 544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register maybe_number, 545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register key, 547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister scratch2, 549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 550fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org bool specialize_for_processor, 551fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset) { 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label smi_value, done, maybe_nan, not_nan, is_nan, have_double_value; 553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(maybe_number, &smi_value, Label::kNear); 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckMap(maybe_number, 556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate()->factory()->heap_number_map(), 557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fail, 558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DONT_DO_SMI_CHECK); 559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Double value, canonicalize NaN. 561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); 562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(FieldOperand(maybe_number, offset), 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kNaNOrInfinityLowerBoundUpper32)); 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater_equal, &maybe_nan, Label::kNear); 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_nan); 567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference canonical_nan_reference = 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::address_of_canonical_non_hole_nan(); 569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) { 570750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope use_sse2(this, SSE2); 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movdbl(scratch2, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&have_double_value); 573fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org movdbl(FieldOperand(elements, key, times_4, 574fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch2); 576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fld_d(FieldOperand(maybe_number, HeapNumber::kValueOffset)); 578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&have_double_value); 579fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org fstp_d(FieldOperand(elements, key, times_4, 580fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset)); 581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&done); 583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&maybe_nan); 585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise 586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // it's an Infinity, and the non-NaN code path applies. 587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater, &is_nan, Label::kNear); 588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_nan); 590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_nan); 591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) { 592750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope use_sse2(this, SSE2); 593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movdbl(scratch2, Operand::StaticVariable(canonical_nan_reference)); 594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fld_d(Operand::StaticVariable(canonical_nan_reference)); 596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&have_double_value, Label::kNear); 598c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 599c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&smi_value); 600c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a smi. Convert to a double and store. 601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve original value. 602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch1, maybe_number); 603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiUntag(scratch1); 604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) { 605750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope fscope(this, SSE2); 606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cvtsi2sd(scratch2, scratch1); 607fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org movdbl(FieldOperand(elements, key, times_4, 608fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch2); 610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com push(scratch1); 612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fild_s(Operand(esp, 0)); 613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pop(scratch1); 614fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org fstp_d(FieldOperand(elements, key, times_4, 615fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset)); 616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 621f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::CompareMap(Register obj, 622f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Handle<Map> map, 623a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Label* early_success) { 624f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 625f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 626f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 627f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 6285c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CheckMap(Register obj, 6295c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 6305c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 631a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type) { 63240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (smi_check_type == DO_SMI_CHECK) { 633c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org JumpIfSmi(obj, fail); 6345c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 635f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 636f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Label success; 637a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org CompareMap(obj, map, &success); 6385c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, fail); 639f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bind(&success); 6405c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 6415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6425c838251403b0be9a882540f1922577abba4c872ager@chromium.org 643ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgvoid MacroAssembler::DispatchMap(Register obj, 6442bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 645ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 646ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 647ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type) { 648ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label fail; 649560b07baefe6e8699f1ca093711f8298c43a01f9ager@chromium.org if (smi_check_type == DO_SMI_CHECK) { 650ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org JumpIfSmi(obj, &fail); 651ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 652ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map)); 653ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org j(equal, success); 654ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 655ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org bind(&fail); 656ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 657ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 658ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 6590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgCondition MacroAssembler::IsObjectStringType(Register heap_object, 6600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Register map, 6610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Register instance_type) { 6620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 6630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 66480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 6650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org test(instance_type, Immediate(kIsNotStringMask)); 6660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return zero; 6670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 6680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 6690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 670750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCondition MacroAssembler::IsObjectNameType(Register heap_object, 671750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 672750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type) { 673750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 674750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 675750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org cmpb(instance_type, static_cast<uint8_t>(LAST_NAME_TYPE)); 676750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return below_equal; 677750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 678750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 679750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 6801af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid MacroAssembler::IsObjectJSObjectType(Register heap_object, 6811af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register map, 6821af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register scratch, 6831af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Label* fail) { 6841af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 6851af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org IsInstanceJSObjectType(map, scratch, fail); 6861af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 6871af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 6881af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 6891af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid MacroAssembler::IsInstanceJSObjectType(Register map, 6901af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register scratch, 6911af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Label* fail) { 6921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org movzx_b(scratch, FieldOperand(map, Map::kInstanceTypeOffset)); 693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(scratch, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 694d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org cmp(scratch, 695d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org LAST_NONCALLABLE_SPEC_OBJECT_TYPE - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 6961af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org j(above, fail); 6971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 6981af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 6991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::FCmp() { 701c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (CpuFeatures::IsSupported(CMOV)) { 7023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org fucomip(); 7031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org fstp(0); 7043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 7053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org fucompp(); 7063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org push(eax); 7073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org fnstsw_ax(); 7083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org sahf(); 7093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org pop(eax); 7103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 71243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 714c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNumber(Register object) { 715c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 716c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Label ok; 717c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org JumpIfSmi(object, &ok); 718c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org cmp(FieldOperand(object, HeapObject::kMapOffset), 719c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate()->factory()->heap_number_map()); 720594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandNotANumber); 721c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org bind(&ok); 722c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 7235c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 726c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(Register object) { 727c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 728c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 729594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandIsNotASmi); 730c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 731f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org} 732f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 733f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 734c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertString(Register object) { 735c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 736c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 737594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAString); 738c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org push(object); 739c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org mov(object, FieldOperand(object, HeapObject::kMapOffset)); 740c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CmpInstanceType(object, FIRST_NONSTRING_TYPE); 741c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org pop(object); 742594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kOperandIsNotAString); 743c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 744d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 745d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 746d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 747750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid MacroAssembler::AssertName(Register object) { 748750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (emit_debug_code()) { 749750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org test(object, Immediate(kSmiTagMask)); 750594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAName); 751750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org push(object); 752750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org mov(object, FieldOperand(object, HeapObject::kMapOffset)); 753750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CmpInstanceType(object, LAST_NAME_TYPE); 754750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org pop(object); 755594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below_equal, kOperandIsNotAName); 756750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 757750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 758750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 759750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 760c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNotSmi(Register object) { 761c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 762c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 763594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmi); 764c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 76526c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org} 76626c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org 76726c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org 7687c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(ebp); 770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ebp, esp); 77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(esi); 77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(Immediate(Smi::FromInt(type))); 773061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org push(Immediate(CodeObject())); 774badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 7757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); 776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kCodeObjectNotProperlyPatched); 777061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org } 77843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 77943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 78043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7817c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 782badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), 78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Immediate(Smi::FromInt(type))); 785594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kStackFrameTypesMustMatch); 78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 78743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen leave(); 78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 790d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 791d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::EnterExitFramePrologue() { 792f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the frame structure on the stack. 793eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 794236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 795236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 796236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org push(ebp); 797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ebp, esp); 798236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 799d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Reserve room for entry stack pointer and push the code object. 800236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 8015c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(0)); // Saved entry sp, patched before call. 8025c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. 803236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 804236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Save the frame pointer and the context in top. 80583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 806ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 80783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference context_address(Isolate::kContextAddress, 808ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 809236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(c_entry_fp_address), ebp); 810236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(context_address), esi); 811c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 812236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 813236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 814a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { 815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Optionally save all XMM registers. 816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (save_doubles) { 817750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(this, SSE2); 818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize; 819c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(space)); 8200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int offset = -2 * kPointerSize; 821a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 822a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = XMMRegister::from_code(i); 823a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org movdbl(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); 824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 826c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(argc * kPointerSize)); 827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 828236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 829236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Get the required frame alignment for the OS. 830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int kFrameAlignment = OS::ActivationFrameAlignment(); 831236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (kFrameAlignment > 0) { 832236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ASSERT(IsPowerOf2(kFrameAlignment)); 833236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org and_(esp, -kFrameAlignment); 834236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } 835236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 836236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Patch the saved entry sp. 837236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); 838236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 839236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 840236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::EnterExitFrame(bool save_doubles) { 842d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(); 843c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 844f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up argc and argv in callee-saved registers. 845c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 846c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(edi, eax); 847c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org lea(esi, Operand(ebp, eax, times_4, offset)); 848c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 849ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Reserve space for argc, argv and isolate. 850ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org EnterExitFrameEpilogue(3, save_doubles); 851c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 852c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 853c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 8544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::EnterApiExitFrame(int argc) { 855d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(); 856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EnterExitFrameEpilogue(argc, false); 857c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 858c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 859c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 860a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::LeaveExitFrame(bool save_doubles) { 861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Optionally restore all XMM registers. 862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (save_doubles) { 863750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(this, SSE2); 8640ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int offset = -2 * kPointerSize; 865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 866a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = XMMRegister::from_code(i); 867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org movdbl(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); 868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 871236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Get the return address from the stack and restore the frame pointer. 872236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(ecx, Operand(ebp, 1 * kPointerSize)); 873236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(ebp, Operand(ebp, 0 * kPointerSize)); 874236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 875236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Pop the arguments and the receiver from the caller stack. 876236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org lea(esp, Operand(esi, 1 * kPointerSize)); 877236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 8784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Push the return address to get ready to return. 8794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com push(ecx); 8804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 8814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com LeaveExitFrameEpilogue(); 8824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 8834a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 884e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 8854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::LeaveExitFrameEpilogue() { 886236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Restore current context from top and clear it in debug mode. 88783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 888236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(esi, Operand::StaticVariable(context_address)); 88965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef DEBUG 89065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org mov(Operand::StaticVariable(context_address), Immediate(0)); 89165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 892236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 893236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Clear the top frame. 89483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 895ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 896236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); 897236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 898236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 899236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 9004a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::LeaveApiExitFrame() { 901c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(esp, ebp); 9024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com pop(ebp); 9034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 9044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com LeaveExitFrameEpilogue(); 9054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 9064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 9074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 90878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid MacroAssembler::PushTryHandler(StackHandler::Kind kind, 90904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_index) { 910eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Adjust this code if not the case. 9114acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 9124acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 91304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 91404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 91504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 91604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 91704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 91804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // We will build up the handler from the bottom by pushing on the stack. 91978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // First push the frame pointer and context. 92078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (kind == StackHandler::JS_ENTRY) { 92104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The frame pointer does not point to a JS frame so we save NULL for 92204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // ebp. We expect the code throwing an exception to check ebp before 92304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // dereferencing it to restore the context. 924eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(Immediate(0)); // NULL frame pointer. 9254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org push(Immediate(Smi::FromInt(0))); // No context. 92678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 92778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(ebp); 92878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(esi); 92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 93004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push the state and the code object. 93178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org unsigned state = 93278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::IndexField::encode(handler_index) | 93378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::KindField::encode(kind); 93404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Immediate(state)); 93564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Push(CodeObject()); 93604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 93704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Link the current handler as the next handler. 93804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 93904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Operand::StaticVariable(handler_address)); 94004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Set this new handler as the current one. 94104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(Operand::StaticVariable(handler_address), esp); 94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 94343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::PopTryHandler() { 9464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 94704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 94804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(Operand::StaticVariable(handler_address)); 949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 95013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 95113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 95213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 95304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid MacroAssembler::JumpToHandlerEntry() { 95404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Compute the handler entry address and jump to it. The handler table is 95504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // a fixed array of (smi-tagged) code offsets. 95604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // eax = exception, edi = code object, edx = state. 95704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(ebx, FieldOperand(edi, Code::kHandlerTableOffset)); 95804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org shr(edx, StackHandler::kKindWidth); 95904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(edx, FieldOperand(ebx, edx, times_4, FixedArray::kHeaderSize)); 96004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org SmiUntag(edx); 96104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); 96204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org jmp(edi); 96304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org} 96404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 96504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 96649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgvoid MacroAssembler::Throw(Register value) { 96749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Adjust this code if not the case. 9684acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 9694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 97004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 97104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 97204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 97304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 97404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 97504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The exception is expected in eax. 97649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (!value.is(eax)) { 97749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org mov(eax, value); 97849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 97904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Drop the stack pointer to the top of the top handler. 98004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 98149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org mov(esp, Operand::StaticVariable(handler_address)); 98204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the next handler. 98349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pop(Operand::StaticVariable(handler_address)); 98404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 98504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in edi. 98604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edi); // Code object. 98704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edx); // Index and state. 98804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 98904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the context and frame pointer. 9904acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(esi); // Context. 9914acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(ebp); // Frame pointer. 99249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 9934acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // If the handler is a JS frame, restore the context to the frame. 99404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either 99504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // ebp or esi. 99683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label skip; 99704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org test(esi, esi); 99804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(zero, &skip, Label::kNear); 9994acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 100049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org bind(&skip); 100149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 100204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 100349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 100449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 100549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 100665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.orgvoid MacroAssembler::ThrowUncatchable(Register value) { 100749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Adjust this code if not the case. 10084acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 10094acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 101004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 101104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 101204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 101304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 101449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 1015c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // The exception is expected in eax. 101665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value.is(eax)) { 1017c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(eax, value); 101849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 1019c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Drop the stack pointer to the top of the top stack handler. 1020c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 1021c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(esp, Operand::StaticVariable(handler_address)); 1022c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1023c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Unwind the handlers until the top ENTRY handler is found. 1024c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Label fetch_next, check_kind; 1025c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org jmp(&check_kind, Label::kNear); 1026c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&fetch_next); 1027c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(esp, Operand(esp, StackHandlerConstants::kNextOffset)); 1028c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1029c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&check_kind); 103078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org STATIC_ASSERT(StackHandler::JS_ENTRY == 0); 103104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org test(Operand(esp, StackHandlerConstants::kStateOffset), 103204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Immediate(StackHandler::KindField::kMask)); 103304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(not_zero, &fetch_next); 1034c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1035c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Set the top handler address to next handler past the top ENTRY handler. 1036c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(Operand::StaticVariable(handler_address)); 103749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 103804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in edi. 103904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edi); // Code object. 104004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edx); // Index and state. 104104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 104204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Clear the context pointer and frame pointer (0 was saved in the handler). 1043c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(esi); 104449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pop(ebp); 104549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 104604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 104749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 104849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 104949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 10505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 1051e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch1, 1052e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch2, 1053e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org Label* miss) { 10545a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Label same_contexts; 10555a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1056e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!holder_reg.is(scratch1)); 1057e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!holder_reg.is(scratch2)); 1058e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!scratch1.is(scratch2)); 105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Load current lexical context from the stack frame. 1061e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, Operand(ebp, StandardFrameConstants::kContextOffset)); 10625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 10635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // When generating debug code, make sure the lexical context is set. 1064badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1065e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, Immediate(0)); 1066594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 106846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context of the current context. 106946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org int offset = 107046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 1071e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, offset)); 1072e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, GlobalObject::kNativeContextOffset)); 10735a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 107446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 1075badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 107646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map. 1077e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(FieldOperand(scratch1, HeapObject::kMapOffset), 1078e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->native_context_map()); 1079594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 10805a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 10815a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 10825a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Check if both contexts are the same. 1083e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 10847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(equal, &same_contexts); 10855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 10865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Compare security tokens, save holder_reg on the stack so we can use it 10875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // as a temporary register. 10885a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // 108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that the security token in the calling global object is 109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // compatible with the security token in the receiving global 109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // object. 1092e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch2, 109346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 10945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 109546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 1096badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1097e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch2, isolate()->factory()->null_value()); 1098594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 10995a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 110046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map(), 1101e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(FieldOperand(scratch2, HeapObject::kMapOffset), 1102e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->native_context_map()); 1103594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 11045a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 11055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 11065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org int token_offset = Context::kHeaderSize + 11075a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Context::SECURITY_TOKEN_INDEX * kPointerSize; 1108e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, token_offset)); 1109e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, FieldOperand(scratch2, token_offset)); 11107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, miss); 11115a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 11125a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org bind(&same_contexts); 111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1116f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Compute the hash code from the untagged key. This must be kept in sync 1117f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// with ComputeIntegerHash in utils.h. 1118f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// 1119f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Note: r0 will contain hash code 1120f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 1121f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Xor original key with a seed. 1122f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com if (Serializer::enabled()) { 1123f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExternalReference roots_array_start = 1124f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExternalReference::roots_array_start(isolate()); 1125f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, Immediate(Heap::kHashSeedRootIndex)); 1126f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, 1127f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Operand::StaticArray(scratch, times_pointer_size, roots_array_start)); 1128f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiUntag(scratch); 1129f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1130f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } else { 1131f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com int32_t seed = isolate()->heap()->HashSeed(); 1132f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, Immediate(seed)); 1133f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 1134f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1135f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = ~hash + (hash << 15); 1136f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1137f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com not_(r0); 1138f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shl(scratch, 15); 1139f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com add(r0, scratch); 1140f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 12); 1141f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1142f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 12); 1143f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1144f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash + (hash << 2); 1145f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com lea(r0, Operand(r0, r0, times_4, 0)); 1146f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 4); 1147f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1148f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 4); 1149f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1150f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash * 2057; 1151f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com imul(r0, r0, 2057); 1152f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 16); 1153f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1154f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 16); 1155f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1156f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 1157f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1158f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1159f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 11606db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 11616db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 11626db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 11636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 11646db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 11656db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 11666db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result) { 11676db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Register use: 11686db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11696db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // elements - holds the slow-case elements of the receiver and is unchanged. 11706db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11716db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // key - holds the smi key on entry and is unchanged. 11726db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11736db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scratch registers: 11746db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11756db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r0 - holds the untagged key on entry and holds the hash once computed. 11766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r1 - used to hold the capacity mask of the dictionary 11786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r2 - used for the index into the dictionary. 11806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 11816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // result - holds the result on exit if the load succeeds and we fall through. 11826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 11836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Label done; 11846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1185f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com GetNumberHash(r0, r1); 11866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 11876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute capacity mask. 1188f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset)); 11896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org shr(r1, kSmiTagSize); // convert smi to int 11906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org dec(r1); 11916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 11926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Generate an unrolled loop that performs a few probes before giving up. 11936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kProbes = 4; 11946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org for (int i = 0; i < kProbes; i++) { 11956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Use r2 for index calculations and keep the hash intact in r0. 11966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org mov(r2, r0); 11976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute the masked index: (hash + i + i * i) & mask. 11986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (i > 0) { 1199f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com add(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 12006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(r2, r1); 12026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 12036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scale the index by multiplying by the entry size. 1204f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(SeededNumberDictionary::kEntrySize == 3); 12056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 12066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 12076db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check if the key matches. 12086db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org cmp(key, FieldOperand(elements, 12096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org r2, 12106db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org times_pointer_size, 1211f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset)); 12126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (i != (kProbes - 1)) { 12136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(equal, &done); 12146db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } else { 12156db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_equal, miss); 12166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 12176db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 12186db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 12196db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org bind(&done); 12206db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check that the value is a normal propety. 12216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kDetailsOffset = 1222f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 12236db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org ASSERT_EQ(NORMAL, 0); 12246db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 122583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); 12266db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_zero, miss); 12276db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 12286db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Get the value at the masked, scaled index. 12296db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kValueOffset = 1230f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + kPointerSize; 12316db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 12326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 12336db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 12346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1235a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid MacroAssembler::LoadAllocationTopHelper(Register result, 1236a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Register scratch, 1237a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags) { 12382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 12392bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 124018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 124118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Just return if allocation top is already known. 1242a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & RESULT_CONTAINS_TOP) != 0) { 124318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // No use of scratch if allocation top is provided. 124418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(scratch.is(no_reg)); 1245a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG 1246a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Assert that result actually contains top on entry. 12472bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org cmp(result, Operand::StaticVariable(allocation_top)); 1248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kUnexpectedAllocationTop); 1249a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 125018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 125118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 125218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 125318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Move address of new object to result. Use scratch register if available. 125418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (scratch.is(no_reg)) { 12552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(result, Operand::StaticVariable(allocation_top)); 125618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 12572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(scratch, Immediate(allocation_top)); 125818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(result, Operand(scratch, 0)); 125918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 126018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 126118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 126218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 126318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 12642bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 12652bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 1266badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1267ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org test(result_end, Immediate(kObjectAlignmentMask)); 1268594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kUnalignedAllocationInNewSpace); 1269ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 1270ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 12712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 12722bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 127318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 127418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update new top. Use scratch if available. 127518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (scratch.is(no_reg)) { 12762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(Operand::StaticVariable(allocation_top), result_end); 127718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 127818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(Operand(scratch, 0), result_end); 127918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 128018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 128118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1282a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 12832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid MacroAssembler::Allocate(int object_size, 12842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 12852bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 12862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 12872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 12882bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 12894cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1290c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize); 1291303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1292badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1293303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1294303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1295303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result_end.is_valid()) { 1296303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1297303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1298303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1299303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1300303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1301303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1302303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1303303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1304303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 130518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 130618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 130718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1308beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 130918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1310af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org ExternalReference allocation_limit = 1311af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1312af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org 13134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 1314af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 13154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 13162bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 13174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 13184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label aligned; 13194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 13204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org j(zero, &aligned, Label::kNear); 1321af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1322af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1323af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org j(above_equal, gc_required); 1324af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org } 13254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org mov(Operand(result, 0), 13264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 13274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org add(result, Immediate(kDoubleSize / 2)); 13284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bind(&aligned); 13294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 13304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 13312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // Calculate new top and bail out if space is exhausted. 1332af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org Register top_reg = result_end.is_valid() ? result_end : result; 1333d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (!top_reg.is(result)) { 1334d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com mov(top_reg, result); 1335a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(top_reg, Immediate(object_size)); 13377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(carry, gc_required); 13382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org cmp(top_reg, Operand::StaticVariable(allocation_limit)); 13397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(above, gc_required); 13400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 13410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 13422bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(top_reg, scratch, flags); 1343c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1344c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Tag result if requested. 13454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bool tag_result = (flags & TAG_OBJECT) != 0; 1346c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (top_reg.is(result)) { 13474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (tag_result) { 1348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(result, Immediate(object_size - kHeapObjectTag)); 1349c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 1350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(result, Immediate(object_size)); 1351c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 13524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else if (tag_result) { 13534cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kHeapObjectTag == 1); 13544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org inc(result); 1355c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 135618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 135718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 135818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1359f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(int header_size, 1360f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 1361f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 1362f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org RegisterValueType element_count_type, 1363f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1364f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1365f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1366f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1367f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 13684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & SIZE_IN_WORDS) == 0); 1369303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1370badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1371303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1372303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1373303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1374303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1375303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1376303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1377303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Register element_count is not modified by the function. 1378303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1379303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1380303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1381303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 138218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 138318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 138418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1385beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 138618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1387af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org ExternalReference allocation_limit = 1388af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1389af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org 13904cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 1391af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 13924cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1393f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 13944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 13954cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label aligned; 13964cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 13974cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org j(zero, &aligned, Label::kNear); 1398af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1399af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1400af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org j(above_equal, gc_required); 1401af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org } 14024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org mov(Operand(result, 0), 14034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 14044cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org add(result, Immediate(kDoubleSize / 2)); 14054cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bind(&aligned); 14064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 14074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 1408f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Calculate new top and bail out if space is exhausted. 1409d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // We assume that element_count*element_size + header_size does not 1410d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // overflow. 14114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (element_count_type == REGISTER_VALUE_IS_SMI) { 14124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_2 - 1) == times_1); 14134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_4 - 1) == times_2); 14144cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_8 - 1) == times_4); 14154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(element_size >= times_2); 14164cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kSmiTagSize == 1); 14174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org element_size = static_cast<ScaleFactor>(element_size - 1); 14184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else { 14194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(element_count_type == REGISTER_VALUE_IS_INT32); 14204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 1421d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com lea(result_end, Operand(element_count, element_size, header_size)); 1422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(result_end, result); 1423d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 1424f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp(result_end, Operand::StaticVariable(allocation_limit)); 142518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 142618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1427a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 14284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kHeapObjectTag == 1); 14294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org inc(result); 1430a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 14310c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 14320c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 14332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 143418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 143518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 143618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1437f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(Register object_size, 1438f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1439f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1440f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1441f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1442f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 144394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1444303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1445badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1446303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1447303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1448303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1449303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1450303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1451303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1452303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // object_size is left unchanged by this function. 1453303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1454303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1455303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1456303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 145718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 145818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 145918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1460beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 146118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1462af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org ExternalReference allocation_limit = 1463af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1464af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org 146594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Align the next allocation. Storing the filler map without checking top is 1466af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 146794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1468f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 146994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 147094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Label aligned; 147194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 147294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org j(zero, &aligned, Label::kNear); 1473af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1474af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1475af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org j(above_equal, gc_required); 1476af59fe73a44727fc8176c070f49ca05ddf07a382mstarzinger@chromium.org } 147794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org mov(Operand(result, 0), 147894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 147994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org add(result, Immediate(kDoubleSize / 2)); 148094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org bind(&aligned); 148194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 148294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1483f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Calculate new top and bail out if space is exhausted. 148418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (!object_size.is(result_end)) { 148518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(result_end, object_size); 148618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 1487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(result_end, result); 14887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(carry, gc_required); 1489f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp(result_end, Operand::StaticVariable(allocation_limit)); 14907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(above, gc_required); 149118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1492a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Tag result if requested. 1493a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 149494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(kHeapObjectTag == 1); 149594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org inc(result); 1496a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 14970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 14980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 14992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 150018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 150118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 150218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 150318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UndoAllocationInNewSpace(Register object) { 150418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference new_space_allocation_top = 1505ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 150618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 150718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Make sure the object has no tag before resetting top. 1508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(object, Immediate(~kHeapObjectTagMask)); 150918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef DEBUG 151018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org cmp(object, Operand::StaticVariable(new_space_allocation_top)); 1511594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kUndoAllocationOfNonAllocatedMemory); 151218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 151318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(Operand::StaticVariable(new_space_allocation_top), object); 151418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 151518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 151618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 15173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgvoid MacroAssembler::AllocateHeapNumber(Register result, 15183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch1, 15193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch2, 15203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label* gc_required) { 15213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate heap number in new space. 15222bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, 15232bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 15243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 15253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Set the map. 15263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 15277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->heap_number_map())); 15283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 15293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 15303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1531ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateTwoByteString(Register result, 1532ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register length, 1533ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1534ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1535ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch3, 1536ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1537ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Calculate the number of bytes needed for the characters in the string while 1538ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // observing object alignment. 1539ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 1540ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org ASSERT(kShortSize == 2); 154113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // scratch1 = length * 2 + kObjectAlignmentMask. 154213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); 1543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, Immediate(~kObjectAlignmentMask)); 1544ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1545ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate two byte string in new space. 1546f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqTwoByteString::kHeaderSize, 1547f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 1548f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 1549f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_INT32, 1550f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 1551f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 1552f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 1553f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 1554f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 1555ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1556ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map, length and hash field. 1557ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 15587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->string_map())); 1559ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(scratch1, length); 1560ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org SmiTag(scratch1); 1561ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(FieldOperand(result, String::kLengthOffset), scratch1); 1562ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 1563ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Immediate(String::kEmptyHashField)); 1564ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1565ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1566ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1567ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result, 1568ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register length, 1569ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1570ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1571ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch3, 1572ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1573ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Calculate the number of bytes needed for the characters in the string while 1574ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // observing object alignment. 1575fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); 1576ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(scratch1, length); 1577ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org ASSERT(kCharSize == 1); 1578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(scratch1, Immediate(kObjectAlignmentMask)); 1579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, Immediate(~kObjectAlignmentMask)); 1580ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 15812efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allocate ASCII string in new space. 1582f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqOneByteString::kHeaderSize, 1583f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 1584f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 1585f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_INT32, 1586f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 1587f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 1588f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 1589f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 1590f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 1591ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1592ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map, length and hash field. 1593ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 15947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->ascii_string_map())); 1595ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(scratch1, length); 1596ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org SmiTag(scratch1); 1597ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(FieldOperand(result, String::kLengthOffset), scratch1); 1598ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 1599ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Immediate(String::kEmptyHashField)); 1600ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1601ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1602ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 16033cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result, 16043cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org int length, 16053cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Register scratch1, 16063cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Register scratch2, 16073cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Label* gc_required) { 16083cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org ASSERT(length > 0); 16093cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 16102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allocate ASCII string in new space. 16112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, 16122bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org gc_required, TAG_OBJECT); 16133cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 16143cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org // Set the map, length and hash field. 16153cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 16167979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->ascii_string_map())); 16173cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, String::kLengthOffset), 16183cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Immediate(Smi::FromInt(length))); 16193cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 16203cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Immediate(String::kEmptyHashField)); 16213cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org} 16223cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 16233cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 16241805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteConsString(Register result, 1625ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1626ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1627ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1628ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate heap number in new space. 16292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 16302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 1631ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1632ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map. The other fields are left uninitialized. 1633ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 16347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->cons_string_map())); 1635ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1636ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1637ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1638ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateAsciiConsString(Register result, 1639ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1640ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1641ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 164257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label allocate_new_space, install_map; 164357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org AllocationFlags flags = TAG_OBJECT; 164457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 164557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ExternalReference high_promotion_mode = ExternalReference:: 164657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org new_space_high_promotion_mode_active_address(isolate()); 164757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 164857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org test(Operand::StaticVariable(high_promotion_mode), Immediate(1)); 164957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org j(zero, &allocate_new_space); 165057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 165157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 165257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 165357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 165457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 165557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 165657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE)); 165757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org jmp(&install_map); 165857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 165957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bind(&allocate_new_space); 166057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 166157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 166257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 166357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 166457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 166557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org flags); 1666ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 166757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bind(&install_map); 1668ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map. The other fields are left uninitialized. 1669ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 16707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->cons_ascii_string_map())); 1671ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1672ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1673c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 16741805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 167580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch1, 167680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch2, 167780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Label* gc_required) { 167880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Allocate heap number in new space. 16792bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 16802bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 168180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 168280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Set the map. The other fields are left uninitialized. 168380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 168480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Immediate(isolate()->factory()->sliced_string_map())); 168580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 168680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 168780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 168880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.orgvoid MacroAssembler::AllocateAsciiSlicedString(Register result, 168980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch1, 169080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch2, 169180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Label* gc_required) { 169280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Allocate heap number in new space. 16932bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 16942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 169580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 169680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Set the map. The other fields are left uninitialized. 169780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 169880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Immediate(isolate()->factory()->sliced_ascii_string_map())); 169980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 170080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 170180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 1702c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Copy memory, byte-by-byte, from source to destination. Not optimized for 1703c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// long or aligned copies. The contents of scratch and length are destroyed. 1704c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Source and destination are incremented by length. 1705c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Many variants of movsb, loop unrolling, word moves, and indexed operands 1706c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// have been tried here already, and this is fastest. 1707c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// A simpler loop is faster on small copies, but 30% slower on large ones. 1708c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// The cld() instruction must have been emitted, to set the direction flag(), 1709c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// before calling this function. 1710c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid MacroAssembler::CopyBytes(Register source, 1711c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register destination, 1712c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register length, 1713c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register scratch) { 1714c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Label loop, done, short_string, short_loop; 1715c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Experimentation shows that the short string loop is faster if length < 10. 1716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(length, Immediate(10)); 1717c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org j(less_equal, &short_string); 1718c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1719c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(source.is(esi)); 1720c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(destination.is(edi)); 1721c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(length.is(ecx)); 1722c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1723c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Because source is 4-byte aligned in our uses of this function, 1724c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // we keep source aligned for the rep_movs call by copying the odd bytes 1725c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // at the end of the ranges. 1726c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(scratch, Operand(source, length, times_1, -4)); 1727c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(Operand(destination, length, times_1, -4), scratch); 1728c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(scratch, ecx); 1729c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org shr(ecx, 2); 1730c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org rep_movs(); 1731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(0x3)); 1732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(destination, scratch); 1733c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org jmp(&done); 1734c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1735c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&short_string); 1736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(length, length); 1737c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org j(zero, &done); 1738c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1739c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&short_loop); 1740c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov_b(scratch, Operand(source, 0)); 1741c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov_b(Operand(destination, 0), scratch); 1742c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inc(source); 1743c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inc(destination); 1744c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org dec(length); 1745c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org j(not_zero, &short_loop); 1746c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1747c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&done); 174821b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org} 174921b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 1750ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InitializeFieldsWithFiller(Register start_offset, 1752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 1753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler) { 1754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 1755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&entry); 1756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&loop); 1757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand(start_offset, 0), filler); 1758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(start_offset, Immediate(kPointerSize)); 1759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&entry); 1760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(start_offset, end_offset); 1761c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(less, &loop); 1762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MacroAssembler::BooleanBitTest(Register object, 1766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int field_offset, 1767394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int bit_index) { 1768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bit_index += kSmiTagSize + kSmiShiftSize; 1769394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(IsPowerOf2(kBitsPerByte)); 1770394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_index = bit_index / kBitsPerByte; 1771394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_bit_index = bit_index & (kBitsPerByte - 1); 1772394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com test_b(FieldOperand(object, field_offset + byte_index), 1773394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static_cast<byte>(1 << byte_bit_index)); 1774394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1775394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1776394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1777394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 177843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::NegativeZeroTest(Register result, 177943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op, 178043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label* then_label) { 178143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label ok; 1782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(result, result); 17837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &ok); 1784c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(op, op); 17857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(sign, then_label); 178643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&ok); 178743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 178843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 178943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 179043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::NegativeZeroTest(Register result, 179143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op1, 179243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op2, 179343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register scratch, 179443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label* then_label) { 179543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label ok; 1796c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(result, result); 17977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &ok); 1798c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, op1); 1799c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(scratch, op2); 18007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(sign, then_label); 180143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&ok); 180243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 180343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 180443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18057c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::TryGetFunctionPrototype(Register function, 18067c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Register result, 18077c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Register scratch, 1808394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 1809394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function) { 18107c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Check that the receiver isn't a smi. 18117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org JumpIfSmi(function, miss); 18127c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18137c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Check that the function really is a function. 18147be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpObjectType(function, JS_FUNCTION_TYPE, result); 18157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, miss); 18167c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 1817394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (miss_on_bound_function) { 1818394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If a bound function, go to miss label. 1819394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com mov(scratch, 1820394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 1821394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com BooleanBitTest(scratch, SharedFunctionInfo::kCompilerHintsOffset, 1822394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SharedFunctionInfo::kBoundFunction); 1823394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com j(not_zero, miss); 1824394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1825394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 18267c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Make sure that the function has an instance prototype. 18277c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Label non_instance; 18287c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset)); 18297c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); 18307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &non_instance); 18317c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18327c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Get the prototype or initial map from the function. 18337c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, 18347c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 18357c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18367c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // If the prototype or initial map is the hole, don't return it and 18377c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // simply miss the cache instead. This will allow us to allocate a 18387c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // prototype object on-demand in the runtime system. 1839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(result, Immediate(isolate()->factory()->the_hole_value())); 18407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(equal, miss); 18417c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18427c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // If the function does not have an initial map, we're done. 18437c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Label done; 18447be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpObjectType(result, MAP_TYPE, scratch); 18457c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org j(not_equal, &done); 18467c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18477c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Get the prototype from the initial map. 18487c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, FieldOperand(result, Map::kPrototypeOffset)); 18497c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org jmp(&done); 18507c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18517c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Non-instance prototype: Fetch prototype from constructor field 18527c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // in initial map. 18537c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org bind(&non_instance); 18547c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, FieldOperand(result, Map::kConstructorOffset)); 18557c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18567c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // All done. 18577c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org bind(&done); 18587c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org} 18597c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 18607c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 1861471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 1862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs. 18638432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id); 186443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 186543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 186643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1867ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::TailCallStub(CodeStub* stub) { 18682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ASSERT(allow_stub_calls_ || 18692bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org stub->CompilingCallsToThisStubIsGCSafe(isolate())); 18708432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org jmp(stub->GetCode(isolate()), RelocInfo::CODE_TARGET); 1871ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1872ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1873ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 187443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::StubReturn(int argc) { 187543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(argc >= 1 && generating_stub()); 187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ret((argc - 1) * kPointerSize); 187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 187943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1880c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 1881c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false; 18822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(isolate()); 1883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 188641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.orgvoid MacroAssembler::IllegalOperation(int num_arguments) { 188741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (num_arguments > 0) { 1888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(num_arguments * kPointerSize)); 188941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org } 18907979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org mov(eax, Immediate(isolate()->factory()->undefined_value())); 189143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1894d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 1895d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The assert checks that the constants for the maximum number of digits 1896d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // for an array index cached in the hash field and the number of bits 1897d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // reserved for it does not conflict. 1898d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 1899d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org (1 << String::kArrayIndexValueBits)); 1900d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // We want the smi-tagged index in key. kArrayIndexValueMask has zeros in 1901d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // the low kHashShift bits. 1902d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org and_(hash, String::kArrayIndexValueMask); 1903d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org STATIC_ASSERT(String::kHashShift >= kSmiTagSize && kSmiTag == 0); 1904d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org if (String::kHashShift > kSmiTagSize) { 1905d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org shr(hash, String::kHashShift - kSmiTagSize); 1906d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 1907d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org if (!index.is(hash)) { 1908d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(index, hash); 1909d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 1910d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 1911d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 1912d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { 191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CallRuntime(Runtime::FunctionForId(id), num_arguments); 191543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 191643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 191743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { 1919ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const Runtime::Function* function = Runtime::FunctionForId(id); 1920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Set(eax, Immediate(function->nargs)); 1921ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(function, isolate()))); 1922a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CEntryStub ces(1, CpuFeatures::IsSupported(SSE2) ? kSaveFPRegs 1923a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org : kDontSaveFPRegs); 1924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CallStub(&ces); 1925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1926a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1927a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1928ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 1929ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int num_arguments) { 193031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // If the expected number of arguments of the runtime function is 193131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // constant, we check that the actual number of arguments match the 193231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // expectation. 193331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager if (f->nargs >= 0 && f->nargs != num_arguments) { 193441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org IllegalOperation(num_arguments); 193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 193643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 193743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1938b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // TODO(1236192): Most runtime routines don't need the number of 1939b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // arguments passed in because it is constant. At some point we 1940b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // should remove this need and make the runtime routine entry code 1941b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // smarter. 1942b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Set(eax, Immediate(num_arguments)); 1943ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(f, isolate()))); 1944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CEntryStub ces(1); 1945b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallStub(&ces); 194643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 194743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 194843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1949e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.orgvoid MacroAssembler::CallExternalReference(ExternalReference ref, 1950e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int num_arguments) { 1951e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org mov(eax, Immediate(num_arguments)); 1952e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org mov(ebx, Immediate(ref)); 1953e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1954e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org CEntryStub stub(1); 1955e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org CallStub(&stub); 1956e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 1957e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1958e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1959ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 1960ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 1961ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 196231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // TODO(1236192): Most runtime routines don't need the number of 196331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // arguments passed in because it is constant. At some point we 196431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // should remove this need and make the runtime routine entry code 196531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // smarter. 19663bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org Set(eax, Immediate(num_arguments)); 1967ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org JumpToExternalReference(ext); 1968ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 1969ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1970ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1971ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 1972ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 1973ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 1974ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TailCallExternalReference(ExternalReference(fid, isolate()), 1975ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org num_arguments, 1976ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result_size); 197743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 197843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 197943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19805f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// If true, a Handle<T> returned by value from a function with cdecl calling 19815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// convention will be returned directly as a value of location_ field in a 19825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// register eax. 19835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// If false, it is returned as a pointer to a preallocated by caller memory 19845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// region. Pointer to this region should be passed to a function as an 19855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// implicit first argument. 1986c22f2d813ad21e25e8df5d4a371fd63f582e4262danno@chromium.org#if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__) 19875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgstatic const bool kReturnHandlesDirectly = true; 1988303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#else 19895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgstatic const bool kReturnHandlesDirectly = false; 1990303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif 1991303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 1992303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 1993bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgOperand ApiParameterOperand(int index, bool returns_handle) { 1994bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org int offset = (index +(kReturnHandlesDirectly || !returns_handle ? 0 : 1)); 1995bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org return Operand(esp, offset * kPointerSize); 1996c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 1997c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1998c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1999bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgvoid MacroAssembler::PrepareCallApiFunction(int argc, bool returns_handle) { 2000bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org if (kReturnHandlesDirectly || !returns_handle) { 20014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com EnterApiExitFrame(argc); 20025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // When handles are returned directly we don't have to allocate extra 2003303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // space for and pass an out parameter. 2004ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (emit_debug_code()) { 2005ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org mov(esi, Immediate(BitCast<int32_t>(kZapValue))); 2006ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 20072d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org } else { 2008303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // We allocate two additional slots: return value and pointer to it. 20094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com EnterApiExitFrame(argc + 2); 2010c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2011303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // The argument slots are filled as follows: 2012303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // 2013ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // n + 1: output slot 2014303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // n: arg n 2015303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // ... 2016303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // 1: arg1 2017ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // 0: pointer to the output slot 20184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 2019ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org lea(esi, Operand(esp, (argc + 1) * kPointerSize)); 2020ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org mov(Operand(esp, 0 * kPointerSize), esi); 2021badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 2022ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org mov(Operand(esi, 0), Immediate(0)); 20234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 2024303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 20254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 20264a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 20272d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 2028c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid MacroAssembler::CallApiFunctionAndReturn(Address function_address, 2029b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Address thunk_address, 2030b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Operand thunk_last_arg, 2031bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org int stack_space, 2032bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org bool returns_handle, 2033bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org int return_value_offset) { 2034303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference next_address = 203509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_next_address(isolate()); 2036303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference limit_address = 203709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_limit_address(isolate()); 2038303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference level_address = 203909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_level_address(isolate()); 20402d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 2041303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Allocate HandleScope in callee-save registers. 2042303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(ebx, Operand::StaticVariable(next_address)); 2043303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(edi, Operand::StaticVariable(limit_address)); 2044303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org add(Operand::StaticVariable(level_address), Immediate(1)); 2045303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 204683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 204783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 204883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 2049ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1, eax); 2050ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org mov(Operand(esp, 0), 2051ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2052ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 205383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 205483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 205583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 2056b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2057b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label profiler_disabled; 2058b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label end_profiler_check; 2059b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bool* is_profiling_flag = 2060b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org isolate()->cpu_profiler()->is_profiling_address(); 2061b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org STATIC_ASSERT(sizeof(*is_profiling_flag) == 1); 2062b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org mov(eax, Immediate(reinterpret_cast<Address>(is_profiling_flag))); 2063b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org cmpb(Operand(eax, 0), 0); 2064b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org j(zero, &profiler_disabled); 2065b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2066b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Additional parameter is the address of the actual getter function. 2067b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org mov(thunk_last_arg, Immediate(function_address)); 2068b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Call the api function. 2069b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org call(thunk_address, RelocInfo::RUNTIME_ENTRY); 2070b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org jmp(&end_profiler_check); 2071b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2072b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&profiler_disabled); 2073c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Call the api function. 2074c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org call(function_address, RelocInfo::RUNTIME_ENTRY); 2075b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&end_profiler_check); 20762d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 207783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 207883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 207983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 2080ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1, eax); 2081ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org mov(Operand(esp, 0), 2082ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2083ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); 208483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 208583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 208683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 2087303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label prologue; 2088bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org if (returns_handle) { 2089bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org if (!kReturnHandlesDirectly) { 2090bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // PrepareCallApiFunction saved pointer to the output slot into 2091bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // callee-save register esi. 2092bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org mov(eax, Operand(esi, 0)); 2093bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org } 2094bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Label empty_handle; 2095bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Check if the result handle holds 0. 2096bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org test(eax, eax); 2097bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org j(zero, &empty_handle); 2098bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // It was non-zero. Dereference to get the result value. 2099bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org mov(eax, Operand(eax, 0)); 2100bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org jmp(&prologue); 2101bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org bind(&empty_handle); 2102bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org } 2103bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Load the value from ReturnValue 2104bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org mov(eax, Operand(ebp, return_value_offset * kPointerSize)); 2105bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org 2106303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label promote_scheduled_exception; 2107303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label delete_allocated_handles; 2108303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label leave_exit_frame; 2109303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 2110303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&prologue); 2111303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // No more valid handles (the result handle was the last one). Restore 2112303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // previous handle scope. 2113303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(Operand::StaticVariable(next_address), ebx); 2114303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org sub(Operand::StaticVariable(level_address), Immediate(1)); 2115594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(above_equal, kInvalidHandleScopeLevel); 2116303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmp(edi, Operand::StaticVariable(limit_address)); 21177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, &delete_allocated_handles); 2118303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&leave_exit_frame); 2119303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 2120303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Check if the function scheduled an exception. 2121303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference scheduled_exception_address = 2122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::scheduled_exception_address(isolate()); 2123303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmp(Operand::StaticVariable(scheduled_exception_address), 2124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Immediate(isolate()->factory()->the_hole_value())); 21257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, &promote_scheduled_exception); 212667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 212767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#if ENABLE_EXTRA_CHECKS 212867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org // Check if the function returned a valid JavaScript value. 212967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Label ok; 213067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register return_value = eax; 213167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register map = ecx; 213267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 213367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org JumpIfSmi(return_value, &ok, Label::kNear); 213467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org mov(map, FieldOperand(return_value, HeapObject::kMapOffset)); 213567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 213667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_NONSTRING_TYPE); 213767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(below, &ok, Label::kNear); 213867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 213967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 214067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(above_equal, &ok, Label::kNear); 214167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 214267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(map, isolate()->factory()->heap_number_map()); 214367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 214467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 214567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->undefined_value()); 214667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 214767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 214867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->true_value()); 214967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 215067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 215167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->false_value()); 215267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 215367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 215467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->null_value()); 215567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 215667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 2157594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kAPICallReturnedInvalidObject); 215867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 215967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org bind(&ok); 216067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#endif 216167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 21624a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com LeaveApiExitFrame(); 21634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com ret(stack_space * kPointerSize); 2164c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2165b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org bind(&promote_scheduled_exception); 2166b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); 2167b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org 2168303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // HandleScope limit has changed. Delete allocated extensions. 2169ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference delete_extensions = 2170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::delete_handle_scope_extensions(isolate()); 2171303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&delete_allocated_handles); 2172303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(Operand::StaticVariable(limit_address), edi); 2173303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(edi, eax); 217432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org mov(Operand(esp, 0), 217532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(eax, Immediate(delete_extensions)); 2177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com call(eax); 2178303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(eax, edi); 2179303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(&leave_exit_frame); 2180c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 2181c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2182c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2183ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 218443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the entry point and jump to the C entry runtime stub. 21853bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(ebx, Immediate(ext)); 2186a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org CEntryStub ces(1); 21878432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org jmp(ces.GetCode(isolate()), RelocInfo::CODE_TARGET); 218843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 218943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 219043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 219140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { 219240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // This macro takes the dst register to make the code more readable 219340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // at the call sites. However, the dst register has to be ecx to 219440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // follow the calling convention which requires the call type to be 219540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // in ecx. 219640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ASSERT(dst.is(ecx)); 219740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (call_kind == CALL_AS_FUNCTION) { 219840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Set to some non-zero smi by updating the least significant 219940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // byte. 2200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov_b(dst, 1 << kSmiTagSize); 220140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } else { 220240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Set to smi zero by clearing the register. 2203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xor_(dst, dst); 220440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 220540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 220640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 220740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 220943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 221043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> code_constant, 221143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const Operand& code_operand, 221283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 22132efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 2214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 221583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance done_near, 221640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 221740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool definitely_matches = false; 22192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = false; 222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label invoke; 222143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expected.is_immediate()) { 222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(actual.is_immediate()); 222343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expected.immediate() == actual.immediate()) { 222443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen definitely_matches = true; 222543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 222643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(eax, actual.immediate()); 2227b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; 2228b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (expected.immediate() == sentinel) { 2229b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Don't worry about adapting arguments for builtins that 2230b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // don't want that done. Skip adaption code by making it look 2231b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // like we have a match between expected and actual number of 2232b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // arguments. 2233b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org definitely_matches = true; 2234b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 22352efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = true; 2236b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org mov(ebx, expected.immediate()); 2237b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 223843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 223943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 224043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (actual.is_immediate()) { 224143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expected is in register, actual is immediate. This is the 224243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // case when we invoke function values without going through the 224343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IC mechanism. 224443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cmp(expected.reg(), actual.immediate()); 224543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen j(equal, &invoke); 224643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(expected.reg().is(ebx)); 224743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(eax, actual.immediate()); 224843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (!expected.reg().is(actual.reg())) { 224943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Both expected and actual are in (different) registers. This 225043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is the case when we invoke functions using call and apply. 2251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(expected.reg(), actual.reg()); 225243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen j(equal, &invoke); 225343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(actual.reg().is(eax)); 225443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(expected.reg().is(ebx)); 225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 225643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 225743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!definitely_matches) { 225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> adaptor = 22607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->builtins()->ArgumentsAdaptorTrampoline(); 226143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!code_constant.is_null()) { 22623bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(edx, Immediate(code_constant)); 2263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (!code_operand.is_reg(edx)) { 226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(edx, code_operand); 226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (flag == CALL_FUNCTION) { 2269fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); 227040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org SetCallKind(ecx, call_kind); 2271236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org call(adaptor, RelocInfo::CODE_TARGET); 2272fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org call_wrapper.AfterCall(); 22732efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!*definitely_mismatches) { 22742efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(done, done_near); 22752efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 227643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 227740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org SetCallKind(ecx, call_kind); 2278236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org jmp(adaptor, RelocInfo::CODE_TARGET); 227943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&invoke); 228143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 228243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 228343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 228443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeCode(const Operand& code, 228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& expected, 228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 228940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 229040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 2291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 229483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 22952efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 2296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokePrologue(expected, actual, Handle<Code>::null(), code, 22972efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org &done, &definitely_mismatches, flag, Label::kNear, 22982efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper, call_kind); 22992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 23002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 23012efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code)); 23022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(ecx, call_kind); 23032efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call(code); 23042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 23052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 23062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(flag == JUMP_FUNCTION); 23072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(ecx, call_kind); 23082efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(code); 23092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 23102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 231143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 231243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 231343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 231443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 231543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeCode(Handle<Code> code, 231643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& expected, 231743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2318236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org RelocInfo::Mode rmode, 2319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 232040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 232140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 2322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 232583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 2326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Operand dummy(eax, 0); 23272efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 23282efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org InvokePrologue(expected, actual, code, dummy, &done, &definitely_mismatches, 23292efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org flag, Label::kNear, call_wrapper, call_kind); 23302efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 23312efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 23322efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code, rmode)); 23332efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(ecx, call_kind); 23342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call(code, rmode); 23352efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 23362efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 23372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(flag == JUMP_FUNCTION); 23382efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(ecx, call_kind); 23392efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(code, rmode); 23402efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 23412efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 234243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 234343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 234443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeFunction(Register fun, 234743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 234940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 235040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 2351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 235443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(fun.is(edi)); 235543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 235643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 235743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 235830ce411529579186181838984710b0b0980857aaricow@chromium.org SmiUntag(ebx); 235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParameterCount expected(ebx); 2361145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 236240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org expected, actual, flag, call_wrapper, call_kind); 236343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 236443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 236732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 23685c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 2369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2370d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org const CallWrapper& call_wrapper, 2371d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org CallKind call_kind) { 2372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 2374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 23755c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Get the function and setup the context. 237664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org LoadHeapObject(edi, function); 23775c838251403b0be9a882540f1922577abba4c872ager@chromium.org mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // We call indirectly through the code field in the function to 2380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // allow recompilation to take effect without changing any of the 2381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // call sites. 2382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2383394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com expected, actual, flag, call_wrapper, call_kind); 23845c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 23855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 2388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2389fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper) { 2390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a builtin without a valid frame. 2391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 239343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Rely on the assertion to check that the number of provided 239443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // arguments match the expected number of arguments. Fake a 239543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parameter count to avoid emitting code to do the check. 239643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParameterCount expected(0); 2397145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(edi, id); 2398145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2399d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org expected, expected, flag, call_wrapper, CALL_AS_METHOD); 240043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2403145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinFunction(Register target, 2404145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com Builtins::JavaScript id) { 2405145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the JavaScript builtin function from the builtins object. 240646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 2407c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 2408145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com mov(target, FieldOperand(target, 2409145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com JSBuiltinsObject::OffsetOfFunctionWithId(id))); 2410145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com} 2411c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2413145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 2414145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com ASSERT(!target.is(edi)); 24155c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Load the JavaScript builtin function from the builtins object. 2416145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(edi, id); 2417145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the code entry point from the function into the target register. 2418145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 241943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 242043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 242143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2422ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 2423ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org if (context_chain_length > 0) { 2424ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Move up the chain of contexts to the context containing the slot. 24256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org mov(dst, Operand(esi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2426ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int i = 1; i < context_chain_length; i++) { 24276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org mov(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2428ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 242983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 243083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Slot is in the current function context. Move it into the 243183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // destination register in case we store into it (the write barrier 243283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // cannot be allowed to destroy the context in esi). 243383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org mov(dst, esi); 243483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 243583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 24364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // We should not have found a with context by walking the context chain 24374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // (i.e., the static scope chain and runtime context chain do not agree). 24384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // A variable occurring in such a scope should have slot type LOOKUP and 24394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // not CONTEXT. 2440badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 24413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org cmp(FieldOperand(dst, HeapObject::kMapOffset), 24423cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org isolate()->factory()->with_context_map()); 2443594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kVariableResolvedToWithContext); 2444ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 2445ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 2446ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2447ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 24481145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadTransitionedArrayMapConditional( 24491145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 24501145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 24511145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 24521145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 24531145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match) { 24541145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Load the global or builtins object from the current context. 245546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(scratch, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 245646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 24571145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24581145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Check that the function's map is the same as the expected cached map. 2459830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org mov(scratch, Operand(scratch, 2460830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); 2461830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 2462830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org size_t offset = expected_kind * kPointerSize + 2463830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 2464830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org cmp(map_in_out, FieldOperand(scratch, offset)); 24651145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org j(not_equal, no_map_match); 24661145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24671145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Use the transitioned cached map. 2468830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org offset = transitioned_kind * kPointerSize + 2469830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 2470830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org mov(map_in_out, FieldOperand(scratch, offset)); 24711145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org} 24721145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24731145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24741145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadInitialArrayMap( 2475830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Register function_in, Register scratch, 2476830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Register map_out, bool can_have_holes) { 2477fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org ASSERT(!function_in.is(map_out)); 2478fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Label done; 2479fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org mov(map_out, FieldOperand(function_in, 2480fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org JSFunction::kPrototypeOrInitialMapOffset)); 2481fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org if (!FLAG_smi_only_arrays) { 2482830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; 2483830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 2484830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org kind, 2485830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org map_out, 2486830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org scratch, 2487830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org &done); 2488830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else if (can_have_holes) { 2489830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 2490830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_HOLEY_SMI_ELEMENTS, 24911145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org map_out, 24921145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org scratch, 24931145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org &done); 2494fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 2495fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org bind(&done); 2496fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 2497fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 2498fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 24994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid MacroAssembler::LoadGlobalContext(Register global_context) { 25004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Load the global or builtins object from the current context. 25014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org mov(global_context, 25024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 25034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Load the native context from the global or builtins object. 25044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org mov(global_context, 25054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org FieldOperand(global_context, GlobalObject::kNativeContextOffset)); 25064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 25074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 25084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 2509d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::LoadGlobalFunction(int index, Register function) { 2510d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Load the global or builtins object from the current context. 251146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(function, 251246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 251346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 25144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org mov(function, 25154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org FieldOperand(function, GlobalObject::kNativeContextOffset)); 251646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 2517d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(function, Operand(function, Context::SlotOffset(index))); 2518d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2519d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2520d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2521d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 2522d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Register map) { 2523d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Load the initial map. The global functions all have initial maps. 2524d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2525badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 2526d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label ok, fail; 2527c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 2528d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org jmp(&ok); 2529d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org bind(&fail); 2530594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kGlobalFunctionsMustHaveInitialMap); 2531d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org bind(&ok); 2532d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 2533d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2534d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2535ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 25363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// Store the value in register src in the safepoint register stack 25373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// slot for register dst. 25383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 25393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(SafepointRegisterSlot(dst), src); 25403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Immediate src) { 25443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(SafepointRegisterSlot(dst), src); 25453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 25493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(dst, SafepointRegisterSlot(src)); 25503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 25543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return Operand(esp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 25553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint MacroAssembler::SafepointRegisterStackIndex(int reg_code) { 2559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // The registers are pushed starting with the lowest encoding, 2560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // which means that lowest encodings are furthest away from 2561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the stack pointer. 2562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); 2563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return kNumSafepointRegisters - reg_code - 1; 2564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 256764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MacroAssembler::LoadHeapObject(Register result, 256864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<HeapObject> object) { 256979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference embedding_raw_address; 257064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 257141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 257241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org mov(result, Operand::ForCell(cell)); 257364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 257464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org mov(result, object); 257564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 257664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 257764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 257864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 2579a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) { 258079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 2581a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 258241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 258341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org cmp(reg, Operand::ForCell(cell)); 2584a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 2585a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org cmp(reg, object); 2586a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 2587a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 2588a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 2589a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 259064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MacroAssembler::PushHeapObject(Handle<HeapObject> object) { 259179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 259264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 259341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 259441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org push(Operand::ForCell(cell)); 259564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 259664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Push(object); 259764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 259864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 259964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 260064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 260143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::Ret() { 260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ret(0); 260343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 260443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 260543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2606d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2607d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (is_uint16(bytes_dropped)) { 2608d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(bytes_dropped); 2609d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 2610d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com pop(scratch); 2611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(bytes_dropped)); 2612d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com push(scratch); 2613d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(0); 2614d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 2615d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 2616d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 2617d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 2618e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid MacroAssembler::VerifyX87StackDepth(uint32_t depth) { 2619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Make sure the floating point stack is either empty or has depth items. 2620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(depth <= 7); 2621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 2622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // The top-of-stack (tos) is 7 if there is one item pushed. 2623e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int tos = (8 - depth) % 8; 2624e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const int kTopMask = 0x3800; 2625e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org push(eax); 2626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org fwait(); 2627e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org fnstsw_ax(); 2628e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org and_(eax, kTopMask); 2629e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org shr(eax, 11); 2630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(eax, Immediate(tos)); 2631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kUnexpectedFPUStackDepthAfterInstruction); 2632e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org fnclex(); 2633e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pop(eax); 2634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 2635e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 2636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 263713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::Drop(int stack_elements) { 263813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org if (stack_elements > 0) { 2639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(stack_elements * kPointerSize)); 264013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } 264113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 264213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 264313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 26444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid MacroAssembler::Move(Register dst, Register src) { 26454a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!dst.is(src)) { 26464a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org mov(dst, src); 26474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 26484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 26494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 26504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 265343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(Operand::StaticVariable(ExternalReference(counter)), Immediate(value)); 265443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 265543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 265643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 265943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(value > 0); 266043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 266143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Operand operand = Operand::StaticVariable(ExternalReference(counter)); 266243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value == 1) { 266343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inc(operand); 266443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 266543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen add(operand, Immediate(value)); 266643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 266743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 266843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 266943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 267243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(value > 0); 267343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 267443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Operand operand = Operand::StaticVariable(ExternalReference(counter)); 267543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value == 1) { 267643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dec(operand); 267743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 267843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen sub(operand, Immediate(value)); 267943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 268043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 268143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 268243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2684b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::IncrementCounter(Condition cc, 2685b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org StatsCounter* counter, 2686b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int value) { 2687b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(value > 0); 2688b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 2689b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label skip; 2690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(NegateCondition(cc), &skip); 2691b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org pushfd(); 2692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org IncrementCounter(counter, value); 2693b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org popfd(); 2694b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bind(&skip); 2695b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2696b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2697b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2698b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::DecrementCounter(Condition cc, 2700b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org StatsCounter* counter, 2701b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int value) { 2702b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(value > 0); 2703b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 2704b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label skip; 2705b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(NegateCondition(cc), &skip); 2706b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org pushfd(); 2707b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DecrementCounter(counter, value); 2708b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org popfd(); 2709b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bind(&skip); 2710b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2711b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2712b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2713b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2714594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 2715594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (emit_debug_code()) Check(cc, reason); 271643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 271743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 271843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27190b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MacroAssembler::AssertFastElements(Register elements) { 2720badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 27217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Factory* factory = isolate()->factory(); 27220b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Label ok; 27230b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 27247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(factory->fixed_array_map())); 27250b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org j(equal, &ok); 27260b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 272784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org Immediate(factory->fixed_double_array_map())); 272884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org j(equal, &ok); 272984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 27307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(factory->fixed_cow_array_map())); 27310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org j(equal, &ok); 2732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kJSObjectWithFastElementsMapHasSlowElements); 27330b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org bind(&ok); 27340b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 27350b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org} 27360b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 27370b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 2738594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 273943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label L; 27407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(cc, &L); 2741594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(reason); 274243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will not return here 274343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&L); 274443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 274543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 274643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2747c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgvoid MacroAssembler::CheckStackAlignment() { 2748c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 2749c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment_mask = frame_alignment - 1; 2750c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org if (frame_alignment > kPointerSize) { 2751c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 2752c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org Label alignment_as_expected; 2753c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org test(esp, Immediate(frame_alignment_mask)); 2754c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org j(zero, &alignment_as_expected); 2755c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Abort if stack is not aligned. 2756c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int3(); 2757c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org bind(&alignment_as_expected); 2758c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 2759c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org} 2760c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2761c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2762594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Abort(BailoutReason reason) { 276343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We want to pass the msg string like a smi to avoid GC 276443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // problems, however msg is not guaranteed to be aligned 276543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // properly. Instead, we pass an aligned pointer that is 27663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // a proper v8 smi, but also pass the alignment difference 276743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // from the real pointer as a smi. 2768594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org const char* msg = GetBailoutReason(reason); 276943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen intptr_t p1 = reinterpret_cast<intptr_t>(msg); 277043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; 277143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); 277243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (msg != NULL) { 277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RecordComment("Abort message: "); 277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RecordComment(msg); 277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 277743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 2778ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 277943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(eax); 278043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(Immediate(p0)); 278143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0)))); 2782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Disable stub call restrictions to always allow calls to abort. 2783c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!has_frame_) { 2784c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't actually want to generate a pile of code for this, so just 2785c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // claim there is a stack frame, without generating one. 2786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(this, StackFrame::NONE); 2787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallRuntime(Runtime::kAbort, 2); 2788c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2789c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallRuntime(Runtime::kAbort, 2); 2790c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 279143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will not return here 2792ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org int3(); 279343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 279443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 279543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 279640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::LoadInstanceDescriptors(Register map, 279740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Register descriptors) { 279889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org mov(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 279940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 280040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 280140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 280206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 280306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org mov(dst, FieldOperand(map, Map::kBitField3Offset)); 280406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 280506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org} 280606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 280706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 2808c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::LoadPowerOf2(XMMRegister dst, 2809c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register scratch, 2810c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org int power) { 2811c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org ASSERT(is_uintn(power + HeapNumber::kExponentBias, 2812c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org HeapNumber::kExponentBits)); 2813c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org mov(scratch, Immediate(power + HeapNumber::kExponentBias)); 2814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movd(dst, scratch); 2815c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org psllq(dst, HeapNumber::kMantissaBits); 2816c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 2817c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 2818c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 28195c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( 28205c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register instance_type, 28215c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch, 2822cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org Label* failure) { 28235c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (!scratch.is(instance_type)) { 28245c838251403b0be9a882540f1922577abba4c872ager@chromium.org mov(scratch, instance_type); 28255c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 28265c838251403b0be9a882540f1922577abba4c872ager@chromium.org and_(scratch, 28275c838251403b0be9a882540f1922577abba4c872ager@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 2828e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org cmp(scratch, kStringTag | kSeqStringTag | kOneByteStringTag); 28295c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, failure); 28305c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 28315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 28325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2833b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register object1, 2834b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register object2, 2835b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register scratch1, 2836b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register scratch2, 2837b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label* failure) { 2838b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check that both objects are not smis. 283980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 2840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch1, object1); 2841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, object2); 28427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org JumpIfSmi(scratch1, failure); 2843b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2844b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Load instance type for both strings. 2845b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org mov(scratch1, FieldOperand(object1, HeapObject::kMapOffset)); 2846b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org mov(scratch2, FieldOperand(object2, HeapObject::kMapOffset)); 2847b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzx_b(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2848b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzx_b(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2849b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 28502efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check that both are flat ASCII strings. 285146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org const int kFlatAsciiStringMask = 285246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2853c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org const int kFlatAsciiStringTag = 2854c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 2855b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Interleave bits from both instance types and compare them in one check. 285646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 2857b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org and_(scratch1, kFlatAsciiStringMask); 2858b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org and_(scratch2, kFlatAsciiStringMask); 285946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org lea(scratch1, Operand(scratch1, scratch2, times_8, 0)); 286046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 3)); 2861b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(not_equal, failure); 2862b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2863b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2864b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 28651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Operand operand, 28661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 28671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 2868ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2869ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label succeed; 2870ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org test(operand, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2871ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(zero, &succeed); 2872ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cmpb(operand, static_cast<uint8_t>(SYMBOL_TYPE)); 2873ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(not_equal, not_unique_name, distance); 2874ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2875ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org bind(&succeed); 28761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 28771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 28781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 2879ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { 2880c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 2881c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (frame_alignment != 0) { 2882ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Make stack end at alignment and make room for num_arguments words 2883ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // and the original value of esp. 2884ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(scratch, esp); 2885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate((num_arguments + 1) * kPointerSize)); 2886c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 2887c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org and_(esp, -frame_alignment); 2888ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(Operand(esp, num_arguments * kPointerSize), scratch); 2889ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 2890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(num_arguments * kPointerSize)); 2891ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 2892ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2893ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2894ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2895ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::CallCFunction(ExternalReference function, 2896ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments) { 2897ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Trashing eax is ok as it will be the return value. 2898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(eax, Immediate(function)); 2899ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org CallCFunction(eax, num_arguments); 2900ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2901ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2902ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2903ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::CallCFunction(Register function, 2904ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments) { 2905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(has_frame()); 2906c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check stack alignment. 2907badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 2908c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org CheckStackAlignment(); 2909c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 2910c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com call(function); 2912ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (OS::ActivationFrameAlignment() != 0) { 2913ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(esp, Operand(esp, num_arguments * kPointerSize)); 2914ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 2915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(num_arguments * kPointerSize)); 2916ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 2917ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2918ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2919ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4) { 2921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r2)) return true; 2922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r3)) return true; 2923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r4)) return true; 2924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r3)) return true; 2925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r4)) return true; 2926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r3.is(r4)) return true; 2927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 2928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 293143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCodePatcher::CodePatcher(byte* address, int size) 2932c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : address_(address), 2933c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_(size), 2934212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org masm_(NULL, address, size + Assembler::kGap) { 29353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Create a new macro assembler pointing to the address of the code to patch. 293643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The size is adjusted with kGap on order for the assembler to generate size 293743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bytes of instructions without failing with buffer size constraints. 293843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 293943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 294043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 294143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 294243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCodePatcher::~CodePatcher() { 294343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Indicate that code has changed. 294443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CPU::FlushICache(address_, size_); 294543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 294643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that the code was patched as expected. 294743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(masm_.pc_ == address_ + size_); 294843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 294943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 295043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 295143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckPageFlag( 2953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 2954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 2955c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 2956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 2957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 2958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 2959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cc == zero || cc == not_zero); 2960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 2961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 2962c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Immediate(~Page::kPageAlignmentMask)); 2964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 2965c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mask < (1 << kBitsPerByte)) { 2967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(scratch, MemoryChunk::kFlagsOffset), 2968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<uint8_t>(mask)); 2969c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 2971c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2972c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 29737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org} 29747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 29757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 29767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid MacroAssembler::CheckPageFlagForMap( 29777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map, 29787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int mask, 29797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Condition cc, 29807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label* condition_met, 29817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::Distance condition_met_distance) { 29827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(cc == zero || cc == not_zero); 29837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Page* page = Page::FromAddress(map->address()); 29847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference reference(ExternalReference::page_flags(page)); 29857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // The inlined static address check of the page's flags relies 29867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // on maps never being compacted. 29877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ASSERT(!isolate()->heap()->mark_compact_collector()-> 29887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org IsOnEvacuationCandidate(*map)); 29897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (mask < (1 << kBitsPerByte)) { 29907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test_b(Operand::StaticVariable(reference), static_cast<uint8_t>(mask)); 29917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 29927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test(Operand::StaticVariable(reference), Immediate(mask)); 29937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 29947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org j(cc, condition_met, condition_met_distance); 2995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2998f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid MacroAssembler::CheckMapDeprecated(Handle<Map> map, 2999f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 3000f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated) { 3001f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (map->CanBeDeprecated()) { 3002f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org mov(scratch, map); 3003f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org mov(scratch, FieldOperand(scratch, Map::kBitField3Offset)); 3004f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org and_(scratch, Immediate(Smi::FromInt(Map::Deprecated::kMask))); 3005f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org j(not_zero, if_deprecated); 3006f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 3007f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 3008f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 3009f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 3010c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfBlack(Register object, 3011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0, 3012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 3013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 3014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_near) { 3015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HasColor(object, scratch0, scratch1, 3016c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com on_black, on_black_near, 3017c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 0); // kBlackBitPattern. 3018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 3019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::HasColor(Register object, 3023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 3024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 3025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* has_color, 3026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance has_color_distance, 3027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int first_bit, 3028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int second_bit) { 3029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object, bitmap_scratch, mask_scratch, ecx)); 3030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3031c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(object, bitmap_scratch, mask_scratch); 3032c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label other_color, word_boundary; 3034c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3035c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(first_bit == 1 ? zero : not_zero, &other_color, Label::kNear); 3036c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(mask_scratch, mask_scratch); // Shift left 1 by adding. 3037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &word_boundary, Label::kNear); 3038c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3039c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); 3040c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&other_color, Label::kNear); 3041c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&word_boundary); 3043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize), 1); 3044c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3045c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); 3046c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&other_color); 3047c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3048c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::GetMarkBits(Register addr_reg, 3051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 3052c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg) { 3053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(addr_reg, mask_reg, bitmap_reg, ecx)); 3054c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 3055c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_reg, addr_reg); 3056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ecx, addr_reg); 3057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int shift = 3058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 3059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(ecx, shift); 3060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(ecx, 3061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (Page::kPageAlignmentMask >> shift) & ~(Bitmap::kBytesPerCell - 1)); 3062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(bitmap_reg, ecx); 3064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ecx, addr_reg); 3065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(ecx, kPointerSizeLog2); 3066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(ecx, (1 << Bitmap::kBitsPerCellLog2) - 1); 3067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(mask_reg, Immediate(1)); 3068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shl_cl(mask_reg); 3069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::EnsureNotWhite( 3073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 3074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 3075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 3076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* value_is_white_and_not_data, 3077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 3078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, ecx)); 3079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(value, bitmap_scratch, mask_scratch); 3080c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the value is black or grey we don't need to do anything. 3082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 3083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 3084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 3085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 3086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 3088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Since both black and grey have a 1 in the first position and white does 3090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not have a 1 there we only need to check one bit. 3091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, &done, Label::kNear); 3093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3094000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 3095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for impossible bit pattern. 3096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 3097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com push(mask_scratch); 3098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // shl. May overflow making the check conservative. 3099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(mask_scratch, mask_scratch); 3100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 3102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 3103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 3104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pop(mask_scratch); 3105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is white. We check whether it is data that doesn't need scanning. 3108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Currently only checks for HeapNumber and non-cons strings. 3109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register map = ecx; // Holds map while checking type. 3110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register length = ecx; // Holds length of object after checking type. 3111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_heap_number; 3112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 3113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for heap-number 3115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(map, FieldOperand(value, HeapObject::kMapOffset)); 3116d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org cmp(map, isolate()->factory()->heap_number_map()); 3117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, ¬_heap_number, Label::kNear); 3118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Immediate(HeapNumber::kSize)); 3119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 3120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_heap_number); 3122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for strings. 3123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 3124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 3125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 3126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 3127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register instance_type = ecx; 3128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 3129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(instance_type, kIsIndirectStringMask | kIsNotStringMask); 3130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, value_is_white_and_not_data); 3131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It's a non-indirect (non-cons and non-slice) string. 3132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's external, the length is just ExternalString::kSize. 3133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). 3134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_external; 3135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // External strings are the only ones with the kExternalStringTag bit 3136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // set. 3137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); 3138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 3139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(instance_type, kExternalStringTag); 3140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_external, Label::kNear); 3141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Immediate(ExternalString::kSize)); 3142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 3143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_external); 3145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sequential string, either ASCII or UC16. 3146e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(kOneByteStringTag == 0x04); 3147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(kStringEncodingMask)); 3148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xor_(length, Immediate(kStringEncodingMask)); 3149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(length, Immediate(0x04)); 3150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value now either 4 (if ASCII) or 8 (if UC16), i.e., char-size shifted 3151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // by 2. If we multiply the string length as smi by this, it still 3152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // won't overflow a 32-bit value. 3153fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT_EQ(SeqOneByteString::kMaxSize, SeqTwoByteString::kMaxSize); 3154fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT(SeqOneByteString::kMaxSize <= 3155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<int>(0xffffffffu >> (2 + kSmiTagSize))); 3156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com imul(length, FieldOperand(value, String::kLengthOffset)); 3157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(length, 2 + kSmiTagSize + kSmiShiftSize); 3158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 3159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(~kObjectAlignmentMask)); 3160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 3162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a data object, and it is white. Mark it black. Since we know 3163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that the object is white we can make it black by flipping one bit. 3164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 3165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 3167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), 3168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com length); 3169000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 3170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset)); 3171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); 3172594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(less_equal, kLiveBytesCountOverflowChunkSize); 3173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 3176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3178be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3179355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid MacroAssembler::EnumLength(Register dst, Register map) { 3180355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3181355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(dst, FieldOperand(map, Map::kBitField3Offset)); 3182355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org and_(dst, Immediate(Smi::FromInt(Map::EnumLengthBits::kMask))); 3183355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 3184355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3185355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3186be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid MacroAssembler::CheckEnumCache(Label* call_runtime) { 3187355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label next, start; 3188be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ecx, eax); 3189be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3190355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check if the enum length field is properly initialized, indicating that 3191355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // there is an enum cache. 3192be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 3193be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3194355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(edx, ebx); 3195355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(edx, Immediate(Smi::FromInt(Map::kInvalidEnumCache))); 3196de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org j(equal, call_runtime); 3197de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 3198355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org jmp(&start); 3199355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3200355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&next); 3201355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 3202be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3203be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For all objects but the receiver, check that the cache is empty. 3204355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(edx, ebx); 3205355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(edx, Immediate(Smi::FromInt(0))); 3206355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org j(not_equal, call_runtime); 3207355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3208355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&start); 3209355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3210355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check that there are no elements. Register rcx contains the current JS 3211355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // object we've reached through the prototype chain. 3212355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset)); 3213355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(ecx, isolate()->factory()->empty_fixed_array()); 3214be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, call_runtime); 3215be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3216be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 3217be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org cmp(ecx, isolate()->factory()->null_value()); 3218be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, &next); 3219be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 3220be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 322159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 3222ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MacroAssembler::TestJSArrayForAllocationMemento( 322359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Register receiver_reg, 322494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register scratch_reg) { 3225ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label no_memento_available; 322628381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org 322759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_start = 322859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_start(isolate()); 322959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_allocation_top = 323059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 323159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 323259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org lea(scratch_reg, Operand(receiver_reg, 3233ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); 323459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmp(scratch_reg, Immediate(new_space_start)); 3235ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(less, &no_memento_available); 323659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmp(scratch_reg, Operand::StaticVariable(new_space_allocation_top)); 3237ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(greater, &no_memento_available); 3238ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), 3239ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map()))); 3240ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org bind(&no_memento_available); 324159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 324259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 324359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 324443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 32459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 3247