| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/ic/call-optimization.h" | 7 #include "src/ic/call-optimization.h" |
| 8 #include "src/ic/handler-compiler.h" | 8 #include "src/ic/handler-compiler.h" |
| 9 #include "src/ic/ic.h" | 9 #include "src/ic/ic.h" |
| 10 #include "src/ic/ic-inl.h" | 10 #include "src/ic/ic-inl.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 | 15 |
| 16 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, | 16 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, |
| 17 Handle<Map> stub_holder, | 17 Handle<Map> stub_holder, |
| 18 Code::Kind kind, | 18 Code::Kind kind, |
| 19 CacheHolderFlag cache_holder, | 19 CacheHolderFlag cache_holder, |
| 20 Code::StubType type) { | 20 Code::StubType type) { |
| 21 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); | 21 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); |
| 22 Object* probe = stub_holder->FindInCodeCache(*name, flags); | 22 Object* probe = stub_holder->FindInCodeCache(*name, flags); |
| 23 if (probe->IsCode()) return handle(Code::cast(probe)); | 23 if (probe->IsCode()) return handle(Code::cast(probe)); |
| 24 return Handle<Code>::null(); | 24 return Handle<Code>::null(); |
| 25 } | 25 } |
| 26 | 26 |
| 27 | 27 |
| 28 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent( | 28 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent( |
| 29 Handle<Name> name, Handle<HeapType> type) { | 29 Handle<Name> name, Handle<Map> receiver_map) { |
| 30 Isolate* isolate = name->GetIsolate(); | 30 Isolate* isolate = name->GetIsolate(); |
| 31 Handle<Map> receiver_map = IC::TypeToMap(*type, isolate); | |
| 32 if (receiver_map->prototype()->IsNull()) { | 31 if (receiver_map->prototype()->IsNull()) { |
| 33 // TODO(jkummerow/verwaest): If there is no prototype and the property | 32 // TODO(jkummerow/verwaest): If there is no prototype and the property |
| 34 // is nonexistent, introduce a builtin to handle this (fast properties | 33 // is nonexistent, introduce a builtin to handle this (fast properties |
| 35 // -> return undefined, dictionary properties -> do negative lookup). | 34 // -> return undefined, dictionary properties -> do negative lookup). |
| 36 return Handle<Code>(); | 35 return Handle<Code>(); |
| 37 } | 36 } |
| 38 CacheHolderFlag flag; | 37 CacheHolderFlag flag; |
| 39 Handle<Map> stub_holder_map = | 38 Handle<Map> stub_holder_map = |
| 40 IC::GetHandlerCacheHolder(*type, false, isolate, &flag); | 39 IC::GetHandlerCacheHolder(receiver_map, false, isolate, &flag); |
| 41 | 40 |
| 42 // If no dictionary mode objects are present in the prototype chain, the load | 41 // If no dictionary mode objects are present in the prototype chain, the load |
| 43 // nonexistent IC stub can be shared for all names for a given map and we use | 42 // nonexistent IC stub can be shared for all names for a given map and we use |
| 44 // the empty string for the map cache in that case. If there are dictionary | 43 // the empty string for the map cache in that case. If there are dictionary |
| 45 // mode objects involved, we need to do negative lookups in the stub and | 44 // mode objects involved, we need to do negative lookups in the stub and |
| 46 // therefore the stub will be specific to the name. | 45 // therefore the stub will be specific to the name. |
| 47 Handle<Name> cache_name = | 46 Handle<Name> cache_name = |
| 48 receiver_map->is_dictionary_map() | 47 receiver_map->is_dictionary_map() |
| 49 ? name | 48 ? name |
| 50 : Handle<Name>::cast(isolate->factory()->nonexistent_symbol()); | 49 : Handle<Name>::cast(isolate->factory()->nonexistent_symbol()); |
| 51 Handle<Map> current_map = stub_holder_map; | 50 Handle<Map> current_map = stub_holder_map; |
| 52 Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); | 51 Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); |
| 53 while (true) { | 52 while (true) { |
| 54 if (current_map->is_dictionary_map()) cache_name = name; | 53 if (current_map->is_dictionary_map()) cache_name = name; |
| 55 if (current_map->prototype()->IsNull()) break; | 54 if (current_map->prototype()->IsNull()) break; |
| 56 last = handle(JSObject::cast(current_map->prototype())); | 55 last = handle(JSObject::cast(current_map->prototype())); |
| 57 current_map = handle(last->map()); | 56 current_map = handle(last->map()); |
| 58 } | 57 } |
| 59 // Compile the stub that is either shared for all names or | 58 // Compile the stub that is either shared for all names or |
| 60 // name specific if there are global objects involved. | 59 // name specific if there are global objects involved. |
| 61 Handle<Code> handler = PropertyHandlerCompiler::Find( | 60 Handle<Code> handler = PropertyHandlerCompiler::Find( |
| 62 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); | 61 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); |
| 63 if (!handler.is_null()) return handler; | 62 if (!handler.is_null()) return handler; |
| 64 | 63 |
| 65 NamedLoadHandlerCompiler compiler(isolate, type, last, flag); | 64 NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag); |
| 66 handler = compiler.CompileLoadNonexistent(cache_name); | 65 handler = compiler.CompileLoadNonexistent(cache_name); |
| 67 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); | 66 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); |
| 68 return handler; | 67 return handler; |
| 69 } | 68 } |
| 70 | 69 |
| 71 | 70 |
| 72 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, | 71 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, |
| 73 Code::StubType type, | 72 Code::StubType type, |
| 74 Handle<Name> name) { | 73 Handle<Name> name) { |
| 75 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder()); | 74 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder()); |
| 76 Handle<Code> code = GetCodeWithFlags(flags, name); | 75 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 77 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name)); | 76 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name)); |
| 78 #ifdef DEBUG | 77 #ifdef DEBUG |
| 79 code->VerifyEmbeddedObjects(); | 78 code->VerifyEmbeddedObjects(); |
| 80 #endif | 79 #endif |
| 81 return code; | 80 return code; |
| 82 } | 81 } |
| 83 | 82 |
| 84 | 83 |
| 85 void PropertyHandlerCompiler::set_type_for_object(Handle<Object> object) { | |
| 86 type_ = IC::CurrentTypeOf(object, isolate()); | |
| 87 } | |
| 88 | |
| 89 | |
| 90 #define __ ACCESS_MASM(masm()) | 84 #define __ ACCESS_MASM(masm()) |
| 91 | 85 |
| 92 | 86 |
| 93 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, | 87 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, |
| 94 Handle<Name> name, | 88 Handle<Name> name, |
| 95 Label* miss) { | 89 Label* miss) { |
| 96 PrototypeCheckType check_type = CHECK_ALL_MAPS; | 90 PrototypeCheckType check_type = CHECK_ALL_MAPS; |
| 97 int function_index = -1; | 91 int function_index = -1; |
| 98 if (type()->Is(HeapType::String())) { | 92 if (map()->instance_type() < FIRST_NONSTRING_TYPE) { |
| 99 function_index = Context::STRING_FUNCTION_INDEX; | 93 function_index = Context::STRING_FUNCTION_INDEX; |
| 100 } else if (type()->Is(HeapType::Symbol())) { | 94 } else if (map()->instance_type() == SYMBOL_TYPE) { |
| 101 function_index = Context::SYMBOL_FUNCTION_INDEX; | 95 function_index = Context::SYMBOL_FUNCTION_INDEX; |
| 102 } else if (type()->Is(HeapType::Number())) { | 96 } else if (map()->instance_type() == HEAP_NUMBER_TYPE) { |
| 103 function_index = Context::NUMBER_FUNCTION_INDEX; | 97 function_index = Context::NUMBER_FUNCTION_INDEX; |
| 104 } else if (type()->Is(HeapType::Boolean())) { | 98 } else if (*map() == isolate()->heap()->boolean_map()) { |
| 105 function_index = Context::BOOLEAN_FUNCTION_INDEX; | 99 function_index = Context::BOOLEAN_FUNCTION_INDEX; |
| 106 } else { | 100 } else { |
| 107 check_type = SKIP_RECEIVER; | 101 check_type = SKIP_RECEIVER; |
| 108 } | 102 } |
| 109 | 103 |
| 110 if (check_type == CHECK_ALL_MAPS) { | 104 if (check_type == CHECK_ALL_MAPS) { |
| 111 GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index, | 105 GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index, |
| 112 scratch1(), miss); | 106 scratch1(), miss); |
| 113 Object* function = isolate()->native_context()->get(function_index); | 107 Object* function = isolate()->native_context()->get(function_index); |
| 114 Object* prototype = JSFunction::cast(function)->instance_prototype(); | 108 Object* prototype = JSFunction::cast(function)->instance_prototype(); |
| 115 set_type_for_object(handle(prototype, isolate())); | 109 Handle<Map> map(JSObject::cast(prototype)->map()); |
| 110 set_map(map); |
| 116 object_reg = scratch1(); | 111 object_reg = scratch1(); |
| 117 } | 112 } |
| 118 | 113 |
| 119 // Check that the maps starting from the prototype haven't changed. | 114 // Check that the maps starting from the prototype haven't changed. |
| 120 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name, | 115 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name, |
| 121 miss, check_type); | 116 miss, check_type); |
| 122 } | 117 } |
| 123 | 118 |
| 124 | 119 |
| 125 // Frontend for store uses the name register. It has to be restored before a | 120 // Frontend for store uses the name register. It has to be restored before a |
| (...skipping 22 matching lines...) Expand all Loading... |
| 148 | 143 |
| 149 | 144 |
| 150 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, | 145 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, |
| 151 Label* miss, | 146 Label* miss, |
| 152 Register scratch1, | 147 Register scratch1, |
| 153 Register scratch2) { | 148 Register scratch2) { |
| 154 Register holder_reg; | 149 Register holder_reg; |
| 155 Handle<Map> last_map; | 150 Handle<Map> last_map; |
| 156 if (holder().is_null()) { | 151 if (holder().is_null()) { |
| 157 holder_reg = receiver(); | 152 holder_reg = receiver(); |
| 158 last_map = IC::TypeToMap(*type(), isolate()); | 153 last_map = map(); |
| 159 // If |type| has null as its prototype, |holder()| is | 154 // If |type| has null as its prototype, |holder()| is |
| 160 // Handle<JSObject>::null(). | 155 // Handle<JSObject>::null(). |
| 161 DCHECK(last_map->prototype() == isolate()->heap()->null_value()); | 156 DCHECK(last_map->prototype() == isolate()->heap()->null_value()); |
| 162 } else { | 157 } else { |
| 163 holder_reg = FrontendHeader(receiver(), name, miss); | 158 holder_reg = FrontendHeader(receiver(), name, miss); |
| 164 last_map = handle(holder()->map()); | 159 last_map = handle(holder()->map()); |
| 165 } | 160 } |
| 166 | 161 |
| 167 if (last_map->is_dictionary_map()) { | 162 if (last_map->is_dictionary_map()) { |
| 168 if (last_map->IsJSGlobalObjectMap()) { | 163 if (last_map->IsJSGlobalObjectMap()) { |
| 169 Handle<JSGlobalObject> global = | 164 Handle<JSGlobalObject> global = |
| 170 holder().is_null() | 165 holder().is_null() |
| 171 ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value()) | 166 ? Handle<JSGlobalObject>::cast(isolate()->global_object()) |
| 172 : Handle<JSGlobalObject>::cast(holder()); | 167 : Handle<JSGlobalObject>::cast(holder()); |
| 173 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); | 168 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); |
| 174 } else { | 169 } else { |
| 175 if (!name->IsUniqueName()) { | 170 if (!name->IsUniqueName()) { |
| 176 DCHECK(name->IsString()); | 171 DCHECK(name->IsString()); |
| 177 name = factory()->InternalizeString(Handle<String>::cast(name)); | 172 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 178 } | 173 } |
| 179 DCHECK(holder().is_null() || | 174 DCHECK(holder().is_null() || |
| 180 holder()->property_dictionary()->FindEntry(name) == | 175 holder()->property_dictionary()->FindEntry(name) == |
| 181 NameDictionary::kNotFound); | 176 NameDictionary::kNotFound); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 GenerateLoadCallback(reg, callback); | 224 GenerateLoadCallback(reg, callback); |
| 230 return GetCode(kind(), Code::FAST, name); | 225 return GetCode(kind(), Code::FAST, name); |
| 231 } | 226 } |
| 232 | 227 |
| 233 | 228 |
| 234 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 229 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
| 235 Handle<Name> name, const CallOptimization& call_optimization, | 230 Handle<Name> name, const CallOptimization& call_optimization, |
| 236 int accessor_index) { | 231 int accessor_index) { |
| 237 DCHECK(call_optimization.is_simple_api_call()); | 232 DCHECK(call_optimization.is_simple_api_call()); |
| 238 Register holder = Frontend(name); | 233 Register holder = Frontend(name); |
| 239 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate()); | 234 GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(), |
| 240 GenerateApiAccessorCall(masm(), call_optimization, receiver_map, receiver(), | |
| 241 scratch2(), false, no_reg, holder, accessor_index); | 235 scratch2(), false, no_reg, holder, accessor_index); |
| 242 return GetCode(kind(), Code::FAST, name); | 236 return GetCode(kind(), Code::FAST, name); |
| 243 } | 237 } |
| 244 | 238 |
| 245 | 239 |
| 246 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { | 240 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { |
| 247 if (IC::ICUseVector(kind())) { | 241 if (IC::ICUseVector(kind())) { |
| 248 if (holder_reg.is(receiver())) { | 242 if (holder_reg.is(receiver())) { |
| 249 PushVectorAndSlot(); | 243 PushVectorAndSlot(); |
| 250 } else { | 244 } else { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 case LookupIterator::DATA: | 283 case LookupIterator::DATA: |
| 290 inline_followup = | 284 inline_followup = |
| 291 it->property_details().type() == DATA && !it->is_dictionary_holder(); | 285 it->property_details().type() == DATA && !it->is_dictionary_holder(); |
| 292 break; | 286 break; |
| 293 case LookupIterator::ACCESSOR: { | 287 case LookupIterator::ACCESSOR: { |
| 294 Handle<Object> accessors = it->GetAccessors(); | 288 Handle<Object> accessors = it->GetAccessors(); |
| 295 if (accessors->IsExecutableAccessorInfo()) { | 289 if (accessors->IsExecutableAccessorInfo()) { |
| 296 Handle<ExecutableAccessorInfo> info = | 290 Handle<ExecutableAccessorInfo> info = |
| 297 Handle<ExecutableAccessorInfo>::cast(accessors); | 291 Handle<ExecutableAccessorInfo>::cast(accessors); |
| 298 inline_followup = info->getter() != NULL && | 292 inline_followup = info->getter() != NULL && |
| 299 ExecutableAccessorInfo::IsCompatibleReceiverType( | 293 ExecutableAccessorInfo::IsCompatibleReceiverMap( |
| 300 isolate(), info, type()); | 294 isolate(), info, map()); |
| 301 } else if (accessors->IsAccessorPair()) { | 295 } else if (accessors->IsAccessorPair()) { |
| 302 Handle<JSObject> property_holder(it->GetHolder<JSObject>()); | 296 Handle<JSObject> property_holder(it->GetHolder<JSObject>()); |
| 303 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 297 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
| 304 isolate()); | 298 isolate()); |
| 305 if (!getter->IsJSFunction()) break; | 299 if (!getter->IsJSFunction()) break; |
| 306 if (!property_holder->HasFastProperties()) break; | 300 if (!property_holder->HasFastProperties()) break; |
| 307 auto function = Handle<JSFunction>::cast(getter); | 301 auto function = Handle<JSFunction>::cast(getter); |
| 308 CallOptimization call_optimization(function); | 302 CallOptimization call_optimization(function); |
| 309 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate()); | 303 Handle<Map> receiver_map = map(); |
| 310 inline_followup = call_optimization.is_simple_api_call() && | 304 inline_followup = call_optimization.is_simple_api_call() && |
| 311 call_optimization.IsCompatibleReceiverType( | 305 call_optimization.IsCompatibleReceiverMap( |
| 312 receiver_map, property_holder); | 306 receiver_map, property_holder); |
| 313 } | 307 } |
| 314 } | 308 } |
| 315 } | 309 } |
| 316 | 310 |
| 317 Label miss; | 311 Label miss; |
| 318 InterceptorVectorSlotPush(receiver()); | 312 InterceptorVectorSlotPush(receiver()); |
| 319 Register reg = FrontendHeader(receiver(), it->name(), &miss); | 313 Register reg = FrontendHeader(receiver(), it->name(), &miss); |
| 320 FrontendFooter(it->name(), &miss); | 314 FrontendFooter(it->name(), &miss); |
| 321 InterceptorVectorSlotPop(reg); | 315 InterceptorVectorSlotPop(reg); |
| 322 | 316 |
| 323 if (inline_followup) { | 317 if (inline_followup) { |
| 324 // TODO(368): Compile in the whole chain: all the interceptors in | 318 // TODO(368): Compile in the whole chain: all the interceptors in |
| 325 // prototypes and ultimate answer. | 319 // prototypes and ultimate answer. |
| 326 GenerateLoadInterceptorWithFollowup(it, reg); | 320 GenerateLoadInterceptorWithFollowup(it, reg); |
| 327 } else { | 321 } else { |
| 328 GenerateLoadInterceptor(reg); | 322 GenerateLoadInterceptor(reg); |
| 329 } | 323 } |
| 330 return GetCode(kind(), Code::FAST, it->name()); | 324 return GetCode(kind(), Code::FAST, it->name()); |
| 331 } | 325 } |
| 332 | 326 |
| 333 | 327 |
| 334 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( | 328 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( |
| 335 LookupIterator* it, Register interceptor_reg) { | 329 LookupIterator* it, Register interceptor_reg) { |
| 336 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); | 330 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); |
| 337 | 331 |
| 338 set_type_for_object(holder()); | 332 Handle<Map> holder_map(holder()->map()); |
| 333 set_map(holder_map); |
| 339 set_holder(real_named_property_holder); | 334 set_holder(real_named_property_holder); |
| 340 | 335 |
| 341 Label miss; | 336 Label miss; |
| 342 InterceptorVectorSlotPush(interceptor_reg); | 337 InterceptorVectorSlotPush(interceptor_reg); |
| 343 Register reg = FrontendHeader(interceptor_reg, it->name(), &miss); | 338 Register reg = FrontendHeader(interceptor_reg, it->name(), &miss); |
| 344 FrontendFooter(it->name(), &miss); | 339 FrontendFooter(it->name(), &miss); |
| 345 // We discard the vector and slot now because we don't miss below this point. | 340 // We discard the vector and slot now because we don't miss below this point. |
| 346 InterceptorVectorSlotPop(reg, DISCARD); | 341 InterceptorVectorSlotPop(reg, DISCARD); |
| 347 | 342 |
| 348 switch (it->state()) { | 343 switch (it->state()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 362 case LookupIterator::ACCESSOR: | 357 case LookupIterator::ACCESSOR: |
| 363 if (it->GetAccessors()->IsExecutableAccessorInfo()) { | 358 if (it->GetAccessors()->IsExecutableAccessorInfo()) { |
| 364 Handle<ExecutableAccessorInfo> info = | 359 Handle<ExecutableAccessorInfo> info = |
| 365 Handle<ExecutableAccessorInfo>::cast(it->GetAccessors()); | 360 Handle<ExecutableAccessorInfo>::cast(it->GetAccessors()); |
| 366 DCHECK_NOT_NULL(info->getter()); | 361 DCHECK_NOT_NULL(info->getter()); |
| 367 GenerateLoadCallback(reg, info); | 362 GenerateLoadCallback(reg, info); |
| 368 } else { | 363 } else { |
| 369 auto function = handle(JSFunction::cast( | 364 auto function = handle(JSFunction::cast( |
| 370 AccessorPair::cast(*it->GetAccessors())->getter())); | 365 AccessorPair::cast(*it->GetAccessors())->getter())); |
| 371 CallOptimization call_optimization(function); | 366 CallOptimization call_optimization(function); |
| 372 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate()); | 367 GenerateApiAccessorCall(masm(), call_optimization, holder_map, |
| 373 GenerateApiAccessorCall(masm(), call_optimization, receiver_map, | |
| 374 receiver(), scratch2(), false, no_reg, reg, | 368 receiver(), scratch2(), false, no_reg, reg, |
| 375 it->GetAccessorIndex()); | 369 it->GetAccessorIndex()); |
| 376 } | 370 } |
| 377 } | 371 } |
| 378 } | 372 } |
| 379 | 373 |
| 380 | 374 |
| 381 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( | 375 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( |
| 382 Handle<Name> name, int accessor_index, int expected_arguments) { | 376 Handle<Name> name, int accessor_index, int expected_arguments) { |
| 383 Register holder = Frontend(name); | 377 Register holder = Frontend(name); |
| 384 GenerateLoadViaGetter(masm(), type(), receiver(), holder, accessor_index, | 378 GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index, |
| 385 expected_arguments, scratch2()); | 379 expected_arguments, scratch2()); |
| 386 return GetCode(kind(), Code::FAST, name); | 380 return GetCode(kind(), Code::FAST, name); |
| 387 } | 381 } |
| 388 | 382 |
| 389 | 383 |
| 390 // TODO(verwaest): Cleanup. holder() is actually the receiver. | 384 // TODO(verwaest): Cleanup. holder() is actually the receiver. |
| 391 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( | 385 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( |
| 392 Handle<Map> transition, Handle<Name> name) { | 386 Handle<Map> transition, Handle<Name> name) { |
| 393 Label miss; | 387 Label miss; |
| 394 | 388 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 __ bind(&miss); | 458 __ bind(&miss); |
| 465 TailCallBuiltin(masm(), MissBuiltin(kind())); | 459 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 466 return GetCode(kind(), Code::FAST, it->name()); | 460 return GetCode(kind(), Code::FAST, it->name()); |
| 467 } | 461 } |
| 468 | 462 |
| 469 | 463 |
| 470 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( | 464 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( |
| 471 Handle<JSObject> object, Handle<Name> name, int accessor_index, | 465 Handle<JSObject> object, Handle<Name> name, int accessor_index, |
| 472 int expected_arguments) { | 466 int expected_arguments) { |
| 473 Register holder = Frontend(name); | 467 Register holder = Frontend(name); |
| 474 GenerateStoreViaSetter(masm(), type(), receiver(), holder, accessor_index, | 468 GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index, |
| 475 expected_arguments, scratch2()); | 469 expected_arguments, scratch2()); |
| 476 | 470 |
| 477 return GetCode(kind(), Code::FAST, name); | 471 return GetCode(kind(), Code::FAST, name); |
| 478 } | 472 } |
| 479 | 473 |
| 480 | 474 |
| 481 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 475 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
| 482 Handle<JSObject> object, Handle<Name> name, | 476 Handle<JSObject> object, Handle<Name> name, |
| 483 const CallOptimization& call_optimization, int accessor_index) { | 477 const CallOptimization& call_optimization, int accessor_index) { |
| 484 Register holder = Frontend(name); | 478 Register holder = Frontend(name); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 DCHECK(elements_kind == DICTIONARY_ELEMENTS); | 512 DCHECK(elements_kind == DICTIONARY_ELEMENTS); |
| 519 cached_stub = LoadDictionaryElementStub(isolate()).GetCode(); | 513 cached_stub = LoadDictionaryElementStub(isolate()).GetCode(); |
| 520 } | 514 } |
| 521 } | 515 } |
| 522 | 516 |
| 523 handlers->Add(cached_stub); | 517 handlers->Add(cached_stub); |
| 524 } | 518 } |
| 525 } | 519 } |
| 526 } | 520 } |
| 527 } // namespace v8::internal | 521 } // namespace v8::internal |
| OLD | NEW |