1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/ic.h" 116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/ic-compiler.h" 126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/stub-cache.h" 13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// ---------------------------------------------------------------------------- 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Static IC stub generators. 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(masm) 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, Register type, 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* global_object) { 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register usage: 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // type: holds the receiver instance type on entry. 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(type, JS_GLOBAL_OBJECT_TYPE); 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, global_object); 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(type, JS_BUILTINS_OBJECT_TYPE); 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, global_object); 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(type, JS_GLOBAL_PROXY_TYPE); 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, global_object); 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Helper function used to load a property from a dictionary backing 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// storage. This function may fail to load a property even though it is 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// in the dictionary, so code at miss_label must always call a backup 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// property load that is complete. This function is safe to call if 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// name is not internalized, and will jump to the miss_label in that 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// case. The generated code assumes that the receiver has slow 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// properties, is not a global object and does not have interceptors. 446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, 456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register elements, Register name, 466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register r0, Register r1, Register result) { 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register use: 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // elements - holds the property dictionary on entry and is unchanged. 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // name - holds the name of the property on entry and is unchanged. 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Scratch registers: 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // r0 - used for the index into the property dictionary 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // r1 - used to hold the capacity of the property dictionary. 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result - holds the result on exit. 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Probe the dictionary. 646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, 656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org elements, name, r0, r1); 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If probing finds an entry in the dictionary, r0 contains the 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index into the dictionary. Check that the value is a normal 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // property. 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kElementsStartOffset = 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameDictionary::kHeaderSize + 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, miss_label); 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the value at the masked, scaled index. 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kValueOffset = kElementsStartOffset + kPointerSize; 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Helper function used to store a property to a dictionary backing 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// storage. This function may fail to store a property eventhough it 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// is in the dictionary, so code at miss_label must always call a 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// backup property store that is complete. This function is safe to 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// call if name is not internalized, and will jump to the miss_label in 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// that case. The generated code assumes that the receiver has slow 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// properties, is not a global object and does not have interceptors. 926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label, 936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register elements, Register name, 946474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register value, Register r0, Register r1) { 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register use: 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // elements - holds the property dictionary on entry and is clobbered. 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // name - holds the name of the property on entry and is unchanged. 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // value - holds the value to store and is unchanged. 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // r0 - used for index into the property dictionary and is clobbered. 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // r1 - used to hold the capacity of the property dictionary and is clobbered. 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Probe the dictionary. 1106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, 1116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org elements, name, r0, r1); 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If probing finds an entry in the dictionary, r0 contains the 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index into the dictionary. Check that the value is a normal 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // property that is not read only. 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kElementsStartOffset = 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameDictionary::kHeaderSize + 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kTypeAndReadOnlyMask = 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (PropertyDetails::TypeField::kMask | 1236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org PropertyDetails::AttributesField::encode(READ_ONLY)) 1246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org << kSmiTagSize; 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(kTypeAndReadOnlyMask)); 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, miss_label); 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the value at the masked, scaled index. 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kValueOffset = kElementsStartOffset + kPointerSize; 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(r0, 0), value); 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update write barrier. Make sure not to clobber the value. 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(r1, value); 13606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWrite(elements, r0, r1, kDontSaveFPRegs); 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Checks the receiver for special cases (value type, slow case bits). 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Falls through for regular JS object. 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm, 1436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register receiver, Register map, 1446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org int interceptor_bit, Label* slow) { 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register use: 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // receiver - holds the receiver and is unchanged. 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Scratch registers: 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // map - used to hold the map of the receiver. 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object isn't a smi. 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(receiver, slow); 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the map of the receiver. 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check bit field. 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(map, Map::kBitFieldOffset), 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, slow); 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object is some kind of JS object EXCEPT JS Value type. 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In the case that the object is a value-wrapper object, 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we enter the runtime system to make sure that indexing 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // into string objects works as intended. 164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(map, JS_OBJECT_TYPE); 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, slow); 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Loads an indexed element from a fast case array. 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// If not_fast_array is NULL, doesn't perform the elements map check. 1736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 1746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register key, Register scratch, 1756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register result, Label* not_fast_array, 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* out_of_range) { 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register use: 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // receiver - holds the receiver and is unchanged. 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // key - holds the key and is unchanged (must be a smi). 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Scratch registers: 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // scratch - used to hold elements of the receiver and the loaded value. 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result - holds the result on exit if the load succeeds and 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we fall through. 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset)); 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (not_fast_array != NULL) { 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object is in fast mode and writable. 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(scratch, 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->isolate()->factory()->fixed_array_map(), 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org not_fast_array, 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DONT_DO_SMI_CHECK); 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertFastElements(scratch); 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the key (index) is within bounds. 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset)); 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, out_of_range); 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fast case: Do the load. 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0)); 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize)); 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch, Immediate(masm->isolate()->factory()->the_hole_value())); 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In case the loaded value is the_hole we have to consult GetProperty 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to ensure the prototype chain is searched. 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, out_of_range); 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!result.is(scratch)) { 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, scratch); 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Checks whether a key is an array index string or a unique name. 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Falls through if the key is a unique name. 2136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void GenerateKeyNameCheck(MacroAssembler* masm, Register key, 2146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register map, Register hash, 2156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Label* index_string, Label* not_unique) { 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register use: 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // key - holds the key and is unchanged. Assumed to be non-smi. 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Scratch registers: 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // map - used to hold the map of the key. 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // hash - used to hold the hash of the key. 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label unique; 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(key, LAST_UNIQUE_NAME_TYPE, map); 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, not_unique); 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE); 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &unique); 226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Is the string an array index, with cached numeric value? 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(hash, FieldOperand(key, Name::kHashFieldOffset)); 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(hash, Immediate(Name::kContainsCachedArrayIndexMask)); 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, index_string); 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Is the string internalized? We already know it's a string so a single 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // bit test is enough. 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kNotInternalizedTag != 0); 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kIsNotInternalizedMask); 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, not_unique); 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&unique); 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic Operand GenerateMappedArgumentsLookup( 2446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Register object, Register key, Register scratch1, 2456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register scratch2, Label* unmapped_case, Label* slow_case) { 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Heap* heap = masm->isolate()->heap(); 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Factory* factory = masm->isolate()->factory(); 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the receiver is a JSObject. Because of the elements 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // map check later, we do not need to check for interceptors or 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // whether it requires access checks. 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(object, slow_case); 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object is some kind of JSObject. 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, scratch1); 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, slow_case); 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the key is a positive smi. 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(key, Immediate(0x80000001)); 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, slow_case); 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the elements into scratch1 and check its map. 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> arguments_map(heap->sloppy_arguments_elements_map()); 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch1, FieldOperand(object, JSObject::kElementsOffset)); 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK); 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if element is in the range of mapped arguments. If not, jump 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to the unmapped lookup with the parameter map in scratch1. 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset)); 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(scratch2, Immediate(Smi::FromInt(2))); 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(key, scratch2); 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, unmapped_case); 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load element index and check whether it is the hole. 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize; 2756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(scratch2, 2766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FieldOperand(scratch1, key, times_half_pointer_size, kHeaderSize)); 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch2, factory->the_hole_value()); 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, unmapped_case); 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load value from context and return it. We can reuse scratch1 because 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we do not jump to the unmapped lookup (which requires the parameter 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // map in scratch1). 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kContextOffset = FixedArray::kHeaderSize; 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch1, FieldOperand(scratch1, kContextOffset)); 2856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return FieldOperand(scratch1, scratch2, times_half_pointer_size, 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Context::kHeaderSize); 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register key, 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register parameter_map, 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch, 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* slow_case) { 295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Element is in arguments backing store, which is referenced by the 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // second element of the parameter_map. 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize; 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register backing_store = parameter_map; 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(backing_store, FieldOperand(parameter_map, kBackingStoreOffset)); 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map()); 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK); 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset)); 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(key, scratch); 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(greater_equal, slow_case); 3056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return FieldOperand(backing_store, key, times_half_pointer_size, 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize); 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 31158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org // The return address is on the stack. 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow, check_name, index_smi, index_name, property_array_property; 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label probe_dictionary, check_number_dictionary; 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 31542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = LoadDescriptor::ReceiverRegister(); 31642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register key = LoadDescriptor::NameRegister(); 317e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(edx)); 318e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(ecx)); 31958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org 320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the key is a smi. 32158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ JumpIfNotSmi(key, &check_name); 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&index_smi); 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Now the key is known to be a smi. This place is also jumped to from 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // where a numeric string is converted to a smi. 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org GenerateKeyedLoadReceiverCheck(masm, receiver, eax, 3276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Map::kHasIndexedInterceptor, &slow); 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the receiver's map to see if it has fast elements. 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckFastElements(eax, &check_number_dictionary); 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 33258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org GenerateFastArrayLoad(masm, receiver, key, eax, eax, NULL, &slow); 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Isolate* isolate = masm->isolate(); 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Counters* counters = isolate->counters(); 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->keyed_load_generic_smi(), 1); 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_number_dictionary); 33958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(ebx, key); 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ebx); 34158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(eax, FieldOperand(receiver, JSObject::kElementsOffset)); 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check whether the elements is a number dictionary. 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx: untagged index 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax: elements 3466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CheckMap(eax, isolate->factory()->hash_table_map(), &slow, 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DONT_DO_SMI_CHECK); 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow_pop_receiver; 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push receiver on the stack to free up a register for the dictionary 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // probing. 35158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(receiver); 35258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ LoadFromNumberDictionary(&slow_pop_receiver, eax, key, ebx, edx, edi, eax); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pop receiver before returning. 35458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ pop(receiver); 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow_pop_receiver); 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pop the receiver from the stack and jump to runtime. 35958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ pop(receiver); 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Slow case: jump to runtime. 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->keyed_load_generic_slow(), 1); 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateRuntimeGetProperty(masm); 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_name); 36758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow); 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org GenerateKeyedLoadReceiverCheck(masm, receiver, eax, Map::kHasNamedInterceptor, 3706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org &slow); 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the receiver is a fast-case object, check the keyed lookup 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // cache. Otherwise probe the dictionary. 37458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kPropertiesOffset)); 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(isolate->factory()->hash_table_map())); 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &probe_dictionary); 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The receiver's map is still in eax, compute the keyed lookup cache hash 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // based on 32 bits of the map pointer and the string hash. 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 38258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ cmp(eax, FieldOperand(receiver, HeapObject::kMapOffset)); 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(equal, kMapIsNoLongerInEax); 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, eax); // Keep the map around for later. 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(eax, KeyedLookupCache::kMapHashShift); 38758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(edi, FieldOperand(key, String::kHashFieldOffset)); 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(edi, String::kHashShift); 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(eax, edi); 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(eax, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the key (consisting of map and internalized string) from the cache and 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // check for match. 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label load_in_object_property; 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label hit_on_nth_entry[kEntriesPerBucket]; 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference cache_keys = 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::keyed_lookup_cache_keys(masm->isolate()); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < kEntriesPerBucket - 1; i++) { 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label try_next_entry; 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, eax); 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(edi, kPointerSizeLog2 + 1); 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (i != 0) { 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(edi, Immediate(kPointerSize * i * 2)); 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &try_next_entry); 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(edi, Immediate(kPointerSize)); 41058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ cmp(key, Operand::StaticArray(edi, times_1, cache_keys)); 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &hit_on_nth_entry[i]); 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&try_next_entry); 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(edi, Operand(eax, 1)); 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(edi, kPointerSizeLog2 + 1); 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(edi, Immediate(kPointerSize * (kEntriesPerBucket - 1) * 2)); 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &slow); 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(edi, Immediate(kPointerSize)); 42158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ cmp(key, Operand::StaticArray(edi, times_1, cache_keys)); 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &slow); 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get field offset. 42558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org // ebx : receiver's map 42658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org // eax : lookup cache index 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference cache_field_offsets = 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Hit on nth entry. 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = kEntriesPerBucket - 1; i >= 0; i--) { 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&hit_on_nth_entry[i]); 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (i != 0) { 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(eax, Immediate(i)); 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand::StaticArray(eax, times_pointer_size, cache_field_offsets)); 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(eax, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(edi, eax); 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, &property_array_property); 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (i != 0) { 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&load_in_object_property); 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load in-object property. 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&load_in_object_property); 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceSizeOffset)); 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(eax, edi); 45058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(eax, FieldOperand(receiver, eax, times_pointer_size, 0)); 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load property array property. 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&property_array_property); 45658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(eax, FieldOperand(receiver, JSObject::kPropertiesOffset)); 4576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(eax, 4586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FieldOperand(eax, edi, times_pointer_size, FixedArray::kHeaderSize)); 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do a quick inline probe of the receiver's dictionary, if it 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // exists. 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&probe_dictionary); 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 46658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(eax, FieldOperand(receiver, JSObject::kMapOffset)); 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateGlobalInstanceTypeCheck(masm, eax, &slow); 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 47058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org GenerateDictionaryLoad(masm, &slow, ebx, key, eax, edi, eax); 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&index_name); 47558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ IndexFromHash(ebx, key); 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Now jump to the place where smi keys are handled. 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&index_smi); 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedLoadIC::GenerateString(MacroAssembler* masm) { 482248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // Return address is on the stack. 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label miss; 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 48542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = LoadDescriptor::ReceiverRegister(); 48642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register index = LoadDescriptor::NameRegister(); 487fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org Register scratch = ebx; 488e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch.is(receiver) && !scratch.is(index)); 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = eax; 490e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(scratch)); 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org StringCharAtGenerator char_at_generator(receiver, index, scratch, result, 493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &miss, // When not a string. 494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &miss, // When not a number. 495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &miss, // When index out of range. 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STRING_INDEX_IS_ARRAY_INDEX); 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org char_at_generator.GenerateFast(masm); 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StubRuntimeCallHelper call_helper; 501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org char_at_generator.GenerateSlow(masm, call_helper); 502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&miss); 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateMiss(masm); 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { 509fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Return address is on the stack. 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow, notin; 51142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 51242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 51342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 514e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(edx)); 515e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(name.is(ecx)); 516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(eax)); 517fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 5186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Operand mapped_location = GenerateMappedArgumentsLookup( 5196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org masm, receiver, name, ebx, edi, ¬in, &slow); 520fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(mapped_location, value); 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ecx, mapped_location); 522fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(edx, value); 52306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); 524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Ret(); 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬in); 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The unmapped lookup expects that the parameter map is in ebx. 527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand unmapped_location = 528fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org GenerateUnmappedArgumentsLookup(masm, name, ebx, edi, &slow); 529fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(unmapped_location, value); 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(edi, unmapped_location); 531fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(edx, value); 53206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Ret(); 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateMiss(masm); 536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic void KeyedStoreGenerateGenericHelper( 5406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, 5416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { 542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label transition_smi_elements; 543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label finish_object_store, non_double_value, transition_double_elements; 544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label fast_double_without_map_check; 54542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 54642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register key = StoreDescriptor::NameRegister(); 54742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 548e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(edx)); 549e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(ecx)); 550e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(eax)); 551fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // key is a smi. 552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx: FixedArray receiver->elements 553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // edi: receiver map 554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fast case: Do the store, could either Object or double. 555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(fast_object); 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (check_map == kCheckMap) { 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, fast_double); 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // HOLECHECK: guards "A[i] = V" 563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We have to go to the runtime if the current value is the hole because 564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // there may be a callback on the element 565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label holecheck_passed1; 566fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ cmp(FixedArrayElementOperand(ebx, key), 567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->isolate()->factory()->the_hole_value()); 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &holecheck_passed1); 569fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ JumpIfDictionaryInPrototypeChain(receiver, ebx, edi, slow); 570fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&holecheck_passed1); 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smi stores don't require further checks. 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label non_smi_value; 576fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ JumpIfNotSmi(value, &non_smi_value); 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (increment_length == kIncrementLength) { 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Add 1 to receiver->length. 579fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ add(FieldOperand(receiver, JSArray::kLengthOffset), 580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(1))); 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // It's irrelevant whether array is smi-only or not when writing a smi. 583fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(FixedArrayElementOperand(ebx, key), value); 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&non_smi_value); 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Escape to elements kind transition case. 588fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckFastObjectElements(edi, &transition_smi_elements); 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fast elements array, store the value to the elements backing store. 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&finish_object_store); 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (increment_length == kIncrementLength) { 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Add 1 to receiver->length. 595fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ add(FieldOperand(receiver, JSArray::kLengthOffset), 596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(1))); 597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 598fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(FixedArrayElementOperand(ebx, key), value); 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update write barrier for the elements array address. 600fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(edx, value); // Preserve the value which is returned. 60106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, 60206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org OMIT_SMI_CHECK); 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(fast_double); 606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (check_map == kCheckMap) { 607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for fast double array case. If this fails, call through to the 608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // runtime. 609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); 610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, slow); 611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the value is a number, store it as a double in the FastDoubleElements 612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // array. 613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // HOLECHECK: guards "A[i] double hole?" 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We have to see if the double version of the hole is present. If so 617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // go to the runtime. 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); 619fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ cmp(FieldOperand(ebx, key, times_4, offset), Immediate(kHoleNanUpper32)); 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &fast_double_without_map_check); 621fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ JumpIfDictionaryInPrototypeChain(receiver, ebx, edi, slow); 622fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&fast_double_without_map_check); 625fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ StoreNumberToDoubleElements(value, ebx, key, edi, 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &transition_double_elements, false); 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (increment_length == kIncrementLength) { 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Add 1 to receiver->length. 629fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ add(FieldOperand(receiver, JSArray::kLengthOffset), 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(1))); 631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&transition_smi_elements); 635fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset)); 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Transition the array appropriately depending on the value type. 6386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CheckMap(value, masm->isolate()->factory()->heap_number_map(), 6396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org &non_double_value, DONT_DO_SMI_CHECK); 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS 642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and complete the store. 643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 6446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FAST_DOUBLE_ELEMENTS, ebx, edi, slow); 6456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org AllocationSiteMode mode = 6466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS); 6476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value, 6486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ebx, mode, slow); 649fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&fast_double_without_map_check); 651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&non_double_value); 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS 6546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS, ebx, 6556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org edi, slow); 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); 657d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 658d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org masm, receiver, key, value, ebx, mode, slow); 659fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&finish_object_store); 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&transition_double_elements); 663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS 666fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset)); 6676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, 6686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ebx, edi, slow); 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); 6706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, 6716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org value, ebx, mode, slow); 672fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&finish_object_store); 674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StrictMode strict_mode) { 679fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Return address is on the stack. 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow, fast_object, fast_object_grow; 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label fast_double, fast_double_grow; 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label array, extra, check_if_double_array; 68342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 68442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register key = StoreDescriptor::NameRegister(); 685e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(edx)); 686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(ecx)); 687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object isn't a smi. 689fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ JumpIfSmi(receiver, &slow); 690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the map from the receiver. 691fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); 692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the receiver does not require access checks and is not observed. 693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The generic stub does not perform map checks or handle observed objects. 694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(edi, Map::kBitFieldOffset), 695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved); 696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &slow); 697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the key is a smi. 698fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ JumpIfNotSmi(key, &slow); 699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(edi, JS_ARRAY_TYPE); 700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &array); 701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object is some kind of JSObject. 702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); 703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, &slow); 704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Object case: Check key against length in the elements array. 706fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Key is a smi. 707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // edi: receiver map 708fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check array bounds. Both the key and the length of FixedArray are smis. 710fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ cmp(key, FieldOperand(ebx, FixedArray::kLengthOffset)); 711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, &fast_object); 712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Slow case: call runtime. 714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 7156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); 716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Extra capacity case: Check if there is extra capacity to 718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // perform the store and update the length. Used for adding one 719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // element to the array by writing to array[array.length]. 720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&extra); 721fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // receiver is a JSArray. 722fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // key is a smi. 723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx: receiver->elements, a FixedArray 724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // edi: receiver map 725fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // flags: compare (key, receiver.length()) 726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // do not leave holes in the array: 727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &slow); 728fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ cmp(key, FieldOperand(ebx, FixedArray::kLengthOffset)); 729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, &slow); 730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); 731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); 732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &check_if_double_array); 733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&fast_object_grow); 734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_if_double_array); 736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); 737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &slow); 738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&fast_double_grow); 739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Array case: Get the length and the elements array from the JS 741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // array. Check that the array is in fast mode (and writable); if it 742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is the length is always a smi. 743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&array); 744fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // receiver is a JSArray. 745fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // key is a smi. 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // edi: receiver map 747fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); 748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the key against the length in the array and fall through to the 750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // common store code. 751fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset)); // Compare smis. 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, &extra); 753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, 7556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kCheckMap, kDontIncrementLength); 756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &slow, kDontCheckMap, kIncrementLength); 758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LoadIC::GenerateNormal(MacroAssembler* masm) { 762077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org Register dictionary = eax; 76342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); 76442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); 765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 766077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org Label slow; 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 76842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(), 7697b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org JSObject::kPropertiesOffset)); 7707b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org GenerateDictionaryLoad(masm, &slow, dictionary, 77142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org LoadDescriptor::NameRegister(), edi, ebx, eax); 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Dictionary load failed, go slow (but don't miss). 7751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org __ bind(&slow); 7761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org GenerateRuntimeGetProperty(masm); 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 780fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.orgstatic void LoadIC_PushArgs(MacroAssembler* masm) { 78142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = LoadDescriptor::ReceiverRegister(); 78242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = LoadDescriptor::NameRegister(); 783e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!ebx.is(receiver) && !ebx.is(name)); 784fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 785fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ pop(ebx); 786fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(receiver); 787fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(name); 788fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(ebx); 789fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org} 790fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 791fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LoadIC::GenerateMiss(MacroAssembler* masm) { 793248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // Return address is on the stack. 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 796fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org LoadIC_PushArgs(masm); 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform tail call to the entry. 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference ref = 800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); 801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(ref, 2, 1); 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 806248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // Return address is on the stack. 807fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org LoadIC_PushArgs(masm); 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform tail call to the entry. 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallRuntime(Runtime::kGetProperty, 2, 1); 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 815248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // Return address is on the stack. 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1); 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 818fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org LoadIC_PushArgs(masm); 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform tail call to the entry. 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference ref = 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); 823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(ref, 2, 1); 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 828248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // Return address is on the stack. 829fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org LoadIC_PushArgs(masm); 830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform tail call to the entry. 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 837fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Return address is on the stack. 838d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 839d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org Code::ComputeHandlerFlags(Code::STORE_IC)); 8407b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org masm->isolate()->stub_cache()->GenerateProbe( 841b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org masm, flags, false, StoreDescriptor::ReceiverRegister(), 84242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org StoreDescriptor::NameRegister(), ebx, no_reg); 843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Cache miss: Jump to runtime. 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateMiss(masm); 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 849fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.orgstatic void StoreIC_PushArgs(MacroAssembler* masm) { 85042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 85142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 85242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 853fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 854e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); 855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); 857fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(receiver); 858fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(name); 859fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(value); 860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); 861fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org} 862fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 863fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org 864fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.orgvoid StoreIC::GenerateMiss(MacroAssembler* masm) { 865fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Return address is on the stack. 866fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org StoreIC_PushArgs(masm); 867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform tail call to the entry. 869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference ref = 870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); 871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(ref, 3, 1); 872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid StoreIC::GenerateNormal(MacroAssembler* masm) { 876077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org Label restore_miss; 87742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 87842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 87942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 880077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org Register dictionary = ebx; 881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 882077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); 883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // A lot of registers are needed for storing to slow case 885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // objects. Push and restore receiver but rely on 886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // GenerateDictionaryStore preserving the value and name. 887fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ push(receiver); 888077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, 889077614ab01af32023172ccb69e837ed2f9524e91machenbach@chromium.org receiver, edi); 890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(1); 891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Counters* counters = masm->isolate()->counters(); 892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->store_normal_hit(), 1); 893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&restore_miss); 896fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org __ pop(receiver); 897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->store_normal_miss(), 1); 898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateMiss(masm); 899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 903fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Return address is on the stack. 904fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org StoreIC_PushArgs(masm); 905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do tail-call to runtime routine. 907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference ref = 908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); 909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(ref, 3, 1); 910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgCondition CompareIC::ComputeCondition(Token::Value op) { 917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (op) { 918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::EQ_STRICT: 919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::EQ: 920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return equal; 921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::LT: 922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return less; 923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::GT: 924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return greater; 925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::LTE: 926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return less_equal; 927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::GTE: 928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return greater_equal; 929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return no_condition; 932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool CompareIC::HasInlinedSmiCode(Address address) { 937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The address of the instruction following the call. 938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address test_instruction_address = 939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org address + Assembler::kCallTargetAddressOffset; 940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the instruction following the call is not a test al, nothing 942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // was inlined. 943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return *test_instruction_address == Assembler::kTestAlByte; 944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid PatchInlinedSmiCode(Address address, InlinedSmiCheck check) { 948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The address of the instruction following the call. 949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address test_instruction_address = 950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org address + Assembler::kCallTargetAddressOffset; 951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the instruction following the call is not a test al, nothing 953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // was inlined. 954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*test_instruction_address != Assembler::kTestAlByte) { 955e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*test_instruction_address == Assembler::kNopByte); 956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address delta_address = test_instruction_address + 1; 960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The delta to the start of the map check instruction and the 961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // condition code uses at the patched jump. 962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address); 963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_trace_ic) { 9646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org PrintF("[ patching ic at %p, test=%p, delta=%d\n", address, 9656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org test_instruction_address, delta); 966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Patch with a short conditional jump. Enabling means switching from a short 969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the 970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // reverse operation of that. 971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address jmp_address = test_instruction_address - delta; 972e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((check == ENABLE_INLINED_SMI_CHECK) 9736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ? (*jmp_address == Assembler::kJncShortOpcode || 9746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org *jmp_address == Assembler::kJcShortOpcode) 9756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org : (*jmp_address == Assembler::kJnzShortOpcode || 9766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org *jmp_address == Assembler::kJzShortOpcode)); 9776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Condition cc = 9786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org (check == ENABLE_INLINED_SMI_CHECK) 9796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 9806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 9836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 9846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} // namespace v8::internal 985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_TARGET_ARCH_X87 987