16474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// Copyright 2014 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 76474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#if V8_TARGET_ARCH_IA32 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 96474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/call-optimization.h" 106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h" 11d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic.h" 12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(masm) 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadViaGetter( 206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Handle<HeapType> type, Register receiver, 216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSFunction> getter) { 226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org { 236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (!getter.is_null()) { 266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Call the JavaScript getter with the receiver on the stack. 276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Swap in the global receiver. 296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(receiver, 306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(receiver); 336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount actual(0); 346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount expected(getter); 356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, 366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NullCallWrapper()); 376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // If we generate a global code snippet for deoptimization only, remember 396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // the place to continue after deoptimization. 406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Restore context register. 446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ ret(0); 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 502b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 512b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, Label* miss_label, Register receiver, 522b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Handle<Name> name, Register scratch0, Register scratch1) { 53e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(name->IsUniqueName()); 54e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!receiver.is(scratch0)); 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Counters* counters = masm->isolate()->counters(); 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->negative_lookups(), 1); 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->negative_lookups_miss(), 1); 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kInterceptorOrAccessCheckNeededMask = 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Bail out if the receiver has a named interceptor or requires access checks. 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(scratch0, Map::kBitFieldOffset), 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kInterceptorOrAccessCheckNeededMask); 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, miss_label); 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that receiver is a JSObject. 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE); 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, miss_label); 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load properties array. 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register properties = scratch0; 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the properties array is a dictionary. 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(properties, HeapObject::kMapOffset), 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(masm->isolate()->factory()->hash_table_map())); 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss_label); 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done, 846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org properties, name, scratch1); 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ DecrementCounter(counters->negative_lookups_miss(), 1); 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 902b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 912b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, int index, Register prototype, Label* miss) { 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the global function with the given index. 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction> function( 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JSFunction::cast(masm->isolate()->native_context()->get(index))); 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check we're still in the same context. 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = prototype; 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, Operand(esi, offset)); 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(scratch, Context::SlotOffset(index)), function); 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss); 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load its initial map. The global functions all have initial maps. 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(prototype, Immediate(Handle<Map>(function->initial_map()))); 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the prototype from the initial map. 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1102b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 1112b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, Register receiver, Register scratch1, 1122b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Register scratch2, Label* miss_label) { 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, scratch1); 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate call to api function. 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// This function uses push() to generate smaller, faster code than 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the version above. It is an optimization that should will be removed 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// when api call ICs are generated in hydrogen. 1232b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateFastApiCall( 1242b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, const CallOptimization& optimization, 1252b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Handle<Map> receiver_map, Register receiver, Register scratch_in, 1262b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org bool is_store, int argc, Register* values) { 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy return value. 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(scratch_in); 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // receiver 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(receiver); 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Write the arguments to stack frame. 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < argc; i++) { 1336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register arg = values[argc - 1 - i]; 134e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!receiver.is(arg)); 135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch_in.is(arg)); 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(arg); 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch_in); 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Stack now matches JSFunction abi. 140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(optimization.is_simple_api_call()); 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abi for CallApiFunctionStub. 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register callee = eax; 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register call_data = ebx; 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register holder = ecx; 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register api_function_address = edx; 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = edi; // scratch_in is no longer valid. 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put holder in place. 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallOptimization::HolderLookup holder_lookup; 1516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSObject> api_holder = 1526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (holder_lookup) { 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CallOptimization::kHolderIsReceiver: 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(holder, receiver); 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CallOptimization::kHolderFound: 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(holder, api_holder); 1596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org break; 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CallOptimization::kHolderNotFound: 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Isolate* isolate = masm->isolate(); 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction> function = optimization.constant_function(); 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> call_data_obj(api_call_info->data(), isolate); 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put callee in place. 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(callee, function); 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool call_data_undefined = false; 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put call_data in place. 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (isolate->heap()->InNewSpace(*call_data_obj)) { 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, api_call_info); 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset)); 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (call_data_obj->IsUndefined()) { 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org call_data_undefined = true; 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(call_data, Immediate(isolate->factory()->undefined_value())); 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(call_data, call_data_obj); 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put api_function_address in place. 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address function_address = v8::ToCData<Address>(api_call_info->callback()); 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(api_function_address, Immediate(function_address)); 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump to stub. 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallStub(&stub); 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate code to check that a global property cell is empty. Create 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the property cell at compilation time if no cell exists for the 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// property. 1982b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateCheckPropertyCell( 1992b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 2002b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Register scratch, Label* miss) { 2016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 202e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cell->value()->IsTheHole()); 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (masm->serializer_enabled()) { 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, Immediate(cell)); 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(the_hole)); 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand::ForCell(cell), Immediate(the_hole)); 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss); 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreViaSetter( 2166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Handle<HeapType> type, Register receiver, 2176474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSFunction> setter) { 2186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // ----------- S t a t e ------------- 2196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // -- esp[0] : return address 2206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // ----------------------------------- 2216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org { 2226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Save value register, so we can restore it later. 2256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(value()); 2266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (!setter.is_null()) { 2286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Call the JavaScript setter with receiver and value on the stack. 2296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 2306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Swap in the global receiver. 2316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(receiver, 2326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 2336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(receiver); 2356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(value()); 2366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount actual(1); 2376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount expected(setter); 2386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, 2396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NullCallWrapper()); 2406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 2416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // If we generate a global code snippet for deoptimization only, remember 2426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // the place to continue after deoptimization. 2436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 2446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // We have to return the passed value, not the return value of the setter. 2476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ pop(eax); 2486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Restore context register. 2506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ ret(0); 2536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 2576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register holder, Register name, 2586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSObject> holder_obj) { 2596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 2606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); 2616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); 2626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); 2636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); 2646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(name); 2656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 2666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor)); 2676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register scratch = name; 2686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(scratch, Immediate(interceptor)); 2696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(scratch); 2706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(receiver); 2716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(holder); 2726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void CompileCallLoadPropertyWithInterceptor( 2766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Register receiver, Register holder, Register name, 2776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSObject> holder_obj, IC::UtilityId id) { 2786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 2796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), 2806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NamedLoadHandlerCompiler::kInterceptorArgsLength); 2816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void StoreIC_PushArgs(MacroAssembler* masm) { 2859aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 2869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 2879aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 2886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); 2906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ pop(ebx); 2926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(receiver); 2936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(name); 2946474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(value); 2956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(ebx); 2966474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { 3006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return address is on the stack. 3016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org StoreIC_PushArgs(masm); 3026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Do tail-call to runtime routine. 3046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ExternalReference ref(IC_Utility(IC::kStoreIC_Slow), masm->isolate()); 3056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ TailCallExternalReference(ref, 3, 1); 3066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 3076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) { 3106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return address is on the stack. 3116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org StoreIC_PushArgs(masm); 3126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Do tail-call to runtime routine. 3146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ExternalReference ref(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate()); 3156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ TailCallExternalReference(ref, 3, 1); 3163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} 3173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#undef __ 3203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define __ ACCESS_MASM(masm()) 3213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 3243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<Name> name) { 3253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (!label->is_unused()) { 3263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org __ bind(label); 3273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org __ mov(this->name(), Immediate(name)); 3283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 3293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} 3303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// store is successful. 3342b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreTransition( 3353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<Map> transition, Handle<Name> name, Register receiver_reg, 3363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Register storage_reg, Register value_reg, Register scratch1, 3373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Register scratch2, Register unused, Label* miss_label, Label* slow) { 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int descriptor = transition->LastAdded(); 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DescriptorArray* descriptors = transition->instance_descriptors(); 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PropertyDetails details = descriptors->GetDetails(descriptor); 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation representation = details.representation(); 342e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!representation.IsNone()); 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (details.type() == CONSTANT) { 3453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<Object> constant(descriptors->GetValue(descriptor), isolate()); 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObject(value_reg, constant); 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss_label); 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsSmi()) { 3496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsHeapObject()) { 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(value_reg, miss_label); 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HeapType* field_type = descriptors->GetFieldType(descriptor); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HeapType::Iterator<Map> it = field_type->Classes(); 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!it.Done()) { 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label do_store; 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (true) { 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CompareMap(value_reg, it.Current()); 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org it.Advance(); 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (it.Done()) { 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss_label); 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &do_store, Label::kNear); 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&do_store); 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsDouble()) { 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label do_store, heap_number; 36958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE); 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(value_reg); 3736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Cvtsi2sd(xmm0, value_reg); 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(value_reg); 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&do_store); 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&heap_number); 3783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label, 3793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org DONT_DO_SMI_CHECK); 3806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&do_store); 3836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Stub never generated for objects that require access checks. 387e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!transition->is_access_check_needed()); 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform map transition for the receiver if necessary. 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (details.type() == FIELD && 3917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The properties must be extended before we can store the value. 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We jump to a runtime call that extends the properties array. 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(scratch1); // Return address. 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(receiver_reg); 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(transition)); 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(value_reg); 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch1); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference( 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 4013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org isolate()), 4023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3, 1); 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the map of the object. 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch1, Immediate(transition)); 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the map field. 4116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2, 4126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (details.type() == CONSTANT) { 415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value_reg.is(eax)); 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int index = transition->instance_descriptors()->GetFieldIndex( 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org transition->LastAdded()); 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Adjust for the number of properties stored in the object. Even in the 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // face of a transition we can use the old map here because the size of the 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object and the number of in-object properties is not going to change. 4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org index -= transition->inobject_properties(); 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org SmiCheck smi_check = 4296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(verwaest): Share this code as a code stub. 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index < 0) { 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set the property straight into the object. 4337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int offset = transition->instance_size() + (index * kPointerSize); 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (representation.IsDouble()) { 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(receiver_reg, offset), storage_reg); 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(receiver_reg, offset), value_reg); 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsSmi()) { 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the array address. 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsDouble()) { 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(storage_reg, value_reg); 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1, 4466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Write to the properties array. 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the properties array (optimistically). 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (representation.IsDouble()) { 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(scratch1, offset), storage_reg); 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(scratch1, offset), value_reg); 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsSmi()) { 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the array address. 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsDouble()) { 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(storage_reg, value_reg); 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg, 4656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the value (register eax). 470e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value_reg.is(eax)); 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 475a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, 4769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Register value_reg, 4779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Label* miss_label) { 4789d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(lookup->representation().IsHeapObject()); 4799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ JumpIfSmi(value_reg, miss_label); 4809d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes(); 4819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Label do_store; 4829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (true) { 4839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ CompareMap(value_reg, it.Current()); 4849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org it.Advance(); 4859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org if (it.Done()) { 4869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ j(not_equal, miss_label); 4879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org break; 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ j(equal, &do_store, Label::kNear); 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4918640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org __ bind(&do_store); 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 4949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org lookup->representation()); 4959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org GenerateTailCall(masm(), stub.GetCode()); 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4992b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgRegister PropertyHandlerCompiler::CheckPrototypes( 5007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register object_reg, Register holder_reg, Register scratch1, 5017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register scratch2, Handle<Name> name, Label* miss, 5027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org PrototypeCheckType check) { 5037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Make sure there's no overlap between holder and object registers. 506e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 5076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 5086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org !scratch2.is(scratch1)); 509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Keep track of the current object in register reg. 511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = object_reg; 512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int depth = 0; 513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSObject> current = Handle<JSObject>::null(); 5157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (type()->IsConstant()) 5167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSObject> prototype = Handle<JSObject>::null(); 518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> current_map = receiver_map; 5197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Map> holder_map(holder()->map()); 520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Traverse the prototype chain and check the maps in the prototype chain for 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // fast and global objects or do negative lookup for normal objects. 522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (!current_map.is_identical_to(holder_map)) { 523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ++depth; 524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Only global objects and objects that do not require access 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // checks are allowed in stubs. 527e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current_map->IsJSGlobalProxyMap() || 528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !current_map->is_access_check_needed()); 529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org prototype = handle(JSObject::cast(current_map->prototype())); 531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_map->is_dictionary_map() && 5323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org !current_map->IsJSGlobalObjectMap()) { 5333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!name->IsUniqueName()) { 535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(name->IsString()); 536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org name = factory()->InternalizeString(Handle<String>::cast(name)); 537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 538e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current.is_null() || 539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current->property_dictionary()->FindEntry(name) == 5406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NameDictionary::kNotFound); 541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 5436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org scratch2); 544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reg = holder_reg; // From now on the object will be in holder_reg. 547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool in_new_space = heap()->InNewSpace(*prototype); 550d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // Two possible reasons for loading the prototype from the map: 551d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // (1) Can't store references to new space in code. 552d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // (2) Handler is shared for all receivers with the same prototype 553d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // map (but not necessarily the same prototype instance). 554d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org bool load_prototype_from_map = in_new_space || depth == 1; 555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (depth != 1 || check == CHECK_ALL_MAPS) { 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check access rights to the global object. This has to happen after 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the map check so that we know that the object is actually a global 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object. 5623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // This allows us to install generated handlers for accesses to the 5633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // global proxy (as opposed to using slow ICs). See corresponding code 5643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // in LookupForRead(). 565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); 567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (current_map->IsJSGlobalObjectMap()) { 5686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 5696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org name, scratch2, miss); 570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 572d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org if (load_prototype_from_map) { 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save the map in scratch1 for later. 574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reg = holder_reg; // From now on the object will be in holder_reg. 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 579d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org if (load_prototype_from_map) { 580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(reg, prototype); 583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Go to the next object in the prototype chain. 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current = prototype; 588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current_map = handle(current->map()); 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Log the check depth. 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (depth != 0 || check == CHECK_ALL_MAPS) { 595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the holder map. 596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform security check for access to the global object. 600e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current_map->IsJSGlobalProxyMap() || 601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !current_map->is_access_check_needed()); 602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); 604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the register containing the holder. 607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return reg; 608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6112b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!miss->is_unused()) { 613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label success; 614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&success); 615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(miss); 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&success); 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6222b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!miss->is_unused()) { 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label success; 625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&success); 6263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org GenerateRestoreName(miss, name); 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&success); 629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6332b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadCallback( 6342b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Register reg, Handle<ExecutableAccessorInfo> callback) { 635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Insert additional parameters into the stack frame above return address. 636e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch3().is(reg)); 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(scratch3()); // Get return address to place it below. 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(receiver()); // receiver 646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push data from ExecutableAccessorInfo. 647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (isolate()->heap()->InNewSpace(callback->data())) { 648e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch2().is(reg)); 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch2(), Immediate(callback)); 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(FieldOperand(scratch2(), ExecutableAccessorInfo::kDataOffset)); 651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Handle<Object>(callback->data(), isolate()))); 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); // ReturnValue 655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ReturnValue default value 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(reinterpret_cast<int>(isolate()))); 658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(reg); // holder 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save a pointer to where we pushed the arguments. This will be 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // passed as the const PropertyAccessorInfo& to the C++ callback. 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esp); 663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(name()); // name 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch3()); // Restore return address. 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abi for CallApiGetter 6696313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Register getter_address = ApiGetterDescriptor::function_address(); 670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address function_address = v8::ToCData<Address>(callback->getter()); 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(getter_address, Immediate(function_address)); 672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallApiGetterStub stub(isolate()); 674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallStub(&stub); 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6782b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the constant value. 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadObject(eax, value); 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( 6865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org LookupIterator* it, Register holder_reg) { 687e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(holder()->HasNamedInterceptor()); 688e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Compile the interceptor call, followed by inline code to load the 6915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // property from further up the prototype chain if the call fails. 6925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Check that the maps haven't changed. 6935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 6945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 6955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Preserve the receiver register explicitly whenever it is different from the 6965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // holder and it is needed should the interceptor return without any result. 6975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD 6985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // case might cause a miss during the prototype check. 6995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org bool must_perform_prototype_check = 7005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org !holder().is_identical_to(it->GetHolder<JSObject>()); 7015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org bool must_preserve_receiver_reg = 7025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org !receiver().is(holder_reg) && 7031af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check); 7045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Save necessary data before invoking an interceptor. 7065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Requires a frame to make GC aware of pushed pointers. 7075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org { 7085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org FrameScope frame_scope(masm(), StackFrame::INTERNAL); 7095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (must_preserve_receiver_reg) { 7115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ push(receiver()); 712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 7135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ push(holder_reg); 7145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ push(this->name()); 7155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Invoke an interceptor. Note: map checks from receiver to 7175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // interceptor's holder has been compiled before (see a caller 7185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // of this method.) 7195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 7205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org masm(), receiver(), holder_reg, this->name(), holder(), 7215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 7225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Check if interceptor provided a value for property. If it's 7245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // the case, return immediately. 7255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org Label interceptor_failed; 7265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ cmp(eax, factory()->no_interceptor_result_sentinel()); 7275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ j(equal, &interceptor_failed); 7285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org frame_scope.GenerateLeaveFrame(); 7295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ ret(0); 730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Clobber registers when generating debug-code to provoke errors. 7325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ bind(&interceptor_failed); 7335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (FLAG_debug_code) { 734e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue))); 735e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue))); 736e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue))); 7375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } 738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ pop(this->name()); 7405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ pop(holder_reg); 7415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (must_preserve_receiver_reg) { 7425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ pop(receiver()); 743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Leave the internal frame. 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 7475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org GenerateLoadPostInterceptor(it, holder_reg); 7495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org} 7505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 7535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(holder()->HasNamedInterceptor()); 7545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 7555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Call the runtime system to load the interceptor. 7565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ pop(scratch2()); // save old return address 7575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), 7585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org holder()); 7595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ push(scratch2()); // restore old return address 7605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org ExternalReference ref = ExternalReference( 7625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 7635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ TailCallExternalReference( 7645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7682b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 7697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSObject> object, Handle<Name> name, 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<ExecutableAccessorInfo> callback) { 7717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register holder_reg = Frontend(receiver(), name); 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(scratch1()); // remove the return address 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(receiver()); 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(holder_reg); 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(callback); 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(name); 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(value()); 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch1()); // restore return address 780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do tail-call to the runtime system. 782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference store_callback_property = 783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(store_callback_property, 5, 1); 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the generated code. 787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetCode(kind(), Code::FAST, name); 788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7912b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgHandle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 7927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Name> name) { 793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(scratch1()); // remove the return address 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(receiver()); 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(this->name()); 796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(value()); 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(scratch1()); // restore return address 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do tail-call to the runtime system. 800f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org ExternalReference store_ic_property = ExternalReference( 801f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(store_ic_property, 3, 1); 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the generated code. 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetCode(kind(), Code::FAST, name); 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 809fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgRegister NamedStoreHandlerCompiler::value() { 8109aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return StoreDescriptor::ValueRegister(); 811fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org} 8122b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org 8132b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org 8142b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgHandle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 8153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label miss; 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 8187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FrontendHeader(receiver(), name, &miss); 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the value from the cell. 8209aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register result = StoreDescriptor::ValueRegister(); 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (masm()->serializer_enabled()) { 8227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(result, Immediate(cell)); 8237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 8257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(result, Operand::ForCell(cell)); 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for deleted property if property can actually be deleted. 829e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (is_configurable) { 8307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cmp(result, factory()->the_hole_value()); 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &miss); 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (FLAG_debug_code) { 8337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cmp(result, factory()->the_hole_value()); 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Counters* counters = isolate()->counters(); 838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->named_load_global_stub(), 1); 839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The code above already loads the result into the return register. 840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 8422b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org FrontendFooter(name, &miss); 843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the generated code. 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetCode(kind(), Code::NORMAL, name); 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 8516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} // namespace v8::internal 852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 8536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#endif // V8_TARGET_ARCH_IA32 854