ic-compiler-x87.cc revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/v8.h" 6 7#if V8_TARGET_ARCH_X87 8 9#include "src/ic/ic.h" 10#include "src/ic/ic-compiler.h" 11 12namespace v8 { 13namespace internal { 14 15#define __ ACCESS_MASM(masm) 16 17 18void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm, 19 StrictMode strict_mode) { 20 // Return address is on the stack. 21 DCHECK(!ebx.is(StoreDescriptor::ReceiverRegister()) && 22 !ebx.is(StoreDescriptor::NameRegister()) && 23 !ebx.is(StoreDescriptor::ValueRegister())); 24 __ pop(ebx); 25 __ push(StoreDescriptor::ReceiverRegister()); 26 __ push(StoreDescriptor::NameRegister()); 27 __ push(StoreDescriptor::ValueRegister()); 28 __ push(Immediate(Smi::FromInt(strict_mode))); 29 __ push(ebx); // return address 30 31 // Do tail-call to runtime routine. 32 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); 33} 34 35 36#undef __ 37#define __ ACCESS_MASM(masm()) 38 39Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, 40 CodeHandleList* handlers, 41 Handle<Name> name, 42 Code::StubType type, 43 IcCheckType check) { 44 Label miss; 45 46 if (check == PROPERTY && 47 (kind() == Code::KEYED_STORE_IC || kind() == Code::KEYED_LOAD_IC)) { 48 // In case we are compiling an IC for dictionary loads or stores, just 49 // check whether the name is unique. 50 if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) { 51 // Keyed loads with dictionaries shouldn't be here, they go generic. 52 // The DCHECK is to protect assumptions when --vector-ics is on. 53 DCHECK(kind() != Code::KEYED_LOAD_IC); 54 Register tmp = scratch1(); 55 __ JumpIfSmi(this->name(), &miss); 56 __ mov(tmp, FieldOperand(this->name(), HeapObject::kMapOffset)); 57 __ movzx_b(tmp, FieldOperand(tmp, Map::kInstanceTypeOffset)); 58 __ JumpIfNotUniqueNameInstanceType(tmp, &miss); 59 } else { 60 __ cmp(this->name(), Immediate(name)); 61 __ j(not_equal, &miss); 62 } 63 } 64 65 Label number_case; 66 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 67 __ JumpIfSmi(receiver(), smi_target); 68 69 // Polymorphic keyed stores may use the map register 70 Register map_reg = scratch1(); 71 DCHECK(kind() != Code::KEYED_STORE_IC || 72 map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister())); 73 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 74 int receiver_count = types->length(); 75 int number_of_handled_maps = 0; 76 for (int current = 0; current < receiver_count; ++current) { 77 Handle<HeapType> type = types->at(current); 78 Handle<Map> map = IC::TypeToMap(*type, isolate()); 79 if (!map->is_deprecated()) { 80 number_of_handled_maps++; 81 Handle<WeakCell> cell = Map::WeakCellForMap(map); 82 __ CmpWeakValue(map_reg, cell, scratch2()); 83 if (type->Is(HeapType::Number())) { 84 DCHECK(!number_case.is_unused()); 85 __ bind(&number_case); 86 } 87 __ j(equal, handlers->at(current)); 88 } 89 } 90 DCHECK(number_of_handled_maps != 0); 91 92 __ bind(&miss); 93 TailCallBuiltin(masm(), MissBuiltin(kind())); 94 95 // Return the generated code. 96 InlineCacheState state = 97 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 98 return GetCode(kind(), type, name, state); 99} 100 101 102Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 103 MapHandleList* receiver_maps, CodeHandleList* handler_stubs, 104 MapHandleList* transitioned_maps) { 105 Label miss; 106 __ JumpIfSmi(receiver(), &miss, Label::kNear); 107 Register map_reg = scratch1(); 108 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 109 for (int i = 0; i < receiver_maps->length(); ++i) { 110 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i)); 111 __ CmpWeakValue(map_reg, cell, scratch2()); 112 if (transitioned_maps->at(i).is_null()) { 113 __ j(equal, handler_stubs->at(i)); 114 } else { 115 Label next_map; 116 __ j(not_equal, &next_map, Label::kNear); 117 Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i)); 118 __ LoadWeakValue(transition_map(), cell, &miss); 119 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); 120 __ bind(&next_map); 121 } 122 } 123 __ bind(&miss); 124 TailCallBuiltin(masm(), MissBuiltin(kind())); 125 126 // Return the generated code. 127 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 128} 129 130 131#undef __ 132} 133} // namespace v8::internal 134 135#endif // V8_TARGET_ARCH_X87 136