1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h" 1042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org#include "src/base/division-by-constant.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h" 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 2071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// ------------------------------------------------------------------------- 237be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// MacroAssembler implementation. 247be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 25c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) 26c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : Assembler(arg_isolate, buffer, size), 277276f14ca716596e0a0d17539516370c1f453847kasper.lund generating_stub_(false), 28c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com has_frame_(false) { 29c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (isolate() != NULL) { 303d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org // TODO(titzer): should we just use a null handle here instead? 31c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), 32c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org isolate()); 33c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 37935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 38e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!r.IsDouble()); 39935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8()) { 40935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsx_b(dst, src); 41935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger8()) { 42935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movzx_b(dst, src); 43935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16()) { 44935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsx_w(dst, src); 45935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger16()) { 46935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movzx_w(dst, src); 47935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 48935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov(dst, src); 49935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 50935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 51935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 52935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 53935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::Store(Register src, const Operand& dst, Representation r) { 54e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!r.IsDouble()); 55935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8() || r.IsUInteger8()) { 56935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov_b(dst, src); 57935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16() || r.IsUInteger16()) { 58935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov_w(dst, src); 59935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 60d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (r.IsHeapObject()) { 61d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org AssertNotSmi(src); 62d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } else if (r.IsSmi()) { 63d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org AssertSmi(src); 64d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 65935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org mov(dst, src); 66935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 67935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 68935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 69935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 70594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 71594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (isolate()->heap()->RootCanBeTreatedAsConstant(index)) { 72594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 73594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, value); 74594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 75594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 76594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 77594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 78594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, Immediate(index)); 79594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(destination, Operand::StaticArray(destination, 80594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org times_pointer_size, 81594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org roots_array_start)); 82594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 83594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 84594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 85594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::StoreRoot(Register source, 86594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register scratch, 87594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 88e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); 89594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 90594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 91594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(scratch, Immediate(index)); 92594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start), 93594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org source); 94594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 95594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 96594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 97594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(Register with, 98594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register scratch, 99594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 100594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference roots_array_start = 101594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ExternalReference::roots_array_start(isolate()); 102594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org mov(scratch, Immediate(index)); 103594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, Operand::StaticArray(scratch, 104594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org times_pointer_size, 105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org roots_array_start)); 106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 107594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 108594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 109594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 110e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(isolate()->heap()->RootCanBeTreatedAsConstant(index)); 111594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 112594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, value); 113594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 114594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 115594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 116594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::CompareRoot(const Operand& with, 117594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Heap::RootListIndex index) { 118e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(isolate()->heap()->RootCanBeTreatedAsConstant(index)); 119594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Object> value(&isolate()->heap()->roots_array_start()[index]); 120594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org cmp(with, value); 121594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 122594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 123594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InNewSpace( 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cc == equal || cc == not_equal); 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Immediate(~Page::kPageAlignmentMask)); 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 136ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that we can use a test_b. 138e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(MemoryChunk::IN_FROM_SPACE < 8); 139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(MemoryChunk::IN_TO_SPACE < 8); 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask = (1 << MemoryChunk::IN_FROM_SPACE) 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com | (1 << MemoryChunk::IN_TO_SPACE); 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If non-zero, the page belongs to new-space. 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(scratch, MemoryChunk::kFlagsOffset), 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<uint8_t>(mask)); 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 147ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14830ce411529579186181838984710b0b0980857aaricow@chromium.org 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RememberedSetHelper( 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, // Only used for debug checks. 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler::RememberedSetFinalAction and_then) { 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 156000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load store buffer top. 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference store_buffer = 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::store_buffer_top(isolate()); 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Operand::StaticVariable(store_buffer)); 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store pointer to buffer. 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand(scratch, 0), addr); 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Increment buffer top. 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(scratch, Immediate(kPointerSize)); 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Write back new top of buffer. 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand::StaticVariable(store_buffer), scratch); 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call stub on end of buffer. 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for end of buffer. 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label buffer_overflowed; 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, &buffer_overflowed, Label::kNear); 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&buffer_overflowed); 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 181e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(and_then == kFallThroughAtEnd); 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &done, Label::kNear); 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 18421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp); 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&store_buffer_overflow); 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(and_then == kFallThroughAtEnd); 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 196c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister scratch_reg, 197c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register result_reg) { 198c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 19989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Label conv_failure; 200a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org xorps(scratch_reg, scratch_reg); 20146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cvtsd2si(result_reg, input_reg); 202c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org test(result_reg, Immediate(0xFFFFFF00)); 203c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 204a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmp(result_reg, Immediate(0x1)); 205a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(overflow, &conv_failure, Label::kNear); 20689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org mov(result_reg, Immediate(0)); 207a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org setcc(sign, result_reg); 20889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org sub(result_reg, Immediate(1)); 20989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org and_(result_reg, Immediate(255)); 21089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org jmp(&done, Label::kNear); 21189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org bind(&conv_failure); 212a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(result_reg, Immediate(0)); 21389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ucomisd(input_reg, scratch_reg); 21489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(below, &done, Label::kNear); 215a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(result_reg, Immediate(255)); 216c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 217c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 218c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 219c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 220c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampUint8(Register reg) { 221c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 222c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org test(reg, Immediate(0xFFFFFF00)); 223c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 224c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org setcc(negative, reg); // 1 if negative, 0 if positive. 225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org dec_b(reg); // 0 if negative, 255 if positive. 226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 227c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 228c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 229c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2308fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::SlowTruncateToI(Register result_reg, 2318fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Register input_reg, 2328fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org int offset) { 233f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 234f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(stub.GetCode(), RelocInfo::CODE_TARGET); 2358fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 2368fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2378fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2388fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 2398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org XMMRegister input_reg) { 2408fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label done; 2418fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cvttsd2si(result_reg, Operand(input_reg)); 242a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmp(result_reg, 0x1); 243a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 2448fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2458fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(esp, Immediate(kDoubleSize)); 2460fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(MemOperand(esp, 0), input_reg); 2478fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, esp, 0); 2488fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(esp, Immediate(kDoubleSize)); 2498fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&done); 2508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 2518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2528fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 25306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgvoid MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, 2548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org XMMRegister scratch, 2558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org MinusZeroMode minus_zero_mode, 25606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label* lost_precision, Label* is_nan, 25706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label* minus_zero, Label::Distance dst) { 258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input_reg.is(scratch)); 2598fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cvttsd2si(result_reg, Operand(input_reg)); 260528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtsi2sd(scratch, Operand(result_reg)); 2618fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ucomisd(scratch, input_reg); 26206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org j(not_equal, lost_precision, dst); 26306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org j(parity_even, is_nan, dst); 2648fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 265c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 266c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // The integer converted back is equal to the original. We 267c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // only have to test if we got -0 as an input. 2688fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org test(result_reg, Operand(result_reg)); 2698fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_zero, &done, Label::kNear); 2708fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org movmskpd(result_reg, input_reg); 271c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Bit 0 contains the sign of the double in input_reg. 272c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // If input was positive, we are ok and return 0, otherwise 27306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // jump to minus_zero. 2748fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org and_(result_reg, 1); 27506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org j(not_zero, minus_zero, dst); 276c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 2778fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 2788fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 2798fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2808fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2818fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 2828fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Register input_reg) { 2838fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label done, slow_case; 2848fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2858fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (CpuFeatures::IsSupported(SSE3)) { 2868fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org CpuFeatureScope scope(this, SSE3); 2878fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org Label convert; 2888fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Use more powerful conversion when sse3 is available. 2898fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Load x87 register with heap number. 2908fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 2918fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Get exponent alone and check for too-big exponent. 2928fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org mov(result_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 2938fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org and_(result_reg, HeapNumber::kExponentMask); 2948fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org const uint32_t kTooBigExponent = 2958fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 2968fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cmp(Operand(result_reg), Immediate(kTooBigExponent)); 2978fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(greater_equal, &slow_case, Label::kNear); 2988fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 2998fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Reserve space for 64 bit answer. 3008fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(Operand(esp), Immediate(kDoubleSize)); 3018fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Do conversion, which cannot fail because we checked the exponent. 3028fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fisttp_d(Operand(esp, 0)); 3038fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 3048fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(Operand(esp), Immediate(kDoubleSize)); 3058fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org jmp(&done, Label::kNear); 3068fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3078fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Slow case. 3088fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&slow_case); 3098fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (input_reg.is(result_reg)) { 3108fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Input is clobbered. Restore number from fpu stack 3118fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(Operand(esp), Immediate(kDoubleSize)); 3128fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fstp_d(Operand(esp, 0)); 3138fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, esp, 0); 3148fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(esp, Immediate(kDoubleSize)); 3158fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } else { 3168fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org fstp(0); 3178fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, input_reg); 3188fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } else { 3200fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3218fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org cvttsd2si(result_reg, Operand(xmm0)); 322a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmp(result_reg, 0x1); 323a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 3248fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Check if the input was 0x8000000 (kMinInt). 3258fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // If no, then we got an overflow and we deoptimize. 3268fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ExternalReference min_int = ExternalReference::address_of_min_int(); 3278fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org ucomisd(xmm0, Operand::StaticVariable(min_int)); 3288fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(not_equal, &slow_case, Label::kNear); 3298fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org j(parity_even, &slow_case, Label::kNear); // NaN. 3308fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org jmp(&done, Label::kNear); 3318fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3328fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Slow case. 3338fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&slow_case); 3348fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org if (input_reg.is(result_reg)) { 3358fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org // Input is clobbered. Restore number from double scratch. 3368fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org sub(esp, Immediate(kDoubleSize)); 3370fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(MemOperand(esp, 0), xmm0); 3388fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, esp, 0); 3398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org add(esp, Immediate(kDoubleSize)); 3408fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } else { 3418fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org SlowTruncateToI(result_reg, input_reg); 3428fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3438fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org } 3448fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org bind(&done); 3458fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org} 3468fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 3478fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org 34846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::LoadUint32(XMMRegister dst, 3497e6132b924829c353864933f29124419916db550machenbach@chromium.org Register src) { 35046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Label done; 35146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cmp(src, Immediate(0)); 352b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ExternalReference uint32_bias = 353b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ExternalReference::address_of_uint32_bias(); 354528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtsi2sd(dst, src); 35546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org j(not_sign, &done, Label::kNear); 3567e6132b924829c353864933f29124419916db550machenbach@chromium.org addsd(dst, Operand::StaticVariable(uint32_bias)); 35746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org bind(&done); 35846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 35946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 36046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 361196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWriteArray( 362196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 363196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register value, 364196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register index, 365196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode save_fp, 366196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RememberedSetAction remembered_set_action, 367196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 368196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 375e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, kSmiTag); 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(value, Immediate(kSmiTagMask)); 377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &done); 378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Array access: calculate the destination address in the same manner as 381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // into an array of words. 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst = index; 384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, Operand(object, index, times_half_pointer_size, 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FixedArray::kHeaderSize - kHeapObjectTag)); 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 387196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWrite(object, dst, value, save_fp, remembered_set_action, 388196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org OMIT_SMI_CHECK, pointers_to_here_check_for_value); 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // turned on to provoke errors. 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 395e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(value, Immediate(bit_cast<int32_t>(kZapValue))); 396e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(index, Immediate(bit_cast<int32_t>(kZapValue))); 39783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 39883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 39983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 40083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteField( 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst, 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 408196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 409196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 41030ce411529579186181838984710b0b0980857aaricow@chromium.org // First, check if a write barrier is even needed. The tests below 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 41283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 414b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org // Skip barrier if writing a smi. 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done, Label::kNear); 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Although the object register is tagged, the offset is relative to the start 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the object, so so offset must be a multiple of kPointerSize. 421e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(offset, kPointerSize)); 422e88a9edffbbdbc4ccc9872560ac4d9ea6b188fbdwhesse@chromium.org 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, FieldOperand(object, offset)); 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(dst, (1 << kPointerSizeLog2) - 1); 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 432196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWrite(object, dst, value, save_fp, remembered_set_action, 433196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org OMIT_SMI_CHECK, pointers_to_here_check_for_value); 43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&done); 436b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 438b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // turned on to provoke errors. 439badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 440e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(value, Immediate(bit_cast<int32_t>(kZapValue))); 441e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(dst, Immediate(bit_cast<int32_t>(kZapValue))); 442b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 44343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 44443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4467028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid MacroAssembler::RecordWriteForMap( 4477028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register object, 4487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map, 4497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register scratch1, 4507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register scratch2, 4517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org SaveFPRegsMode save_fp) { 4527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label done; 4537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register address = scratch1; 4557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Register value = scratch2; 4567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (emit_debug_code()) { 4577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label ok; 4587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org lea(address, FieldOperand(object, HeapObject::kMapOffset)); 4597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test_b(address, (1 << kPointerSizeLog2) - 1); 4607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org j(zero, &ok, Label::kNear); 4617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int3(); 4627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bind(&ok); 4637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 4647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 465e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!object.is(value)); 466e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!object.is(address)); 467e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!value.is(address)); 468c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 4697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (!FLAG_incremental_marking) { 4717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return; 4727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 4737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 474196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // Compute the address. 475196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org lea(address, FieldOperand(object, HeapObject::kMapOffset)); 476196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 4777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // A single check of the map's pages interesting flag suffices, since it is 4787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // only set during incremental collection, and then it's also guaranteed that 4797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // the from object's page's interesting flag is also set. This optimization 4807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // relies on the fact that maps can never be in new space. 481e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!isolate()->heap()->InNewSpace(*map)); 4827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CheckPageFlagForMap(map, 4837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 4847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zero, 4857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org &done, 4867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::kNear); 4877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 488f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET, 489f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org save_fp); 4907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CallStub(&stub); 4917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bind(&done); 4937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 494dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // Count number of write barriers in generated code. 495dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 496dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 497dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 4987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Clobber clobbered input registers when running with the debug-code flag 4997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // turned on to provoke errors. 5007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (emit_debug_code()) { 501e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(value, Immediate(bit_cast<int32_t>(kZapValue))); 502e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(scratch1, Immediate(bit_cast<int32_t>(kZapValue))); 503e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(scratch2, Immediate(bit_cast<int32_t>(kZapValue))); 5047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 5057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org} 5067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 5077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 508196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWrite( 509196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 510196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register address, 511196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register value, 512196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode fp_mode, 513196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RememberedSetAction remembered_set_action, 514196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 515196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!object.is(value)); 517e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!object.is(address)); 518e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!value.is(address)); 519c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (remembered_set_action == OMIT_REMEMBERED_SET && 522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !FLAG_incremental_marking) { 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 526000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(value, Operand(address, 0)); 529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &ok, Label::kNear); 530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 53469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // First, check if a write barrier is even needed. The tests below 53569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // catch stores of Smis and stores into young gen. 53669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Label done; 53769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done, Label::kNear); 541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 543196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 544196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org CheckPageFlag(value, 545196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org value, // Used as scratch. 546196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 547196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org zero, 548196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org &done, 549196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label::kNear); 550196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(object, 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersFromHereAreInterestingMask, 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 558f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 559f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org fp_mode); 560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&stub); 56169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 56269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org bind(&done); 56369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 564dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // Count number of write barriers in generated code. 565dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 566dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 567dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered registers when running with the debug-code flag 56969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // turned on to provoke errors. 570badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 571e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(address, Immediate(bit_cast<int32_t>(kZapValue))); 572e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(value, Immediate(bit_cast<int32_t>(kZapValue))); 57369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 57469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 57569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 57669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 5775c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::DebugBreak() { 578a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(eax, Immediate(0)); 579ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak, isolate()))); 580f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), 1); 581f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 5825c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 58343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 584d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 585528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) { 586528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xorps(dst, dst); 587528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cvtsi2sd(dst, src); 588528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 589528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 590528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgbool MacroAssembler::IsUnsafeImmediate(const Immediate& x) { 5927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static const int kMaxImmediateBits = 17; 5934cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (!RelocInfo::IsNone(x.rmode_)) return false; 5947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return !is_intn(x.x_, kMaxImmediateBits); 5957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 5967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 598a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid MacroAssembler::SafeMove(Register dst, const Immediate& x) { 5997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 600a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(dst, Immediate(x.x_ ^ jit_cookie())); 6017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org xor_(dst, jit_cookie()); 6027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 603a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(dst, x); 6047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 6067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid MacroAssembler::SafePush(const Immediate& x) { 6097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 6107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org push(Immediate(x.x_ ^ jit_cookie())); 6117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org xor_(Operand(esp, 0), Immediate(jit_cookie())); 6127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 6137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org push(x); 6147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 6167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6187be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid MacroAssembler::CmpObjectType(Register heap_object, 6197be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org InstanceType type, 6207be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org Register map) { 6217be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 6227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpInstanceType(map, type); 6237be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 6247be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6257be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6267be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 6277be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 6287be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org static_cast<int8_t>(type)); 6297be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 6307be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6317be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 632d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comvoid MacroAssembler::CheckFastElements(Register map, 633d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 634d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance) { 635830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 636830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 637830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 638830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 640830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleyElementValue); 641c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckFastObjectElements(Register map, 646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 648830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 649830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 650830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 651830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 653830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleySmiElementValue); 654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(below_equal, fail, distance); 655d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 656830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleyElementValue); 657d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com j(above, fail, distance); 658d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com} 659d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 660d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 661830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid MacroAssembler::CheckFastSmiElements(Register map, 662830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 663830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance) { 664830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 665830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 667830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Map::kMaximumBitField2FastHoleySmiElementValue); 668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 672c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::StoreNumberToDoubleElements( 673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register maybe_number, 674c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register key, 676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister scratch2, 678c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 679fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset) { 680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label smi_value, done, maybe_nan, not_nan, is_nan, have_double_value; 681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(maybe_number, &smi_value, Label::kNear); 682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckMap(maybe_number, 684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate()->factory()->heap_number_map(), 685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fail, 686c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DONT_DO_SMI_CHECK); 687c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 688c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Double value, canonicalize NaN. 689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); 690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(FieldOperand(maybe_number, offset), 691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kNaNOrInfinityLowerBoundUpper32)); 692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater_equal, &maybe_nan, Label::kNear); 693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_nan); 695c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference canonical_nan_reference = 696c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::address_of_canonical_non_hole_nan(); 6973c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(scratch2, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 6983c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org bind(&have_double_value); 6993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(FieldOperand(elements, key, times_4, 7003c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 7013c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org scratch2); 702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&done); 703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 704c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&maybe_nan); 705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise 706c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // it's an Infinity, and the non-NaN code path applies. 707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater, &is_nan, Label::kNear); 708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); 709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_nan); 710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_nan); 7113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(scratch2, Operand::StaticVariable(canonical_nan_reference)); 712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&have_double_value, Label::kNear); 713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&smi_value); 715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a smi. Convert to a double and store. 716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve original value. 717c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch1, maybe_number); 718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiUntag(scratch1); 7193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Cvtsi2sd(scratch2, scratch1); 7203c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(FieldOperand(elements, key, times_4, 7213c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 7223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org scratch2); 723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 727935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 728f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 729f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 730f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 731f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 7325c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CheckMap(Register obj, 7335c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 7345c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 735a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type) { 73640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (smi_check_type == DO_SMI_CHECK) { 737c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org JumpIfSmi(obj, fail); 7385c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 739f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 740935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CompareMap(obj, map); 7415c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, fail); 7425c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7435c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7445c838251403b0be9a882540f1922577abba4c872ager@chromium.org 745ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgvoid MacroAssembler::DispatchMap(Register obj, 7462bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 747ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 748ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 749ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type) { 750ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label fail; 751560b07baefe6e8699f1ca093711f8298c43a01f9ager@chromium.org if (smi_check_type == DO_SMI_CHECK) { 752ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org JumpIfSmi(obj, &fail); 753ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 754ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map)); 755ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org j(equal, success); 756ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 757ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org bind(&fail); 758ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 759ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 760ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 7610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgCondition MacroAssembler::IsObjectStringType(Register heap_object, 7620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Register map, 7630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Register instance_type) { 7640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 7650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 76680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 7670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org test(instance_type, Immediate(kIsNotStringMask)); 7680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return zero; 7690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 7700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 7710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 772750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCondition MacroAssembler::IsObjectNameType(Register heap_object, 773750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 774750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type) { 775750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 776750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 777750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org cmpb(instance_type, static_cast<uint8_t>(LAST_NAME_TYPE)); 778750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return below_equal; 779750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 780750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 781750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 7821af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid MacroAssembler::IsObjectJSObjectType(Register heap_object, 7831af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register map, 7841af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register scratch, 7851af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Label* fail) { 7861af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 7871af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org IsInstanceJSObjectType(map, scratch, fail); 7881af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 7891af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 7901af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 7911af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid MacroAssembler::IsInstanceJSObjectType(Register map, 7921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Register scratch, 7931af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Label* fail) { 7941af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org movzx_b(scratch, FieldOperand(map, Map::kInstanceTypeOffset)); 795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(scratch, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 796d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org cmp(scratch, 797d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org LAST_NONCALLABLE_SPEC_OBJECT_TYPE - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 7981af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org j(above, fail); 7991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 8001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 8011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::FCmp() { 8031e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org fucomip(); 8041e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org fstp(0); 80543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 80743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 808c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNumber(Register object) { 809c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 810c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Label ok; 811c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org JumpIfSmi(object, &ok); 812c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org cmp(FieldOperand(object, HeapObject::kMapOffset), 813c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate()->factory()->heap_number_map()); 814594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandNotANumber); 815c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org bind(&ok); 816c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 8175c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 820c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(Register object) { 821c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 822c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 823594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandIsNotASmi); 824c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 825f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org} 826f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 827f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 828c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertString(Register object) { 829c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 830c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 831594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAString); 832c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org push(object); 833c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org mov(object, FieldOperand(object, HeapObject::kMapOffset)); 834c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CmpInstanceType(object, FIRST_NONSTRING_TYPE); 835c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org pop(object); 836594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kOperandIsNotAString); 837c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 838d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 839d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 840d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 841750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid MacroAssembler::AssertName(Register object) { 842750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (emit_debug_code()) { 843750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org test(object, Immediate(kSmiTagMask)); 844594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAName); 845750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org push(object); 846750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org mov(object, FieldOperand(object, HeapObject::kMapOffset)); 847750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CmpInstanceType(object, LAST_NAME_TYPE); 848750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org pop(object); 849594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below_equal, kOperandIsNotAName); 850750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 851750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 852750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 853750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 8542904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 8552904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org if (emit_debug_code()) { 8562904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Label done_checking; 8572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org AssertNotSmi(object); 8582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org cmp(object, isolate()->factory()->undefined_value()); 8592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org j(equal, &done_checking); 8602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org cmp(FieldOperand(object, 0), 8612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Immediate(isolate()->factory()->allocation_site_map())); 8622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Assert(equal, kExpectedUndefinedOrCell); 8632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org bind(&done_checking); 8642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 8652904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org} 8662904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 8672904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 868c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNotSmi(Register object) { 869c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 870c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org test(object, Immediate(kSmiTagMask)); 871594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmi); 872c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 87326c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org} 87426c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org 87526c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org 876285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::StubPrologue() { 877285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(ebp); // Caller's frame pointer. 878285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org mov(ebp, esp); 879285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(esi); // Callee's context. 880285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(Immediate(Smi::FromInt(StackFrame::STUB))); 881285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org} 882285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org 883285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org 884285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::Prologue(bool code_pre_aging) { 885285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org PredictableCodeSizeScope predictible_code_size_scope(this, 886285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org kNoCodeAgeSequenceLength); 887285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org if (code_pre_aging) { 888285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org // Pre-age the code. 889285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 890285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org RelocInfo::CODE_AGE_SEQUENCE); 891285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org Nop(kNoCodeAgeSequenceLength - Assembler::kCallInstructionLength); 892285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org } else { 893c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(ebp); // Caller's frame pointer. 894c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org mov(ebp, esp); 895c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(esi); // Callee's context. 896285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org push(edi); // Callee's JS function. 897c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 898c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 899c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 900c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 9017c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 90243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(ebp); 903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ebp, esp); 90443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(esi); 90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen push(Immediate(Smi::FromInt(type))); 906061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org push(Immediate(CodeObject())); 907badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 9087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); 909594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kCodeObjectNotProperlyPatched); 910061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org } 91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9147c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 915badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), 91743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Immediate(Smi::FromInt(type))); 918594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kStackFrameTypesMustMatch); 91943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen leave(); 92143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 923d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 924d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::EnterExitFramePrologue() { 925f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the frame structure on the stack. 926e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 927e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 928e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 929236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org push(ebp); 930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ebp, esp); 931236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 932d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Reserve room for entry stack pointer and push the code object. 933e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 9345c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(0)); // Saved entry sp, patched before call. 9355c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. 936236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 937236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Save the frame pointer and the context in top. 938cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); 939cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 940236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(c_entry_fp_address), ebp); 941236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(context_address), esi); 942c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 943236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 944236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { 946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Optionally save all XMM registers. 947a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (save_doubles) { 9481e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org int space = XMMRegister::kMaxNumRegisters * kDoubleSize + 9491e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org argc * kPointerSize; 950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(space)); 9510ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int offset = -2 * kPointerSize; 9521e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 953a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = XMMRegister::from_code(i); 9540fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); 955a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 956a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(argc * kPointerSize)); 958a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 959236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 960236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Get the required frame alignment for the OS. 9615de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org const int kFrameAlignment = base::OS::ActivationFrameAlignment(); 962236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (kFrameAlignment > 0) { 96321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); 964236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org and_(esp, -kFrameAlignment); 965236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } 966236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 967236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Patch the saved entry sp. 968236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); 969236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 970236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 971236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 972a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::EnterExitFrame(bool save_doubles) { 973d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(); 974c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 975f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up argc and argv in callee-saved registers. 976c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(edi, eax); 978c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org lea(esi, Operand(ebp, eax, times_4, offset)); 979c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 980ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Reserve space for argc, argv and isolate. 981ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org EnterExitFrameEpilogue(3, save_doubles); 982c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 983c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 984c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 9854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::EnterApiExitFrame(int argc) { 986d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(); 987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EnterExitFrameEpilogue(argc, false); 988c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 989c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 990c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::LeaveExitFrame(bool save_doubles) { 992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Optionally restore all XMM registers. 993a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (save_doubles) { 9940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int offset = -2 * kPointerSize; 9951e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = XMMRegister::from_code(i); 9970fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); 998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1001236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Get the return address from the stack and restore the frame pointer. 1002236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(ecx, Operand(ebp, 1 * kPointerSize)); 1003236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(ebp, Operand(ebp, 0 * kPointerSize)); 1004236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1005236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Pop the arguments and the receiver from the caller stack. 1006236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org lea(esp, Operand(esi, 1 * kPointerSize)); 1007236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 10084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Push the return address to get ready to return. 10094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com push(ecx); 10104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1011528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(true); 10124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 10134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1014e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 1016236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Restore current context from top and clear it in debug mode. 101783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 1018528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 1019528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(esi, Operand::StaticVariable(context_address)); 1020528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 102165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef DEBUG 102265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org mov(Operand::StaticVariable(context_address), Immediate(0)); 102365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 1024236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1025236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Clear the top frame. 102683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 1027ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 1028236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); 1029236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 1030236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1031236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1032528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 1033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(esp, ebp); 10344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com pop(ebp); 10354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1036528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(restore_context); 10374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 10384a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 10394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 104078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid MacroAssembler::PushTryHandler(StackHandler::Kind kind, 104104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_index) { 1042eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Adjust this code if not the case. 10434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 10444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 104504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 104604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 104704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 104804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 104904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 105004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // We will build up the handler from the bottom by pushing on the stack. 105178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // First push the frame pointer and context. 105278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (kind == StackHandler::JS_ENTRY) { 105304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The frame pointer does not point to a JS frame so we save NULL for 105404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // ebp. We expect the code throwing an exception to check ebp before 105504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // dereferencing it to restore the context. 1056eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(Immediate(0)); // NULL frame pointer. 10574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org push(Immediate(Smi::FromInt(0))); // No context. 105878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 105978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(ebp); 106078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(esi); 106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 106204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push the state and the code object. 106378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org unsigned state = 106478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::IndexField::encode(handler_index) | 106578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::KindField::encode(kind); 106604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Immediate(state)); 106764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Push(CodeObject()); 106804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 106904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Link the current handler as the next handler. 107004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 107104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Operand::StaticVariable(handler_address)); 107204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Set this new handler as the current one. 107304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(Operand::StaticVariable(handler_address), esp); 107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 107713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::PopTryHandler() { 10784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 107904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 108004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(Operand::StaticVariable(handler_address)); 1081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 108213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 108313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 108413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 108504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid MacroAssembler::JumpToHandlerEntry() { 108604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Compute the handler entry address and jump to it. The handler table is 108704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // a fixed array of (smi-tagged) code offsets. 108804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // eax = exception, edi = code object, edx = state. 108904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(ebx, FieldOperand(edi, Code::kHandlerTableOffset)); 109004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org shr(edx, StackHandler::kKindWidth); 109104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org mov(edx, FieldOperand(ebx, edx, times_4, FixedArray::kHeaderSize)); 109204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org SmiUntag(edx); 109304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); 109404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org jmp(edi); 109504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org} 109604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 109704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 109849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgvoid MacroAssembler::Throw(Register value) { 109949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Adjust this code if not the case. 11004acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 11014acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 110204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 110304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 110404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 110504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 110604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 110704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The exception is expected in eax. 110849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (!value.is(eax)) { 110949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org mov(eax, value); 111049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 111104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Drop the stack pointer to the top of the top handler. 111204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 111349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org mov(esp, Operand::StaticVariable(handler_address)); 111404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the next handler. 111549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pop(Operand::StaticVariable(handler_address)); 111604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 111704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in edi. 111804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edi); // Code object. 111904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edx); // Index and state. 112004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 112104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the context and frame pointer. 11224acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(esi); // Context. 11234acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(ebp); // Frame pointer. 112449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 11254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // If the handler is a JS frame, restore the context to the frame. 112604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either 112704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // ebp or esi. 112883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label skip; 112904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org test(esi, esi); 113004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(zero, &skip, Label::kNear); 11314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 113249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org bind(&skip); 113349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 113404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 113549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 113649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 113749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 113865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.orgvoid MacroAssembler::ThrowUncatchable(Register value) { 113949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Adjust this code if not the case. 11404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); 11414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 114204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 114304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 114404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 114504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 114649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 1147c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // The exception is expected in eax. 114865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value.is(eax)) { 1149c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(eax, value); 115049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 1151c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Drop the stack pointer to the top of the top stack handler. 1152c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 1153c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(esp, Operand::StaticVariable(handler_address)); 1154c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1155c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Unwind the handlers until the top ENTRY handler is found. 1156c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Label fetch_next, check_kind; 1157c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org jmp(&check_kind, Label::kNear); 1158c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&fetch_next); 1159c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org mov(esp, Operand(esp, StackHandlerConstants::kNextOffset)); 1160c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1161c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&check_kind); 116278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org STATIC_ASSERT(StackHandler::JS_ENTRY == 0); 116304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org test(Operand(esp, StackHandlerConstants::kStateOffset), 116404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Immediate(StackHandler::KindField::kMask)); 116504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(not_zero, &fetch_next); 1166c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1167c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Set the top handler address to next handler past the top ENTRY handler. 1168c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(Operand::StaticVariable(handler_address)); 116949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 117004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in edi. 117104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edi); // Code object. 117204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(edx); // Index and state. 117304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 117404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Clear the context pointer and frame pointer (0 was saved in the handler). 1175c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(esi); 117649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pop(ebp); 117749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 117804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 117949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 118049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 118149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 11825a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 1183e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch1, 1184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch2, 1185e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org Label* miss) { 11865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Label same_contexts; 11875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1188e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!holder_reg.is(scratch1)); 1189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!holder_reg.is(scratch2)); 1190e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch1.is(scratch2)); 119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11925a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Load current lexical context from the stack frame. 1193e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, Operand(ebp, StandardFrameConstants::kContextOffset)); 11945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 11955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // When generating debug code, make sure the lexical context is set. 1196badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1197e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, Immediate(0)); 1198594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 120046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context of the current context. 120146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org int offset = 120246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 1203e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, offset)); 1204e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, GlobalObject::kNativeContextOffset)); 12055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 120646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 1207badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 120846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map. 1209e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(FieldOperand(scratch1, HeapObject::kMapOffset), 1210e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->native_context_map()); 1211594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 12125a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 12135a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12145a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Check if both contexts are the same. 1215e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 12167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(equal, &same_contexts); 12175a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12185a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Compare security tokens, save holder_reg on the stack so we can use it 12195a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // as a temporary register. 12205a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // 122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that the security token in the calling global object is 122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // compatible with the security token in the receiving global 122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // object. 1224e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch2, 122546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 12265a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 122746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 1228badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1229e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch2, isolate()->factory()->null_value()); 1230594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 12315a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 123246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map(), 1233e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(FieldOperand(scratch2, HeapObject::kMapOffset), 1234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()->factory()->native_context_map()); 1235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 12365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 12375a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12385a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org int token_offset = Context::kHeaderSize + 12395a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Context::SECURITY_TOKEN_INDEX * kPointerSize; 1240e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mov(scratch1, FieldOperand(scratch1, token_offset)); 1241e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org cmp(scratch1, FieldOperand(scratch2, token_offset)); 12427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, miss); 12435a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 12445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org bind(&same_contexts); 124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1248ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// Compute the hash code from the untagged key. This must be kept in sync with 1249dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in 1250ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// code-stub-hydrogen.cc 1251f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// 1252f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Note: r0 will contain hash code 1253f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 1254f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Xor original key with a seed. 1255874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (serializer_enabled()) { 1256f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExternalReference roots_array_start = 1257f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ExternalReference::roots_array_start(isolate()); 1258f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, Immediate(Heap::kHashSeedRootIndex)); 1259f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, 1260f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Operand::StaticArray(scratch, times_pointer_size, roots_array_start)); 1261f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiUntag(scratch); 1262f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1263f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } else { 1264f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com int32_t seed = isolate()->heap()->HashSeed(); 1265f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, Immediate(seed)); 1266f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 1267f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1268f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = ~hash + (hash << 15); 1269f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1270f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com not_(r0); 1271f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shl(scratch, 15); 1272f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com add(r0, scratch); 1273f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 12); 1274f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1275f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 12); 1276f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1277f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash + (hash << 2); 1278f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com lea(r0, Operand(r0, r0, times_4, 0)); 1279f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 4); 1280f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1281f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 4); 1282f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1283f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash * 2057; 1284f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com imul(r0, r0, 2057); 1285f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 16); 1286f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(scratch, r0); 1287f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shr(scratch, 16); 1288f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xor_(r0, scratch); 1289f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 1290f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1291f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1292f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 12936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 12946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 12956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 12966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 12976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 12986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 12996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result) { 13006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Register use: 13016db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // elements - holds the slow-case elements of the receiver and is unchanged. 13036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13046db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // key - holds the smi key on entry and is unchanged. 13056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scratch registers: 13076db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13086db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r0 - holds the untagged key on entry and holds the hash once computed. 13096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13106db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r1 - used to hold the capacity mask of the dictionary 13116db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r2 - used for the index into the dictionary. 13136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 13146db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // result - holds the result on exit if the load succeeds and we fall through. 13156db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Label done; 13176db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1318f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com GetNumberHash(r0, r1); 13196db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13206db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute capacity mask. 1321f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset)); 13226db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org shr(r1, kSmiTagSize); // convert smi to int 13236db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org dec(r1); 13246db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13256db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Generate an unrolled loop that performs a few probes before giving up. 1326ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org for (int i = 0; i < kNumberDictionaryProbes; i++) { 13276db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Use r2 for index calculations and keep the hash intact in r0. 13286db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org mov(r2, r0); 13296db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute the masked index: (hash + i + i * i) & mask. 13306db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (i > 0) { 1331f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com add(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 13326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(r2, r1); 13346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scale the index by multiplying by the entry size. 1336e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SeededNumberDictionary::kEntrySize == 3); 13376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 13386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check if the key matches. 13406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org cmp(key, FieldOperand(elements, 13416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org r2, 13426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org times_pointer_size, 1343f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset)); 1344ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (i != (kNumberDictionaryProbes - 1)) { 13456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(equal, &done); 13466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } else { 13476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_equal, miss); 13486db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 13496db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 13506db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13516db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org bind(&done); 13526db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check that the value is a normal propety. 13536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kDetailsOffset = 1354f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 1355e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(NORMAL, 0); 13566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 135783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); 13586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_zero, miss); 13596db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13606db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Get the value at the masked, scaled index. 13616db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kValueOffset = 1362f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + kPointerSize; 13636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 13646db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 13656db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13666db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1367a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid MacroAssembler::LoadAllocationTopHelper(Register result, 1368a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Register scratch, 1369a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags) { 13702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 13712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 137218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 137318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Just return if allocation top is already known. 1374a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & RESULT_CONTAINS_TOP) != 0) { 137518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // No use of scratch if allocation top is provided. 1376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(scratch.is(no_reg)); 1377a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG 1378a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Assert that result actually contains top on entry. 13792bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org cmp(result, Operand::StaticVariable(allocation_top)); 1380594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kUnexpectedAllocationTop); 1381a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 138218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 138318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 138418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 138518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Move address of new object to result. Use scratch register if available. 138618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (scratch.is(no_reg)) { 13872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(result, Operand::StaticVariable(allocation_top)); 138818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 13892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(scratch, Immediate(allocation_top)); 139018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(result, Operand(scratch, 0)); 139118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 139218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 139318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 139418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 139518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 13962bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 13972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 1398badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1399ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org test(result_end, Immediate(kObjectAlignmentMask)); 1400594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kUnalignedAllocationInNewSpace); 1401ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 1402ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 14032bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 14042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 140518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 140618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update new top. Use scratch if available. 140718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (scratch.is(no_reg)) { 14082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org mov(Operand::StaticVariable(allocation_top), result_end); 140918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 141018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(Operand(scratch, 0), result_end); 141118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 141218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 141318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1414a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 14152bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid MacroAssembler::Allocate(int object_size, 14162bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 14172bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 14182bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 14192bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 14202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 1421e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1422e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 1423303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1424badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1425303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1426303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1427303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result_end.is_valid()) { 1428303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1429303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1430303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1431303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1432303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1433303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1434303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1435303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1436303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1437e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(result_end)); 143818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 143918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1440beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 144118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1442f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org ExternalReference allocation_limit = 1443f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1444f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org 14454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 1446f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 14474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1448e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 1449e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 14504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label aligned; 14514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 14524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org j(zero, &aligned, Label::kNear); 1453f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1454f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1455f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org j(above_equal, gc_required); 1456f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org } 14574cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org mov(Operand(result, 0), 14584cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 14594cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org add(result, Immediate(kDoubleSize / 2)); 14604cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bind(&aligned); 14614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 14624cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 14632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // Calculate new top and bail out if space is exhausted. 1464f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org Register top_reg = result_end.is_valid() ? result_end : result; 1465d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (!top_reg.is(result)) { 1466d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com mov(top_reg, result); 1467a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(top_reg, Immediate(object_size)); 14697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(carry, gc_required); 14702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org cmp(top_reg, Operand::StaticVariable(allocation_limit)); 14717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(above, gc_required); 14720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 14730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 14742bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(top_reg, scratch, flags); 1475c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1476c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Tag result if requested. 14774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bool tag_result = (flags & TAG_OBJECT) != 0; 1478c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (top_reg.is(result)) { 14794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (tag_result) { 1480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(result, Immediate(object_size - kHeapObjectTag)); 1481c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 1482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(result, Immediate(object_size)); 1483c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 14844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else if (tag_result) { 1485e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kHeapObjectTag == 1); 14864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org inc(result); 1487c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 148818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 148918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 149018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1491f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(int header_size, 1492f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 1493f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 1494f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org RegisterValueType element_count_type, 1495f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1496f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1497f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1498f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1499f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 1500e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((flags & SIZE_IN_WORDS) == 0); 1501303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1502badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1503303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1504303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1505303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1506303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1507303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1508303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1509303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Register element_count is not modified by the function. 1510303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1511303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1512303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1513303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1514e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(result_end)); 151518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 151618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1517beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 151818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1519f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org ExternalReference allocation_limit = 1520f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1521f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org 15224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 1523f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 15244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1525e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 1526e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 15274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label aligned; 15284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 15294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org j(zero, &aligned, Label::kNear); 1530f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1531f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1532f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org j(above_equal, gc_required); 1533f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org } 15344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org mov(Operand(result, 0), 15354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 15364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org add(result, Immediate(kDoubleSize / 2)); 15374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bind(&aligned); 15384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 15394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 1540f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Calculate new top and bail out if space is exhausted. 1541d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // We assume that element_count*element_size + header_size does not 1542d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // overflow. 15434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (element_count_type == REGISTER_VALUE_IS_SMI) { 15444cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_2 - 1) == times_1); 15454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_4 - 1) == times_2); 15464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org STATIC_ASSERT(static_cast<ScaleFactor>(times_8 - 1) == times_4); 1547e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(element_size >= times_2); 1548e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kSmiTagSize == 1); 15494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org element_size = static_cast<ScaleFactor>(element_size - 1); 15504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else { 1551e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(element_count_type == REGISTER_VALUE_IS_INT32); 15524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 1553d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com lea(result_end, Operand(element_count, element_size, header_size)); 1554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(result_end, result); 1555d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 1556f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp(result_end, Operand::StaticVariable(allocation_limit)); 155718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 155818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1559a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 1560e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kHeapObjectTag == 1); 15614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org inc(result); 1562a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 15630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 15640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 15652bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 156618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 156718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 156818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1569f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(Register object_size, 1570f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1571f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1572f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1573f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1574f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 1575e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1576303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (!FLAG_inline_new) { 1577badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1578303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 1579303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result, Immediate(0x7091)); 1580303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(result_end, Immediate(0x7191)); 1581303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 1582303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(scratch, Immediate(0x7291)); 1583303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1584303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // object_size is left unchanged by this function. 1585303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1586303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 1587303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 1588303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1589e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(result_end)); 159018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 159118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 1592beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 159318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1594f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org ExternalReference allocation_limit = 1595f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 1596f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org 159794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Align the next allocation. Storing the filler map without checking top is 1598f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 159994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 1600e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 1601e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 160294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Label aligned; 160394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org test(result, Immediate(kDoubleAlignmentMask)); 160494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org j(zero, &aligned, Label::kNear); 1605f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 1606f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org cmp(result, Operand::StaticVariable(allocation_limit)); 1607f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org j(above_equal, gc_required); 1608f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org } 160994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org mov(Operand(result, 0), 161094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Immediate(isolate()->factory()->one_pointer_filler_map())); 161194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org add(result, Immediate(kDoubleSize / 2)); 161294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org bind(&aligned); 161394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 161494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1615f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Calculate new top and bail out if space is exhausted. 161618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (!object_size.is(result_end)) { 161718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(result_end, object_size); 161818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 1619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(result_end, result); 16207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(carry, gc_required); 1621f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp(result_end, Operand::StaticVariable(allocation_limit)); 16227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(above, gc_required); 162318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1624a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Tag result if requested. 1625a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 1626e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kHeapObjectTag == 1); 162794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org inc(result); 1628a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 16290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 16300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Update allocation top. 16312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 163218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 163318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 163418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 163518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UndoAllocationInNewSpace(Register object) { 163618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference new_space_allocation_top = 1637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 163818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 163918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Make sure the object has no tag before resetting top. 1640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(object, Immediate(~kHeapObjectTagMask)); 164118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef DEBUG 164218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org cmp(object, Operand::StaticVariable(new_space_allocation_top)); 1643594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kUndoAllocationOfNonAllocatedMemory); 164418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 164518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mov(Operand::StaticVariable(new_space_allocation_top), object); 164618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 164718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 164818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 16493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgvoid MacroAssembler::AllocateHeapNumber(Register result, 16503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch1, 16513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch2, 165258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org Label* gc_required, 165358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org MutableMode mode) { 16543811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate heap number in new space. 16552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, 16562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 16573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 165858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org Handle<Map> map = mode == MUTABLE 165958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org ? isolate()->factory()->mutable_heap_number_map() 166058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org : isolate()->factory()->heap_number_map(); 166158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org 16623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Set the map. 166358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), Immediate(map)); 16643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 16653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 16663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1667ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::AllocateTwoByteString(Register result, 1668ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register length, 1669ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1670ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1671ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch3, 1672ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1673ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Calculate the number of bytes needed for the characters in the string while 1674ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // observing object alignment. 1675e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 1676e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kShortSize == 2); 167713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // scratch1 = length * 2 + kObjectAlignmentMask. 167813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); 1679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, Immediate(~kObjectAlignmentMask)); 1680ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1681ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate two byte string in new space. 1682f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqTwoByteString::kHeaderSize, 1683f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 1684f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 1685f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_INT32, 1686f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 1687f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 1688f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 1689f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 1690f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 1691ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1692ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map, length and hash field. 1693ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 16947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->string_map())); 1695ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(scratch1, length); 1696ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org SmiTag(scratch1); 1697ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(FieldOperand(result, String::kLengthOffset), scratch1); 1698ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 1699ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Immediate(String::kEmptyHashField)); 1700ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1701ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1702ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 17032c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgvoid MacroAssembler::AllocateOneByteString(Register result, Register length, 17042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, Register scratch2, 17052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch3, 17062c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label* gc_required) { 1707ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Calculate the number of bytes needed for the characters in the string while 1708ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // observing object alignment. 1709e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); 1710ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(scratch1, length); 1711e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kCharSize == 1); 1712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(scratch1, Immediate(kObjectAlignmentMask)); 1713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, Immediate(~kObjectAlignmentMask)); 1714ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 17152c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Allocate one-byte string in new space. 1716f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqOneByteString::kHeaderSize, 1717f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 1718f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 1719f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org REGISTER_VALUE_IS_INT32, 1720f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 1721f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 1722f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 1723f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 1724f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 1725ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1726ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map, length and hash field. 1727ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17282c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Immediate(isolate()->factory()->one_byte_string_map())); 1729ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(scratch1, length); 1730ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org SmiTag(scratch1); 1731ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mov(FieldOperand(result, String::kLengthOffset), scratch1); 1732ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 1733ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Immediate(String::kEmptyHashField)); 1734ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1735ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1736ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 17372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgvoid MacroAssembler::AllocateOneByteString(Register result, int length, 17382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, Register scratch2, 17392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label* gc_required) { 1740e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(length > 0); 17413cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Allocate one-byte string in new space. 17432bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, 17442bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org gc_required, TAG_OBJECT); 17453cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17463cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org // Set the map, length and hash field. 17473cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Immediate(isolate()->factory()->one_byte_string_map())); 17493cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, String::kLengthOffset), 17503cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Immediate(Smi::FromInt(length))); 17513cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org mov(FieldOperand(result, String::kHashFieldOffset), 17523cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org Immediate(String::kEmptyHashField)); 17533cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org} 17543cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17553cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 17561805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteConsString(Register result, 1757ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch1, 1758ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Register scratch2, 1759ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Label* gc_required) { 1760ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Allocate heap number in new space. 17612bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 17622bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 1763ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1764ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map. The other fields are left uninitialized. 1765ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(isolate()->factory()->cons_string_map())); 1767ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1768ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1769ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 17702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgvoid MacroAssembler::AllocateOneByteConsString(Register result, 17712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, 17722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, 17732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label* gc_required) { 177457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 177557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 177657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 177757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 177857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 17797e6132b924829c353864933f29124419916db550machenbach@chromium.org TAG_OBJECT); 1780ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1781ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Set the map. The other fields are left uninitialized. 1782ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 17832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Immediate(isolate()->factory()->cons_one_byte_string_map())); 1784ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 1785ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1786c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 17871805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 178880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch1, 178980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Register scratch2, 179080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Label* gc_required) { 179180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Allocate heap number in new space. 17922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 17932bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 179480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 179580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Set the map. The other fields are left uninitialized. 179680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 179780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Immediate(isolate()->factory()->sliced_string_map())); 179880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 179980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 180080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 18012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgvoid MacroAssembler::AllocateOneByteSlicedString(Register result, 18022c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, 18032c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, 18042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label* gc_required) { 180580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Allocate heap number in new space. 18062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 18072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 180880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 180980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Set the map. The other fields are left uninitialized. 181080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org mov(FieldOperand(result, HeapObject::kMapOffset), 18112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Immediate(isolate()->factory()->sliced_one_byte_string_map())); 181280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 181380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 181480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 1815c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Copy memory, byte-by-byte, from source to destination. Not optimized for 1816c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// long or aligned copies. The contents of scratch and length are destroyed. 1817c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Source and destination are incremented by length. 1818c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Many variants of movsb, loop unrolling, word moves, and indexed operands 1819c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// have been tried here already, and this is fastest. 1820c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// A simpler loop is faster on small copies, but 30% slower on large ones. 1821c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// The cld() instruction must have been emitted, to set the direction flag(), 1822c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// before calling this function. 1823c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid MacroAssembler::CopyBytes(Register source, 1824c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register destination, 1825c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register length, 1826c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register scratch) { 18270cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label short_loop, len4, len8, len12, done, short_string; 1828e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(source.is(esi)); 1829e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination.is(edi)); 1830e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(length.is(ecx)); 18310cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(4)); 18320cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below, &short_string, Label::kNear); 1833c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1834c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Because source is 4-byte aligned in our uses of this function, 1835c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // we keep source aligned for the rep_movs call by copying the odd bytes 1836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // at the end of the ranges. 1837c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(scratch, Operand(source, length, times_1, -4)); 1838c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(Operand(destination, length, times_1, -4), scratch); 18390cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 18400cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(8)); 18410cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len4, Label::kNear); 18420cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(12)); 18430cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len8, Label::kNear); 18440cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmp(length, Immediate(16)); 18450cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len12, Label::kNear); 18460cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 1847c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov(scratch, ecx); 1848c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org shr(ecx, 2); 1849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org rep_movs(); 1850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(0x3)); 1851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(destination, scratch); 18520cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 18530cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 18540cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len12); 18550cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(scratch, Operand(source, 8)); 18560cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(Operand(destination, 8), scratch); 18570cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len8); 18580cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(scratch, Operand(source, 4)); 18590cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(Operand(destination, 4), scratch); 18600cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len4); 18610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(scratch, Operand(source, 0)); 18620cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org mov(Operand(destination, 0), scratch); 18630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org add(destination, length); 18640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 1865c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1866c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&short_string); 1867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(length, length); 18680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(zero, &done, Label::kNear); 1869c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1870c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&short_loop); 1871c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov_b(scratch, Operand(source, 0)); 1872c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org mov_b(Operand(destination, 0), scratch); 1873c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inc(source); 1874c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inc(destination); 1875c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org dec(length); 1876c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org j(not_zero, &short_loop); 1877c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1878c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bind(&done); 187921b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org} 188021b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 1881ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 1882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InitializeFieldsWithFiller(Register start_offset, 1883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 1884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler) { 1885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 1886c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&entry); 1887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&loop); 1888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(Operand(start_offset, 0), filler); 1889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(start_offset, Immediate(kPointerSize)); 1890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&entry); 1891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(start_offset, end_offset); 1892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(less, &loop); 1893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1896394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MacroAssembler::BooleanBitTest(Register object, 1897394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int field_offset, 1898394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int bit_index) { 1899394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bit_index += kSmiTagSize + kSmiShiftSize; 190021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(base::bits::IsPowerOfTwo32(kBitsPerByte)); 1901394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_index = bit_index / kBitsPerByte; 1902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_bit_index = bit_index & (kBitsPerByte - 1); 1903394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com test_b(FieldOperand(object, field_offset + byte_index), 1904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static_cast<byte>(1 << byte_bit_index)); 1905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1907394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1908394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::NegativeZeroTest(Register result, 191043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op, 191143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label* then_label) { 191243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label ok; 1913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(result, result); 19147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &ok); 1915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(op, op); 19167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(sign, then_label); 191743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&ok); 191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 191943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 192043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::NegativeZeroTest(Register result, 192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op1, 192343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register op2, 192443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Register scratch, 192543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label* then_label) { 192643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label ok; 1927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(result, result); 19287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_zero, &ok); 1929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, op1); 1930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(scratch, op2); 19317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(sign, then_label); 193243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&ok); 193343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 193443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19367c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgvoid MacroAssembler::TryGetFunctionPrototype(Register function, 19377c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Register result, 19387c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Register scratch, 1939394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 1940394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function) { 19417c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Label non_instance; 19427c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (miss_on_bound_function) { 19437c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org // Check that the receiver isn't a smi. 19447c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org JumpIfSmi(function, miss); 19457c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19467c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org // Check that the function really is a function. 19477c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CmpObjectType(function, JS_FUNCTION_TYPE, result); 19487c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org j(not_equal, miss); 19497c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 1950394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If a bound function, go to miss label. 1951394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com mov(scratch, 1952394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 1953394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com BooleanBitTest(scratch, SharedFunctionInfo::kCompilerHintsOffset, 1954394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SharedFunctionInfo::kBoundFunction); 1955394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com j(not_zero, miss); 1956394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 19577c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org // Make sure that the function has an instance prototype. 19587c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset)); 19597c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); 19607c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org j(not_zero, &non_instance); 19617c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 19627c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19637c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Get the prototype or initial map from the function. 19647c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, 19657c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 19667c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19677c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // If the prototype or initial map is the hole, don't return it and 19687c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // simply miss the cache instead. This will allow us to allocate a 19697c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // prototype object on-demand in the runtime system. 1970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(result, Immediate(isolate()->factory()->the_hole_value())); 19717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(equal, miss); 19727c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19737c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // If the function does not have an initial map, we're done. 19747c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org Label done; 19757be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org CmpObjectType(result, MAP_TYPE, scratch); 19767c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org j(not_equal, &done); 19777c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19787c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Get the prototype from the initial map. 19797c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org mov(result, FieldOperand(result, Map::kPrototypeOffset)); 19807c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19817c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (miss_on_bound_function) { 19827c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org jmp(&done); 19837c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org 19847c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org // Non-instance prototype: Fetch prototype from constructor field 19857c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org // in initial map. 19867c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org bind(&non_instance); 19877c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org mov(result, FieldOperand(result, Map::kConstructorOffset)); 19887c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 19897c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19907c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // All done. 19917c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org bind(&done); 19927c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org} 19937c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 19947c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org 1995471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 1996e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs. 1997f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 199843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 199943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 200043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2001ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::TailCallStub(CodeStub* stub) { 2002f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org jmp(stub->GetCode(), RelocInfo::CODE_TARGET); 2003ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 2004ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2005ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 200643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::StubReturn(int argc) { 2007e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(argc >= 1 && generating_stub()); 200843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ret((argc - 1) * kPointerSize); 200943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 201043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 201143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 20138a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org return has_frame_ || !stub->SometimesSetsUpAFrame(); 2014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2016c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2017d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 2018d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The assert checks that the constants for the maximum number of digits 2019d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // for an array index cached in the hash field and the number of bits 2020d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // reserved for it does not conflict. 2021e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) < 2022d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org (1 << String::kArrayIndexValueBits)); 2023d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org if (!index.is(hash)) { 2024d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(index, hash); 2025d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 2026d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DecodeFieldToSmi<String::ArrayIndexValueBits>(index); 2027d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2028d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2029d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2030ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 2031fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int num_arguments, 2032fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles) { 203331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // If the expected number of arguments of the runtime function is 203431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // constant, we check that the actual number of arguments match the 203531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // expectation. 203629699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org CHECK(f->nargs < 0 || f->nargs == num_arguments); 203743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2038b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // TODO(1236192): Most runtime routines don't need the number of 2039b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // arguments passed in because it is constant. At some point we 2040b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // should remove this need and make the runtime routine entry code 2041b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // smarter. 2042a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(eax, Immediate(num_arguments)); 2043ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(ebx, Immediate(ExternalReference(f, isolate()))); 20443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org CEntryStub ces(isolate(), 1, save_doubles); 2045b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallStub(&ces); 204643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 204743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 204843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2049e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.orgvoid MacroAssembler::CallExternalReference(ExternalReference ref, 2050e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int num_arguments) { 2051e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org mov(eax, Immediate(num_arguments)); 2052e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org mov(ebx, Immediate(ref)); 2053e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 2054f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub stub(isolate(), 1); 2055e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org CallStub(&stub); 2056e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 2057e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 2058e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 2059ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 2060ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 2061ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 206231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // TODO(1236192): Most runtime routines don't need the number of 206331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // arguments passed in because it is constant. At some point we 206431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // should remove this need and make the runtime routine entry code 206531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // smarter. 2066a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Move(eax, Immediate(num_arguments)); 2067ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org JumpToExternalReference(ext); 2068ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2069ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2070ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2071ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 2072ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 2073ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 2074ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TailCallExternalReference(ExternalReference(fid, isolate()), 2075ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org num_arguments, 2076ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result_size); 207743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 207843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 207943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2080662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgOperand ApiParameterOperand(int index) { 2081662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org return Operand(esp, index * kPointerSize); 2082c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 2083c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2084c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2085662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PrepareCallApiFunction(int argc) { 2086662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org EnterApiExitFrame(argc); 2087662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (emit_debug_code()) { 2088e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org mov(esi, Immediate(bit_cast<int32_t>(kZapValue))); 2089303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 20904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 20914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 20922d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 2093528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::CallApiFunctionAndReturn( 2094e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Register function_address, 2095a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org ExternalReference thunk_ref, 2096528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand thunk_last_arg, 2097528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org int stack_space, 2098528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand return_value_operand, 2099528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand* context_restore_operand) { 2100303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference next_address = 210109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_next_address(isolate()); 2102303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference limit_address = 210309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_limit_address(isolate()); 2104303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference level_address = 210509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_level_address(isolate()); 21062d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 2107e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(edx.is(function_address)); 2108303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Allocate HandleScope in callee-save registers. 2109303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(ebx, Operand::StaticVariable(next_address)); 2110303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(edi, Operand::StaticVariable(limit_address)); 2111303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org add(Operand::StaticVariable(level_address), Immediate(1)); 2112303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 211383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 211483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 211583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 2116ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1, eax); 2117ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org mov(Operand(esp, 0), 2118ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2119ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 212083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 212183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 212283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 2123b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2124b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label profiler_disabled; 2125b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label end_profiler_check; 2126a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org mov(eax, Immediate(ExternalReference::is_profiling_address(isolate()))); 2127b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org cmpb(Operand(eax, 0), 0); 2128b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org j(zero, &profiler_disabled); 2129b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2130b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Additional parameter is the address of the actual getter function. 2131e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org mov(thunk_last_arg, function_address); 2132b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Call the api function. 2133a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org mov(eax, Immediate(thunk_ref)); 2134a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org call(eax); 2135b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org jmp(&end_profiler_check); 2136b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2137b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&profiler_disabled); 2138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Call the api function. 2139e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org call(function_address); 2140b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&end_profiler_check); 21412d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org 214283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 214383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 214483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 2145ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1, eax); 2146ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org mov(Operand(esp, 0), 2147ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2148ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); 214983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 215083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 215183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 2152303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label prologue; 2153bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Load the value from ReturnValue 2154528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(eax, return_value_operand); 2155bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org 2156303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label promote_scheduled_exception; 2157528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label exception_handled; 2158303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label delete_allocated_handles; 2159303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label leave_exit_frame; 2160303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 2161303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&prologue); 2162303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // No more valid handles (the result handle was the last one). Restore 2163303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // previous handle scope. 2164303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(Operand::StaticVariable(next_address), ebx); 2165303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org sub(Operand::StaticVariable(level_address), Immediate(1)); 2166594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(above_equal, kInvalidHandleScopeLevel); 2167303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmp(edi, Operand::StaticVariable(limit_address)); 21687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, &delete_allocated_handles); 2169303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&leave_exit_frame); 2170303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 2171303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Check if the function scheduled an exception. 2172303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference scheduled_exception_address = 2173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::scheduled_exception_address(isolate()); 2174303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmp(Operand::StaticVariable(scheduled_exception_address), 2175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Immediate(isolate()->factory()->the_hole_value())); 21767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(not_equal, &promote_scheduled_exception); 2177528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&exception_handled); 217867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 217967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#if ENABLE_EXTRA_CHECKS 218067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org // Check if the function returned a valid JavaScript value. 218167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Label ok; 218267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register return_value = eax; 218367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register map = ecx; 218467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 218567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org JumpIfSmi(return_value, &ok, Label::kNear); 218667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org mov(map, FieldOperand(return_value, HeapObject::kMapOffset)); 218767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 218867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_NONSTRING_TYPE); 218967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(below, &ok, Label::kNear); 219067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 219167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 219267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(above_equal, &ok, Label::kNear); 219367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 219467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(map, isolate()->factory()->heap_number_map()); 219567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 219667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 219767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->undefined_value()); 219867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 219967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 220067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->true_value()); 220167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 220267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 220367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->false_value()); 220467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 220567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 220667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org cmp(return_value, isolate()->factory()->null_value()); 220767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 220867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 2209594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kAPICallReturnedInvalidObject); 221067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 221167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org bind(&ok); 221267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#endif 221367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 2214528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool restore_context = context_restore_operand != NULL; 2215528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 2216528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(esi, *context_restore_operand); 2217528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 2218528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveApiExitFrame(!restore_context); 22194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com ret(stack_space * kPointerSize); 2220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2221b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org bind(&promote_scheduled_exception); 2222528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org { 2223528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FrameScope frame(this, StackFrame::INTERNAL); 222447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kPromoteScheduledException, 0); 2225528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 2226528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&exception_handled); 2227b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org 2228303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // HandleScope limit has changed. Delete allocated extensions. 2229ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference delete_extensions = 2230ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::delete_handle_scope_extensions(isolate()); 2231303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&delete_allocated_handles); 2232303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(Operand::StaticVariable(limit_address), edi); 2233303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(edi, eax); 223432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org mov(Operand(esp, 0), 223532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Immediate(ExternalReference::isolate_address(isolate()))); 2236ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org mov(eax, Immediate(delete_extensions)); 2237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com call(eax); 2238303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org mov(eax, edi); 2239303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(&leave_exit_frame); 2240c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 2241c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2242c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 2243ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 224443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the entry point and jump to the C entry runtime stub. 22453bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(ebx, Immediate(ext)); 2246f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), 1); 2247f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 224843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 224943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 225043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 225143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 225243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 225343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> code_constant, 225443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const Operand& code_operand, 225583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 22562efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 2257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 225883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance done_near, 2259e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 226043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool definitely_matches = false; 22612efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = false; 226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label invoke; 226343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expected.is_immediate()) { 2264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(actual.is_immediate()); 226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (expected.immediate() == actual.immediate()) { 226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen definitely_matches = true; 226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 226843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(eax, actual.immediate()); 2269b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; 2270b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (expected.immediate() == sentinel) { 2271b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Don't worry about adapting arguments for builtins that 2272b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // don't want that done. Skip adaption code by making it look 2273b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // like we have a match between expected and actual number of 2274b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // arguments. 2275b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org definitely_matches = true; 2276b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 22772efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = true; 2278b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org mov(ebx, expected.immediate()); 2279b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 228143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 228243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (actual.is_immediate()) { 228343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expected is in register, actual is immediate. This is the 228443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // case when we invoke function values without going through the 228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IC mechanism. 228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cmp(expected.reg(), actual.immediate()); 228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen j(equal, &invoke); 2288e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expected.reg().is(ebx)); 228943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(eax, actual.immediate()); 229043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (!expected.reg().is(actual.reg())) { 229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Both expected and actual are in (different) registers. This 229243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is the case when we invoke functions using call and apply. 2293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(expected.reg(), actual.reg()); 229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen j(equal, &invoke); 2295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(actual.reg().is(eax)); 2296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expected.reg().is(ebx)); 229743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 229843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 229943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 230043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!definitely_matches) { 230143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> adaptor = 23027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org isolate()->builtins()->ArgumentsAdaptorTrampoline(); 230343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!code_constant.is_null()) { 23043bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org mov(edx, Immediate(code_constant)); 2305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 230643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (!code_operand.is_reg(edx)) { 230743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(edx, code_operand); 230843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 230943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 231043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (flag == CALL_FUNCTION) { 2311fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); 2312236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org call(adaptor, RelocInfo::CODE_TARGET); 2313fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org call_wrapper.AfterCall(); 23142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!*definitely_mismatches) { 23152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(done, done_near); 23162efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 231743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 2318236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org jmp(adaptor, RelocInfo::CODE_TARGET); 231943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 232043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&invoke); 232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 232243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 232343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeCode(const Operand& code, 232643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& expected, 232743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2329e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 2330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2331e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag == JUMP_FUNCTION || has_frame()); 2332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 233383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 23342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 2335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokePrologue(expected, actual, Handle<Code>::null(), code, 23362efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org &done, &definitely_mismatches, flag, Label::kNear, 2337e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org call_wrapper); 23382efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 23392efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 23402efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code)); 23412efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call(code); 23422efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 23432efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 2344e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag == JUMP_FUNCTION); 23452efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(code); 23462efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 23472efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 234843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 234943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 235043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::InvokeFunction(Register fun, 235343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const ParameterCount& actual, 2354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2355e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 2356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2357e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag == JUMP_FUNCTION || has_frame()); 2358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2359e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(fun.is(edi)); 236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 236143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 236243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 236330ce411529579186181838984710b0b0980857aaricow@chromium.org SmiUntag(ebx); 236443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParameterCount expected(ebx); 2366145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2367e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org expected, actual, flag, call_wrapper); 236843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 236943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 237043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23718a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Register fun, 237232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 23735c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 2374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2375e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 2376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 2377e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag == JUMP_FUNCTION || has_frame()); 2378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2379e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(fun.is(edi)); 23805c838251403b0be9a882540f1922577abba4c872ager@chromium.org mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2383e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org expected, actual, flag, call_wrapper); 23845c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 23855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23878a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 23888a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& expected, 23898a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& actual, 23908a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org InvokeFlag flag, 2391e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 23928a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org LoadHeapObject(edi, function); 2393e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InvokeFunction(edi, expected, actual, flag, call_wrapper); 23948a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org} 23958a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 23968a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 2397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 2398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InvokeFlag flag, 2399fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper) { 2400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a builtin without a valid frame. 2401e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag == JUMP_FUNCTION || has_frame()); 240243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Rely on the assertion to check that the number of provided 240443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // arguments match the expected number of arguments. Fake a 240543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // parameter count to avoid emitting code to do the check. 240643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ParameterCount expected(0); 2407145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(edi, id); 2408145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2409e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org expected, expected, flag, call_wrapper); 241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 241143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2413145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinFunction(Register target, 2414145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com Builtins::JavaScript id) { 2415145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the JavaScript builtin function from the builtins object. 241646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 2417c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 2418145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com mov(target, FieldOperand(target, 2419145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com JSBuiltinsObject::OffsetOfFunctionWithId(id))); 2420145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com} 2421c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2423145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 2424e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!target.is(edi)); 24255c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Load the JavaScript builtin function from the builtins object. 2426145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(edi, id); 2427145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the code entry point from the function into the target register. 2428145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 242943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 243043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2432ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 2433ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org if (context_chain_length > 0) { 2434ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Move up the chain of contexts to the context containing the slot. 24356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org mov(dst, Operand(esi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2436ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int i = 1; i < context_chain_length; i++) { 24376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org mov(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2438ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 243983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 244083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Slot is in the current function context. Move it into the 244183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // destination register in case we store into it (the write barrier 244283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // cannot be allowed to destroy the context in esi). 244383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org mov(dst, esi); 244483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 244583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 24464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // We should not have found a with context by walking the context chain 24474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // (i.e., the static scope chain and runtime context chain do not agree). 24484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // A variable occurring in such a scope should have slot type LOOKUP and 24494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // not CONTEXT. 2450badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 24513cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org cmp(FieldOperand(dst, HeapObject::kMapOffset), 24523cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org isolate()->factory()->with_context_map()); 2453594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kVariableResolvedToWithContext); 2454ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 2455ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 2456ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2457ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 24581145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadTransitionedArrayMapConditional( 24591145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 24601145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 24611145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 24621145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 24631145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match) { 24641145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Load the global or builtins object from the current context. 246546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(scratch, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 246646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 24671145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24681145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Check that the function's map is the same as the expected cached map. 2469830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org mov(scratch, Operand(scratch, 2470830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); 2471830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 2472830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org size_t offset = expected_kind * kPointerSize + 2473830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 2474830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org cmp(map_in_out, FieldOperand(scratch, offset)); 24751145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org j(not_equal, no_map_match); 24761145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24771145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Use the transitioned cached map. 2478830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org offset = transitioned_kind * kPointerSize + 2479830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 2480830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org mov(map_in_out, FieldOperand(scratch, offset)); 24811145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org} 24821145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 24831145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 2484d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::LoadGlobalFunction(int index, Register function) { 2485d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Load the global or builtins object from the current context. 248646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org mov(function, 248746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 248846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 24894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org mov(function, 24904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org FieldOperand(function, GlobalObject::kNativeContextOffset)); 249146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 2492d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(function, Operand(function, Context::SlotOffset(index))); 2493d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2494d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2495d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2496d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 2497d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Register map) { 2498d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Load the initial map. The global functions all have initial maps. 2499d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2500badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 2501d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label ok, fail; 2502c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 2503d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org jmp(&ok); 2504d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org bind(&fail); 2505594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kGlobalFunctionsMustHaveInitialMap); 2506d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org bind(&ok); 2507d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 2508d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2509d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2510ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 25113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// Store the value in register src in the safepoint register stack 25123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// slot for register dst. 25133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 25143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(SafepointRegisterSlot(dst), src); 25153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Immediate src) { 25193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(SafepointRegisterSlot(dst), src); 25203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 25243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org mov(dst, SafepointRegisterSlot(src)); 25253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 25293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return Operand(esp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 25303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 25313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 25323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint MacroAssembler::SafepointRegisterStackIndex(int reg_code) { 2534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // The registers are pushed starting with the lowest encoding, 2535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // which means that lowest encodings are furthest away from 2536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the stack pointer. 2537e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg_code >= 0 && reg_code < kNumSafepointRegisters); 2538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return kNumSafepointRegisters - reg_code - 1; 2539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 254264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MacroAssembler::LoadHeapObject(Register result, 254364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<HeapObject> object) { 254479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference embedding_raw_address; 254564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 254641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 254741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org mov(result, Operand::ForCell(cell)); 254864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 254964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org mov(result, object); 255064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 255164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 255264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 255364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 2554a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) { 255579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 2556a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 255741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 255841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org cmp(reg, Operand::ForCell(cell)); 2559a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 2560a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org cmp(reg, object); 2561a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 2562a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 2563a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 2564a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 256564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MacroAssembler::PushHeapObject(Handle<HeapObject> object) { 256679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 256764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 256841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 256941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org push(Operand::ForCell(cell)); 257064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 257164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Push(object); 257264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 257364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 257464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 257564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 257643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::Ret() { 257743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ret(0); 257843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 257943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2581d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2582d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (is_uint16(bytes_dropped)) { 2583d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(bytes_dropped); 2584d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 2585d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com pop(scratch); 2586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(bytes_dropped)); 2587d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com push(scratch); 2588d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(0); 2589d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 2590d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 2591d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 2592d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 259313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::Drop(int stack_elements) { 259413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org if (stack_elements > 0) { 2595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(stack_elements * kPointerSize)); 259613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } 259713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 259813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 259913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 26004a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid MacroAssembler::Move(Register dst, Register src) { 26014a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!dst.is(src)) { 26024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org mov(dst, src); 26034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 26044a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 26054a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 26064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 2607a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid MacroAssembler::Move(Register dst, const Immediate& x) { 2608a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (x.is_zero()) { 2609a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org xor_(dst, dst); // Shorter than mov of 32-bit immediate 0. 2610486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else { 2611a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org mov(dst, x); 2612486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 2613486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org} 2614486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 2615486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 2616a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid MacroAssembler::Move(const Operand& dst, const Immediate& x) { 2617a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org mov(dst, x); 2618a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org} 2619a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 2620a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 2621fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgvoid MacroAssembler::Move(XMMRegister dst, double val) { 2622fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // TODO(titzer): recognize double constants with ExternalReferences. 2623e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org uint64_t int_val = bit_cast<uint64_t, double>(val); 2624fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (int_val == 0) { 2625fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org xorps(dst, dst); 2626fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } else { 2627fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int32_t lower = static_cast<int32_t>(int_val); 2628fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); 2629fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org push(Immediate(upper)); 2630fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org push(Immediate(lower)); 2631fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org movsd(dst, Operand(esp, 0)); 2632fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org add(esp, Immediate(kDoubleSize)); 2633fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 2634fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org} 2635fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 2636fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 263743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 263843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 263943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mov(Operand::StaticVariable(ExternalReference(counter)), Immediate(value)); 264043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 264143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 264243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 264343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 264443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 2645e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value > 0); 264643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 264743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Operand operand = Operand::StaticVariable(ExternalReference(counter)); 264843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value == 1) { 264943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inc(operand); 265043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen add(operand, Immediate(value)); 265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 265343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 265443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 265543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 2658e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value > 0); 265943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_native_code_counters && counter->Enabled()) { 266043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Operand operand = Operand::StaticVariable(ExternalReference(counter)); 266143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value == 1) { 266243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dec(operand); 266343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 266443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen sub(operand, Immediate(value)); 266543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 266643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 266743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 266843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 266943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2670b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::IncrementCounter(Condition cc, 2671b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org StatsCounter* counter, 2672b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int value) { 2673e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value > 0); 2674b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 2675b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label skip; 2676b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(NegateCondition(cc), &skip); 2677b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org pushfd(); 2678b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org IncrementCounter(counter, value); 2679b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org popfd(); 2680b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bind(&skip); 2681b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2682b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2683b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2684b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2685b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::DecrementCounter(Condition cc, 2686b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org StatsCounter* counter, 2687b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int value) { 2688e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value > 0); 2689b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 2690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label skip; 2691b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(NegateCondition(cc), &skip); 2692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org pushfd(); 2693b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DecrementCounter(counter, value); 2694b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org popfd(); 2695b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bind(&skip); 2696b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2697b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2698b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2700594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 2701594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (emit_debug_code()) Check(cc, reason); 270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27050b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MacroAssembler::AssertFastElements(Register elements) { 2706badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 27077979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Factory* factory = isolate()->factory(); 27080b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Label ok; 27090b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 27107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(factory->fixed_array_map())); 27110b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org j(equal, &ok); 27120b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 271384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org Immediate(factory->fixed_double_array_map())); 271484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org j(equal, &ok); 271584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org cmp(FieldOperand(elements, HeapObject::kMapOffset), 27167979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Immediate(factory->fixed_cow_array_map())); 27170b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org j(equal, &ok); 2718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kJSObjectWithFastElementsMapHasSlowElements); 27190b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org bind(&ok); 27200b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 27210b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org} 27220b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 27230b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 2724594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 272543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Label L; 27267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org j(cc, &L); 2727594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(reason); 272843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will not return here 272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bind(&L); 273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 273143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2733c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgvoid MacroAssembler::CheckStackAlignment() { 27345de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org int frame_alignment = base::OS::ActivationFrameAlignment(); 2735c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment_mask = frame_alignment - 1; 2736c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org if (frame_alignment > kPointerSize) { 273721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 2738c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org Label alignment_as_expected; 2739c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org test(esp, Immediate(frame_alignment_mask)); 2740c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org j(zero, &alignment_as_expected); 2741c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Abort if stack is not aligned. 2742c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int3(); 2743c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org bind(&alignment_as_expected); 2744c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 2745c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org} 2746c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2747c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2748594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Abort(BailoutReason reason) { 2749052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org#ifdef DEBUG 2750f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const char* msg = GetBailoutReason(reason); 275143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (msg != NULL) { 275243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RecordComment("Abort message: "); 275343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RecordComment(msg); 275443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 27551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 27561e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (FLAG_trap_on_abort) { 27571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int3(); 27581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return; 27591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 2761ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 2762f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(reason)))); 2763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Disable stub call restrictions to always allow calls to abort. 2764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!has_frame_) { 2765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't actually want to generate a pile of code for this, so just 2766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // claim there is a stack frame, without generating one. 2767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(this, StackFrame::NONE); 2768f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(Runtime::kAbort, 1); 2769c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2770f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(Runtime::kAbort, 1); 2771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 277243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // will not return here 2773ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org int3(); 277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 277740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::LoadInstanceDescriptors(Register map, 277840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Register descriptors) { 277989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org mov(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 278040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 278140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 278240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 278306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 278406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org mov(dst, FieldOperand(map, Map::kBitField3Offset)); 278506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 278606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org} 278706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 278806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 2789c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::LoadPowerOf2(XMMRegister dst, 2790c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register scratch, 2791c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org int power) { 2792e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_uintn(power + HeapNumber::kExponentBias, 2793c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org HeapNumber::kExponentBits)); 2794c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org mov(scratch, Immediate(power + HeapNumber::kExponentBias)); 2795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movd(dst, scratch); 2796c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org psllq(dst, HeapNumber::kMantissaBits); 2797c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 2798c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 2799c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 2800528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LookupNumberStringCache(Register object, 2801528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register result, 2802528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch1, 2803528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch2, 2804528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label* not_found) { 2805528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Use of registers. Register result is used as a temporary. 2806528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register number_string_cache = result; 2807528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register mask = scratch1; 2808528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch = scratch2; 2809528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2810528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Load the number string cache. 2811528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 2812528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Make the hash mask from the length of the number string cache. It 2813528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // contains two elements (number and string) for each cache entry. 2814528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 2815528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org shr(mask, kSmiTagSize + 1); // Untag length and divide it by two. 2816528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org sub(mask, Immediate(1)); // Make mask. 2817528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2818528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Calculate the entry in the number string cache. The hash value in the 2819528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // number string cache for smis is just the smi value, and the hash for 2820528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // doubles is the xor of the upper and lower words. See 2821528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Heap::GetNumberStringCache. 2822528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label smi_hash_calculated; 2823528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label load_result_from_cache; 2824528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label not_smi; 2825528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 2826528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfNotSmi(object, ¬_smi, Label::kNear); 2827528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(scratch, object); 2828528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmiUntag(scratch); 2829528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&smi_hash_calculated, Label::kNear); 2830528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(¬_smi); 2831528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cmp(FieldOperand(object, HeapObject::kMapOffset), 2832528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org isolate()->factory()->heap_number_map()); 2833528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); 2834528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(8 == kDoubleSize); 2835528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 2836528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 2837528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Object is heap number and hash is now in scratch. Calculate cache index. 2838528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org and_(scratch, mask); 2839528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register index = scratch; 2840528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register probe = mask; 2841528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(probe, 2842528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2843528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2844528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_twice_pointer_size, 2845528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2846528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfSmi(probe, not_found); 28473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 28483c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); 2849528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(parity_even, not_found); // Bail out if NaN is involved. 2850528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); // The cache did not contain this value. 2851528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&load_result_from_cache, Label::kNear); 2852528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2853528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&smi_hash_calculated); 2854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Object is smi and hash is now in scratch. Calculate cache index. 2855528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org and_(scratch, mask); 2856528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the entry is the smi we are looking for. 2857528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cmp(object, 2858528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2859528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2860528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_twice_pointer_size, 2861528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2862528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); 2863528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2864528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Get the result from the cache. 2865528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&load_result_from_cache); 2866528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mov(result, 2867528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2868528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2869528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_twice_pointer_size, 2870528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize + kPointerSize)); 2871528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org IncrementCounter(isolate()->counters()->number_to_string_native(), 1); 2872528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 2873528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2874528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 28752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( 28762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register instance_type, Register scratch, Label* failure) { 28775c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (!scratch.is(instance_type)) { 28785c838251403b0be9a882540f1922577abba4c872ager@chromium.org mov(scratch, instance_type); 28795c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 28805c838251403b0be9a882540f1922577abba4c872ager@chromium.org and_(scratch, 28815c838251403b0be9a882540f1922577abba4c872ager@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 2882e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org cmp(scratch, kStringTag | kSeqStringTag | kOneByteStringTag); 28835c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, failure); 28845c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 28855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 28865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 28872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgvoid MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register object1, 28882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register object2, 28892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, 28902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, 28912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label* failure) { 2892b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check that both objects are not smis. 289380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 2894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch1, object1); 2895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch1, object2); 28967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org JumpIfSmi(scratch1, failure); 2897b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2898b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Load instance type for both strings. 2899b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org mov(scratch1, FieldOperand(object1, HeapObject::kMapOffset)); 2900b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org mov(scratch2, FieldOperand(object2, HeapObject::kMapOffset)); 2901b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzx_b(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2902b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzx_b(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2903b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 29042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Check that both are flat one-byte strings. 29052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org const int kFlatOneByteStringMask = 290646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 29072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org const int kFlatOneByteStringTag = 2908c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 2909b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Interleave bits from both instance types and compare them in one check. 29102c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); 29112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org and_(scratch1, kFlatOneByteStringMask); 29122c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org and_(scratch2, kFlatOneByteStringMask); 291346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org lea(scratch1, Operand(scratch1, scratch2, times_8, 0)); 29142c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org cmp(scratch1, kFlatOneByteStringTag | (kFlatOneByteStringTag << 3)); 2915b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org j(not_equal, failure); 2916b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2917b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2918b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 291906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, 292006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label* not_unique_name, 292106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance distance) { 2922ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2923ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label succeed; 2924ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org test(operand, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2925ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(zero, &succeed); 2926ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cmpb(operand, static_cast<uint8_t>(SYMBOL_TYPE)); 2927ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org j(not_equal, not_unique_name, distance); 2928ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2929ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org bind(&succeed); 29301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 29311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 29321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 29339af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 29349af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index, 29359af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value, 29369af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org uint32_t encoding_mask) { 29379af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Label is_object; 29389af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org JumpIfNotSmi(string, &is_object, Label::kNear); 293905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Abort(kNonObject); 29409af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org bind(&is_object); 29419af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29429af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org push(value); 29439af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org mov(value, FieldOperand(string, HeapObject::kMapOffset)); 29449af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); 29459af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 29479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmp(value, Immediate(encoding_mask)); 29489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org pop(value); 294905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(equal, kUnexpectedStringType); 29509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29519af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // The index is assumed to be untagged coming in, tag it to compare with the 29529af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // string length without using a temp register, it is restored at the end of 29539af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // this function. 29549af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiTag(index); 295505150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(no_overflow, kIndexIsTooLarge); 29569af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29579af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmp(index, FieldOperand(string, String::kLengthOffset)); 295805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(less, kIndexIsTooLarge); 29599af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29609af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmp(index, Immediate(Smi::FromInt(0))); 296105150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(greater_equal, kIndexIsNegative); 29629af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29639af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // Restore the index 29649af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiUntag(index); 29659af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org} 29669af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 29679af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 2968ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { 29695de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org int frame_alignment = base::OS::ActivationFrameAlignment(); 2970c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (frame_alignment != 0) { 2971ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Make stack end at alignment and make room for num_arguments words 2972ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // and the original value of esp. 2973ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(scratch, esp); 2974c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate((num_arguments + 1) * kPointerSize)); 297521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 2976c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org and_(esp, -frame_alignment); 2977ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(Operand(esp, num_arguments * kPointerSize), scratch); 2978ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 2979c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sub(esp, Immediate(num_arguments * kPointerSize)); 2980ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 2981ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2982ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2983ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2984ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::CallCFunction(ExternalReference function, 2985ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments) { 2986ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Trashing eax is ok as it will be the return value. 2987c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(eax, Immediate(function)); 2988ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org CallCFunction(eax, num_arguments); 2989ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2990ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2991ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2992ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::CallCFunction(Register function, 2993ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments) { 2994e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(has_frame()); 2995c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check stack alignment. 2996badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 2997c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org CheckStackAlignment(); 2998c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 2999c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 3000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com call(function); 30015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org if (base::OS::ActivationFrameAlignment() != 0) { 3002ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org mov(esp, Operand(esp, num_arguments * kPointerSize)); 3003ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 3004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(esp, Immediate(num_arguments * kPointerSize)); 3005ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 3006ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 3007ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 3008ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 30099bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#ifdef DEBUG 30109bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgbool AreAliased(Register reg1, 30119bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg2, 30129bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg3, 30139bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg4, 30149bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg5, 30159bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg6, 30169bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg7, 30179bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg8) { 30189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + 30199bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + 30209bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org reg7.is_valid() + reg8.is_valid(); 30219bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 30229bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org RegList regs = 0; 30239bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg1.is_valid()) regs |= reg1.bit(); 30249bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg2.is_valid()) regs |= reg2.bit(); 30259bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg3.is_valid()) regs |= reg3.bit(); 30269bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg4.is_valid()) regs |= reg4.bit(); 30279bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg5.is_valid()) regs |= reg5.bit(); 30289bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg6.is_valid()) regs |= reg6.bit(); 30299bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg7.is_valid()) regs |= reg7.bit(); 30309bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (reg8.is_valid()) regs |= reg8.bit(); 30319bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org int n_of_non_aliasing_regs = NumRegs(regs); 30329bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 30339bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return n_of_valid_regs != n_of_non_aliasing_regs; 3034c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 30359bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#endif 3036c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 303843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCodePatcher::CodePatcher(byte* address, int size) 3039c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : address_(address), 3040c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_(size), 3041212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org masm_(NULL, address, size + Assembler::kGap) { 30423291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Create a new macro assembler pointing to the address of the code to patch. 304343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The size is adjusted with kGap on order for the assembler to generate size 304443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bytes of instructions without failing with buffer size constraints. 3045e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 304643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 304743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenCodePatcher::~CodePatcher() { 305043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Indicate that code has changed. 30515de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(address_, size_); 305243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 305343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that the code was patched as expected. 3054e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(masm_.pc_ == address_ + size_); 3055e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 305643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 305743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 305843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckPageFlag( 3060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 3061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 3062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 3063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 3064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 3065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 3066e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cc == zero || cc == not_zero); 3067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 3068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 3069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(scratch, Immediate(~Page::kPageAlignmentMask)); 3071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 3072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mask < (1 << kBitsPerByte)) { 3074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(scratch, MemoryChunk::kFlagsOffset), 3075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<uint8_t>(mask)); 3076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 3078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 30807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org} 30817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 30827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 30837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid MacroAssembler::CheckPageFlagForMap( 30847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map, 30857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int mask, 30867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Condition cc, 30877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label* condition_met, 30887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::Distance condition_met_distance) { 3089e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cc == zero || cc == not_zero); 30907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Page* page = Page::FromAddress(map->address()); 30919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(!serializer_enabled()); // Serializer cannot match page_flags. 30927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference reference(ExternalReference::page_flags(page)); 30937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // The inlined static address check of the page's flags relies 30947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // on maps never being compacted. 3095e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!isolate()->heap()->mark_compact_collector()-> 30967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org IsOnEvacuationCandidate(*map)); 30977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (mask < (1 << kBitsPerByte)) { 30987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test_b(Operand::StaticVariable(reference), static_cast<uint8_t>(mask)); 30997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 31007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org test(Operand::StaticVariable(reference), Immediate(mask)); 31017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 31027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org j(cc, condition_met, condition_met_distance); 3103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3106f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid MacroAssembler::CheckMapDeprecated(Handle<Map> map, 3107f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 3108f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated) { 3109f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (map->CanBeDeprecated()) { 3110f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org mov(scratch, map); 3111f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org mov(scratch, FieldOperand(scratch, Map::kBitField3Offset)); 31123c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org and_(scratch, Immediate(Map::Deprecated::kMask)); 3113f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org j(not_zero, if_deprecated); 3114f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 3115f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 3116f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 3117f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 3118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfBlack(Register object, 3119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0, 3120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 3121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 3122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_near) { 3123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HasColor(object, scratch0, scratch1, 3124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com on_black, on_black_near, 3125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 0); // kBlackBitPattern. 3126e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); 3127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::HasColor(Register object, 3131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 3132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 3133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* has_color, 3134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance has_color_distance, 3135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int first_bit, 3136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int second_bit) { 3137e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, ecx)); 3138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(object, bitmap_scratch, mask_scratch); 3140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label other_color, word_boundary; 3142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(first_bit == 1 ? zero : not_zero, &other_color, Label::kNear); 3144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(mask_scratch, mask_scratch); // Shift left 1 by adding. 3145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &word_boundary, Label::kNear); 3146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); 3148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&other_color, Label::kNear); 3149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&word_boundary); 3151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize), 1); 3152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); 3154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&other_color); 3155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::GetMarkBits(Register addr_reg, 3159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 3160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg) { 3161e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(addr_reg, mask_reg, bitmap_reg, ecx)); 3162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 3163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_reg, addr_reg); 3164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ecx, addr_reg); 3165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int shift = 3166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 3167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(ecx, shift); 3168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(ecx, 3169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (Page::kPageAlignmentMask >> shift) & ~(Bitmap::kBytesPerCell - 1)); 3170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(bitmap_reg, ecx); 3172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(ecx, addr_reg); 3173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(ecx, kPointerSizeLog2); 3174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(ecx, (1 << Bitmap::kBitsPerCellLog2) - 1); 3175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(mask_reg, Immediate(1)); 3176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shl_cl(mask_reg); 3177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::EnsureNotWhite( 3181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 3182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 3183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 3184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* value_is_white_and_not_data, 3185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 3186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, ecx)); 3187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(value, bitmap_scratch, mask_scratch); 3188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the value is black or grey we don't need to do anything. 3190e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 3191e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); 3192e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); 3193e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 3194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 3196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Since both black and grey have a 1 in the first position and white does 3198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not have a 1 there we only need to check one bit. 3199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, &done, Label::kNear); 3201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3202000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 3203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for impossible bit pattern. 3204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 3205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com push(mask_scratch); 3206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // shl. May overflow making the check conservative. 3207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(mask_scratch, mask_scratch); 3208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 3209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 3210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 3211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 3212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pop(mask_scratch); 3213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is white. We check whether it is data that doesn't need scanning. 3216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Currently only checks for HeapNumber and non-cons strings. 3217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register map = ecx; // Holds map while checking type. 3218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register length = ecx; // Holds length of object after checking type. 3219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_heap_number; 3220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 3221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for heap-number 3223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(map, FieldOperand(value, HeapObject::kMapOffset)); 3224d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org cmp(map, isolate()->factory()->heap_number_map()); 3225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, ¬_heap_number, Label::kNear); 3226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Immediate(HeapNumber::kSize)); 3227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 3228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_heap_number); 3230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for strings. 3231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 3232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 3233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 3234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 3235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register instance_type = ecx; 3236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 3237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(instance_type, kIsIndirectStringMask | kIsNotStringMask); 3238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, value_is_white_and_not_data); 3239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It's a non-indirect (non-cons and non-slice) string. 3240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's external, the length is just ExternalString::kSize. 3241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). 3242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_external; 3243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // External strings are the only ones with the kExternalStringTag bit 3244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // set. 3245e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, kSeqStringTag & kExternalStringTag); 3246e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, kConsStringTag & kExternalStringTag); 3247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com test_b(instance_type, kExternalStringTag); 3248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_external, Label::kNear); 3249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Immediate(ExternalString::kSize)); 3250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 3251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_external); 32532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Sequential string, either Latin1 or UC16. 3254e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kOneByteStringTag == 0x04); 3255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(kStringEncodingMask)); 3256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xor_(length, Immediate(kStringEncodingMask)); 3257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(length, Immediate(0x04)); 32582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Value now either 4 (if Latin1) or 8 (if UC16), i.e., char-size shifted 3259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // by 2. If we multiply the string length as smi by this, it still 3260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // won't overflow a 32-bit value. 3261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(SeqOneByteString::kMaxSize, SeqTwoByteString::kMaxSize); 3262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SeqOneByteString::kMaxSize <= 3263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<int>(0xffffffffu >> (2 + kSmiTagSize))); 3264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com imul(length, FieldOperand(value, String::kLengthOffset)); 3265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(length, 2 + kSmiTagSize + kSmiShiftSize); 3266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 3267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(~kObjectAlignmentMask)); 3268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 3270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a data object, and it is white. Mark it black. Since we know 3271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that the object is white we can make it black by flipping one bit. 3272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 3273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 3275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com add(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), 3276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com length); 3277000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 3278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mov(length, Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset)); 3279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); 3280594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(less_equal, kLiveBytesCountOverflowChunkSize); 3281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 3284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3286be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3287355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid MacroAssembler::EnumLength(Register dst, Register map) { 3288355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3289355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(dst, FieldOperand(map, Map::kBitField3Offset)); 32903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org and_(dst, Immediate(Map::EnumLengthBits::kMask)); 32913c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org SmiTag(dst); 3292355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 3293355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3294355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3295be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid MacroAssembler::CheckEnumCache(Label* call_runtime) { 3296355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label next, start; 3297be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ecx, eax); 3298be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3299355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check if the enum length field is properly initialized, indicating that 3300355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // there is an enum cache. 3301be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 3302be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3303355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(edx, ebx); 3304af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org cmp(edx, Immediate(Smi::FromInt(kInvalidEnumCacheSentinel))); 3305de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org j(equal, call_runtime); 3306de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 3307355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org jmp(&start); 3308355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3309355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&next); 3310355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 3311be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 3312be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For all objects but the receiver, check that the cache is empty. 3313355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(edx, ebx); 3314355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(edx, Immediate(Smi::FromInt(0))); 3315355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org j(not_equal, call_runtime); 3316355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3317355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&start); 3318355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3319355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check that there are no elements. Register rcx contains the current JS 3320355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // object we've reached through the prototype chain. 33216d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Label no_elements; 3322355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset)); 3323355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmp(ecx, isolate()->factory()->empty_fixed_array()); 33246d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org j(equal, &no_elements); 33256d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org 33266d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org // Second chance, the object may be using the empty slow element dictionary. 33276d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org cmp(ecx, isolate()->factory()->empty_slow_element_dictionary()); 3328be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, call_runtime); 3329be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 33306d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bind(&no_elements); 3331be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 3332be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org cmp(ecx, isolate()->factory()->null_value()); 3333be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, &next); 3334be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 3335be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 333659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 3337ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MacroAssembler::TestJSArrayForAllocationMemento( 333859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Register receiver_reg, 3339b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Register scratch_reg, 3340b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label* no_memento_found) { 334159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_start = 334259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_start(isolate()); 334359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_allocation_top = 334459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 334559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 334659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org lea(scratch_reg, Operand(receiver_reg, 3347ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); 334859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmp(scratch_reg, Immediate(new_space_start)); 3349b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(less, no_memento_found); 335059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmp(scratch_reg, Operand::StaticVariable(new_space_allocation_top)); 3351b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(greater, no_memento_found); 3352ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), 3353528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Immediate(isolate()->factory()->allocation_memento_map())); 335459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 335559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 335659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 3357e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 3358e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register object, 3359e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch0, 3360e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch1, 3361e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* found) { 3362e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch1.is(scratch0)); 3363e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Factory* factory = isolate()->factory(); 3364e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register current = scratch0; 3365e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label loop_again; 3366e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 3367e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // scratch contained elements pointer. 3368e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(current, object); 3369e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 3370e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loop based on the map going up the prototype chain. 3371e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&loop_again); 3372e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(current, FieldOperand(current, HeapObject::kMapOffset)); 3373e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(scratch1, FieldOperand(current, Map::kBitField2Offset)); 3374d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DecodeField<Map::ElementsKindBits>(scratch1); 3375e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org cmp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 3376e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(equal, found); 3377e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mov(current, FieldOperand(current, Map::kPrototypeOffset)); 3378e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org cmp(current, Immediate(factory->null_value())); 3379e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(not_equal, &loop_again); 3380e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 3381e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 3382bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 3383763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 3384e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!dividend.is(eax)); 3385e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!dividend.is(edx)); 338642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org base::MagicNumbersForDivision<uint32_t> mag = 338742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org base::SignedDivisionByConstant(static_cast<uint32_t>(divisor)); 338842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org mov(eax, Immediate(mag.multiplier)); 3389bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org imul(dividend); 339042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0; 339142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org if (divisor > 0 && neg) add(edx, dividend); 339242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org if (divisor < 0 && !neg && mag.multiplier > 0) sub(edx, dividend); 339342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org if (mag.shift > 0) sar(edx, mag.shift); 3394763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org mov(eax, dividend); 3395763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org shr(eax, 31); 3396763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org add(edx, eax); 3397bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 3398bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 3399bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 340043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 34019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 3403