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_X64 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 96474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/call-optimization.h" 106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h" 116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@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 182b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 192b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, Label* miss_label, Register receiver, 202b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Handle<Name> name, Register scratch0, Register scratch1) { 21e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(name->IsUniqueName()); 22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!receiver.is(scratch0)); 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Counters* counters = masm->isolate()->counters(); 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->negative_lookups(), 1); 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->negative_lookups_miss(), 1); 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kInterceptorOrAccessCheckNeededMask = 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Bail out if the receiver has a named interceptor or requires access checks. 336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ testb(FieldOperand(scratch0, Map::kBitFieldOffset), 346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Immediate(kInterceptorOrAccessCheckNeededMask)); 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, miss_label); 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that receiver is a JSObject. 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE); 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, miss_label); 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load properties array. 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register properties = scratch0; 436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the properties array is a dictionary. 466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), 476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Heap::kHashTableMapRootIndex); 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss_label); 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done, 526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org properties, name, scratch1); 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ DecrementCounter(counters->negative_lookups_miss(), 1); 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 582b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 592b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, int index, Register prototype, Label* miss) { 606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Isolate* isolate = masm->isolate(); 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the global function with the given index. 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction> function( 636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org JSFunction::cast(isolate->native_context()->get(index))); 646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check we're still in the same context. 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = prototype; 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(scratch, Operand(rsi, offset)); 696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Cmp(Operand(scratch, Context::SlotOffset(index)), function); 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss); 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load its initial map. The global functions all have initial maps. 746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(prototype, Handle<Map>(function->initial_map())); 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the prototype from the initial map. 766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 802b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Register receiver, Register result, Register scratch, 826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Label* miss_label) { 836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ TryGetFunctionPrototype(receiver, result, miss_label); 846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (!result.is(rax)) __ movp(rax, result); 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register holder, Register name, 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSObject> holder_obj) { 92f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 93f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); 94f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); 95f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); 96f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); 976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(name); 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 99e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor)); 1006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(kScratchRegister, interceptor); 1016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(kScratchRegister); 1026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver); 1036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(holder); 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic void CompileCallLoadPropertyWithInterceptor( 1086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Register receiver, Register holder, Register name, 1096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSObject> holder_obj, IC::UtilityId id) { 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 111f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), 112f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org NamedLoadHandlerCompiler::kInterceptorArgsLength); 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate call to api function. 1172b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateFastApiCall( 1182b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, const CallOptimization& optimization, 1192b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Handle<Map> receiver_map, Register receiver, Register scratch_in, 1202b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org bool is_store, int argc, Register* values) { 1216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(optimization.is_simple_api_call()); 1226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 1236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(scratch_in); 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // receiver 1256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver); 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Write the arguments to stack frame. 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < argc; i++) { 1286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register arg = values[argc - 1 - i]; 129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!receiver.is(arg)); 130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch_in.is(arg)); 1316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(arg); 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(scratch_in); 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Stack now matches JSFunction abi. 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abi for CallApiFunctionStub. 1376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register callee = rax; 1386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register call_data = rbx; 1396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register holder = rcx; 1406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register api_function_address = rdx; 1416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register scratch = rdi; // scratch_in is no longer valid. 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put holder in place. 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallOptimization::HolderLookup holder_lookup; 1456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSObject> api_holder = 1466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (holder_lookup) { 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CallOptimization::kHolderIsReceiver: 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(holder, receiver); 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CallOptimization::kHolderFound: 1526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(holder, api_holder); 1536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org break; 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CallOptimization::kHolderNotFound: 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Isolate* isolate = masm->isolate(); 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction> function = optimization.constant_function(); 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> call_data_obj(api_call_info->data(), isolate); 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put callee in place. 1656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(callee, function); 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool call_data_undefined = false; 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put call_data in place. 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (isolate->heap()->InNewSpace(*call_data_obj)) { 1706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(scratch, api_call_info); 1716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset)); 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (call_data_obj->IsUndefined()) { 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org call_data_undefined = true; 1746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(call_data, call_data_obj); 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put api_function_address in place. 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address function_address = v8::ToCData<Address>(api_call_info->callback()); 1816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(api_function_address, function_address, 1826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org RelocInfo::EXTERNAL_REFERENCE); 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump to stub. 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallStub(&stub); 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1902b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateCheckPropertyCell( 1912b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 1922b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Register scratch, Label* miss) { 1936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 194e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cell->value()->IsTheHole()); 1956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(scratch, cell); 1966474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 1976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org masm->isolate()->factory()->the_hole_value()); 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss); 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreViaSetter( 2036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Handle<HeapType> type, Register receiver, 2046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSFunction> setter) { 2056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // ----------- S t a t e ------------- 2066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // -- rsp[0] : return address 2076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // ----------------------------------- 2086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org { 2096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Save value register, so we can restore it later. 2126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(value()); 2136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (!setter.is_null()) { 2156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Call the JavaScript setter with receiver and value on the stack. 2166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 2176474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Swap in the global receiver. 2186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(receiver, 2196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 2206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver); 2226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(value()); 2236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount actual(1); 2246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount expected(setter); 2256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, 2266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NullCallWrapper()); 2276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 2286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // If we generate a global code snippet for deoptimization only, remember 2296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // the place to continue after deoptimization. 2306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 2316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // We have to return the passed value, not the return value of the setter. 2346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Pop(rax); 2356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Restore context register. 2376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ ret(0); 2406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadViaGetter( 2446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MacroAssembler* masm, Handle<HeapType> type, Register receiver, 2456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<JSFunction> getter) { 2466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // ----------- S t a t e ------------- 2476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // -- rax : receiver 2486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // -- rcx : name 2496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // -- rsp[0] : return address 2506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // ----------------------------------- 2516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org { 2526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (!getter.is_null()) { 2556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Call the JavaScript getter with the receiver on the stack. 2566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 2576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Swap in the global receiver. 2586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(receiver, 2596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 2606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver); 2626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount actual(0); 2636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ParameterCount expected(getter); 2646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, 2656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NullCallWrapper()); 2666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 2676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // If we generate a global code snippet for deoptimization only, remember 2686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // the place to continue after deoptimization. 2696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 2706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Restore context register. 2736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 2756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ ret(0); 2766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void StoreIC_PushArgs(MacroAssembler* masm) { 2809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 2819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 2829aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 2836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value)); 2856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2866474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(rbx); 2876474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver); 2886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(name); 2896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(value); 2906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(rbx); 2916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 2926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2946474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { 2956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return address is on the stack. 2966474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org StoreIC_PushArgs(masm); 2976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Do tail-call to runtime routine. 2996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ExternalReference ref(IC_Utility(IC::kStoreIC_Slow), masm->isolate()); 3006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ TailCallExternalReference(ref, 3, 1); 3016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 3026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) { 3056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return address is on the stack. 3066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org StoreIC_PushArgs(masm); 3076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 3086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Do tail-call to runtime routine. 3096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ExternalReference ref(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate()); 3106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ TailCallExternalReference(ref, 3, 1); 3113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} 3123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#undef __ 3156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#define __ ACCESS_MASM((masm())) 3163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 3193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<Name> name) { 3203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (!label->is_unused()) { 3213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org __ bind(label); 3226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(this->name(), name); 3233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 3243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} 3253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// store is successful. 3292b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreTransition( 3303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<Map> transition, Handle<Name> name, Register receiver_reg, 3313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Register storage_reg, Register value_reg, Register scratch1, 3323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Register scratch2, Register unused, Label* miss_label, Label* slow) { 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int descriptor = transition->LastAdded(); 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DescriptorArray* descriptors = transition->instance_descriptors(); 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PropertyDetails details = descriptors->GetDetails(descriptor); 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation representation = details.representation(); 337e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!representation.IsNone()); 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (details.type() == CONSTANT) { 3403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<Object> constant(descriptors->GetValue(descriptor), isolate()); 3416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Cmp(value_reg, constant); 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss_label); 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsSmi()) { 3446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsHeapObject()) { 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(value_reg, miss_label); 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HeapType* field_type = descriptors->GetFieldType(descriptor); 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HeapType::Iterator<Map> it = field_type->Classes(); 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!it.Done()) { 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label do_store; 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (true) { 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CompareMap(value_reg, it.Current()); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org it.Advance(); 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (it.Done()) { 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, miss_label); 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &do_store, Label::kNear); 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&do_store); 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsDouble()) { 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label do_store, heap_number; 3646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE); 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 3676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ SmiToInteger32(scratch1, value_reg); 3686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Cvtlsi2sd(xmm0, scratch1); 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&do_store); 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&heap_number); 3723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label, 3733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org DONT_DO_SMI_CHECK); 3746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&do_store); 3776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Stub never generated for objects that require access checks. 381e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!transition->is_access_check_needed()); 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform map transition for the receiver if necessary. 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (details.type() == FIELD && 3857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The properties must be extended before we can store the value. 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We jump to a runtime call that extends the properties array. 3886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(scratch1); 3896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver_reg); 3906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(transition); 3916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(value_reg); 3926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(scratch1); 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference( 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 3953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org isolate()), 3963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 3, 1); 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the map of the object. 4016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(scratch1, transition); 4026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the map field. 4056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2, 4066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (details.type() == CONSTANT) { 4096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(value_reg.is(rax)); 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int index = transition->instance_descriptors()->GetFieldIndex( 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org transition->LastAdded()); 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Adjust for the number of properties stored in the object. Even in the 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // face of a transition we can use the old map here because the size of the 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object and the number of in-object properties is not going to change. 4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org index -= transition->inobject_properties(); 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(verwaest): Share this code as a code stub. 4236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org SmiCheck smi_check = 4246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index < 0) { 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set the property straight into the object. 4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int offset = transition->instance_size() + (index * kPointerSize); 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (representation.IsDouble()) { 4296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(FieldOperand(receiver_reg, offset), storage_reg); 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(FieldOperand(receiver_reg, offset), value_reg); 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsSmi()) { 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the array address. 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsDouble()) { 4376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(storage_reg, value_reg); 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1, 4406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Write to the properties array. 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the properties array (optimistically). 4466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (representation.IsDouble()) { 4486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(FieldOperand(scratch1, offset), storage_reg); 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(FieldOperand(scratch1, offset), value_reg); 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsSmi()) { 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the array address. 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!representation.IsDouble()) { 4566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(storage_reg, value_reg); 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg, 4596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return the value (register rax). 4646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(value_reg.is(rax)); 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 469a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, 4709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Register value_reg, 4719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Label* miss_label) { 4729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(lookup->representation().IsHeapObject()); 4739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ JumpIfSmi(value_reg, miss_label); 4749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes(); 4759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Label do_store; 4769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org while (true) { 4779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ CompareMap(value_reg, it.Current()); 4789d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org it.Advance(); 4799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org if (it.Done()) { 4809d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ j(not_equal, miss_label); 4819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org break; 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org __ j(equal, &do_store, Label::kNear); 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4858640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org __ bind(&do_store); 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 4889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org lookup->representation()); 4899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org GenerateTailCall(masm(), stub.GetCode()); 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4932b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgRegister PropertyHandlerCompiler::CheckPrototypes( 4947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register object_reg, Register holder_reg, Register scratch1, 4957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register scratch2, Handle<Name> name, Label* miss, 4967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org PrototypeCheckType check) { 4977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Make sure there's no overlap between holder and object registers. 500e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 5016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 5026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org !scratch2.is(scratch1)); 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Keep track of the current object in register reg. On the first 5056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // iteration, reg is an alias for object_reg, on later iterations, 5066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // it is an alias for holder_reg. 507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = object_reg; 508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int depth = 0; 509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSObject> current = Handle<JSObject>::null(); 5116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (type()->IsConstant()) { 5127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 5136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSObject> prototype = Handle<JSObject>::null(); 515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> current_map = receiver_map; 5167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Map> holder_map(holder()->map()); 517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Traverse the prototype chain and check the maps in the prototype chain for 518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // fast and global objects or do negative lookup for normal objects. 519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (!current_map.is_identical_to(holder_map)) { 520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ++depth; 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Only global objects and objects that do not require access 523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // checks are allowed in stubs. 524e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current_map->IsJSGlobalProxyMap() || 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !current_map->is_access_check_needed()); 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org prototype = handle(JSObject::cast(current_map->prototype())); 528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_map->is_dictionary_map() && 5293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org !current_map->IsJSGlobalObjectMap()) { 5303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!name->IsUniqueName()) { 532e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(name->IsString()); 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org name = factory()->InternalizeString(Handle<String>::cast(name)); 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current.is_null() || 536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current->property_dictionary()->FindEntry(name) == 5376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NameDictionary::kNotFound); 538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 5406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org scratch2); 541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reg = holder_reg; // From now on the object will be in holder_reg. 5446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool in_new_space = heap()->InNewSpace(*prototype); 547d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // Two possible reasons for loading the prototype from the map: 548d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // (1) Can't store references to new space in code. 549d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // (2) Handler is shared for all receivers with the same prototype 550d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org // map (but not necessarily the same prototype instance). 551d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org bool load_prototype_from_map = in_new_space || depth == 1; 5526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (load_prototype_from_map) { 5536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Save the map in scratch1 for later. 5546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 5556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (depth != 1 || check == CHECK_ALL_MAPS) { 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check access rights to the global object. This has to happen after 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the map check so that we know that the object is actually a global 562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object. 5633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // This allows us to install generated handlers for accesses to the 5643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // global proxy (as opposed to using slow ICs). See corresponding code 5653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // in LookupForRead(). 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 5676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CheckAccessGlobalProxy(reg, scratch2, miss); 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (current_map->IsJSGlobalObjectMap()) { 5696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 5706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org name, scratch2, miss); 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reg = holder_reg; // From now on the object will be in holder_reg. 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 574d35a295c4172547d6718e2ae3816fadfaef0311dmachenbach@chromium.org if (load_prototype_from_map) { 5756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(reg, prototype); 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Go to the next object in the prototype chain. 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current = prototype; 583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current_map = handle(current->map()); 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Log the check depth. 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (depth != 0 || check == CHECK_ALL_MAPS) { 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the holder map. 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform security check for access to the global object. 595e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(current_map->IsJSGlobalProxyMap() || 596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !current_map->is_access_check_needed()); 597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 5986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CheckAccessGlobalProxy(reg, scratch1, miss); 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the register containing the holder. 602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return reg; 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6062b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!miss->is_unused()) { 608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label success; 609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&success); 610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(miss); 611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&success); 613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6172b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!miss->is_unused()) { 619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label success; 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&success); 6213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org GenerateRestoreName(miss, name); 622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&success); 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6282b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadCallback( 6292b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Register reg, Handle<ExecutableAccessorInfo> callback) { 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Insert additional parameters into the stack frame above return address. 6316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!scratch4().is(reg)); 6326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(scratch4()); 633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 6406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 6416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver()); // receiver 6426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (heap()->InNewSpace(callback->data())) { 643e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch2().is(reg)); 6446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(scratch2(), callback); 6456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(FieldOperand(scratch2(), 6466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ExecutableAccessorInfo::kDataOffset)); // data 647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 6486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(Handle<Object>(callback->data(), isolate())); 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(!kScratchRegister.is(reg)); 6516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 6526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(kScratchRegister); // return value 6536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(kScratchRegister); // return value default 6546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushAddress(ExternalReference::isolate_address(isolate())); 6556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(reg); // holder 6566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(name()); // name 6576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Save a pointer to where we pushed the arguments pointer. This will be 658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // passed as the const PropertyAccessorInfo& to the C++ callback. 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(scratch4()); 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Abi for CallApiGetter 6636313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Register api_function_address = ApiGetterDescriptor::function_address(); 6646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Address getter_address = v8::ToCData<Address>(callback->getter()); 6656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE); 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallApiGetterStub stub(isolate()); 668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallStub(&stub); 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6722b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the constant value. 6746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(rax, value); 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( 6805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org LookupIterator* it, Register holder_reg) { 681e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(holder()->HasNamedInterceptor()); 682e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Compile the interceptor call, followed by inline code to load the 6855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // property from further up the prototype chain if the call fails. 6865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Check that the maps haven't changed. 6875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 6885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 6895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Preserve the receiver register explicitly whenever it is different from the 6905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // holder and it is needed should the interceptor return without any result. 6915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD 6925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // case might cause a miss during the prototype check. 6935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org bool must_perform_prototype_check = 6945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org !holder().is_identical_to(it->GetHolder<JSObject>()); 6955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org bool must_preserve_receiver_reg = 6965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org !receiver().is(holder_reg) && 6971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check); 6985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 6995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Save necessary data before invoking an interceptor. 7005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Requires a frame to make GC aware of pushed pointers. 7015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org { 7025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org FrameScope frame_scope(masm(), StackFrame::INTERNAL); 7035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (must_preserve_receiver_reg) { 7056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver()); 706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 7076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(holder_reg); 7086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(this->name()); 7095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Invoke an interceptor. Note: map checks from receiver to 7115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // interceptor's holder has been compiled before (see a caller 7125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // of this method.) 7135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 7145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org masm(), receiver(), holder_reg, this->name(), holder(), 7155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 7165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Check if interceptor provided a value for property. If it's 7185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // the case, return immediately. 7195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org Label interceptor_failed; 7206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 7215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ j(equal, &interceptor_failed); 7225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org frame_scope.GenerateLeaveFrame(); 7235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ ret(0); 724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ bind(&interceptor_failed); 7266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Pop(this->name()); 7276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Pop(holder_reg); 7285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (must_preserve_receiver_reg) { 7296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Pop(receiver()); 730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Leave the internal frame. 733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 7345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org GenerateLoadPostInterceptor(it, holder_reg); 7365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org} 7375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 7406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Call the runtime system to load the interceptor. 7415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(holder()->HasNamedInterceptor()); 7425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 7436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(scratch2()); 7445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), 7455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org holder()); 7466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(scratch2()); 7475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 7485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org ExternalReference ref = ExternalReference( 7495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 7505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ TailCallExternalReference( 7515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7552b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 7567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<JSObject> object, Handle<Name> name, 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<ExecutableAccessorInfo> callback) { 7587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register holder_reg = Frontend(receiver(), name); 759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(scratch1()); 7616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver()); 7626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(holder_reg); 7636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(callback); // callback info 764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(name); 7656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(value()); 7666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(scratch1()); 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do tail-call to the runtime system. 769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference store_callback_property = 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(store_callback_property, 5, 1); 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the generated code. 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetCode(kind(), Code::FAST, name); 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7782b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgHandle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 7797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<Name> name) { 7806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PopReturnAddressTo(scratch1()); 7816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(receiver()); 7826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(this->name()); 7836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Push(value()); 7846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ PushReturnAddressFrom(scratch1()); 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do tail-call to the runtime system. 787f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org ExternalReference store_ic_property = ExternalReference( 788f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TailCallExternalReference(store_ic_property, 3, 1); 790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the generated code. 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetCode(kind(), Code::FAST, name); 793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 796fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgRegister NamedStoreHandlerCompiler::value() { 7979aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return StoreDescriptor::ValueRegister(); 798fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org} 7992b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org 8002b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org 8012b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.orgHandle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 8023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label miss; 8047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FrontendHeader(receiver(), name, &miss); 8056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the value from the cell. 8079aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register result = StoreDescriptor::ValueRegister(); 8086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(result, cell); 8096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for deleted property if property can actually be deleted. 812e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (is_configurable) { 8136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &miss); 815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (FLAG_debug_code) { 8166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Counters* counters = isolate()->counters(); 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IncrementCounter(counters->named_load_global_stub(), 1); 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); 823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 8242b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org FrontendFooter(name, &miss); 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the generated code. 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetCode(kind(), Code::NORMAL, name); 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 8336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} // namespace v8::internal 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 8356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#endif // V8_TARGET_ARCH_X64 836