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 |