| 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/ic/handler-compiler.h" | 5 #include "src/ic/handler-compiler.h" |
| 6 | 6 |
| 7 #include "src/ic/call-optimization.h" | 7 #include "src/ic/call-optimization.h" |
| 8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
| 9 #include "src/ic/ic-inl.h" | 9 #include "src/ic/ic-inl.h" |
| 10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 if (IC::ICUseVector(kind())) { | 221 if (IC::ICUseVector(kind())) { |
| 222 DiscardVectorAndSlot(); | 222 DiscardVectorAndSlot(); |
| 223 } | 223 } |
| 224 GenerateLoadConstant(isolate()->factory()->undefined_value()); | 224 GenerateLoadConstant(isolate()->factory()->undefined_value()); |
| 225 FrontendFooter(name, &miss); | 225 FrontendFooter(name, &miss); |
| 226 return GetCode(kind(), Code::FAST, name); | 226 return GetCode(kind(), Code::FAST, name); |
| 227 } | 227 } |
| 228 | 228 |
| 229 | 229 |
| 230 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 230 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
| 231 Handle<Name> name, Handle<ExecutableAccessorInfo> callback) { | 231 Handle<Name> name, Handle<AccessorInfo> callback) { |
| 232 Register reg = Frontend(name); | 232 Register reg = Frontend(name); |
| 233 GenerateLoadCallback(reg, callback); | 233 GenerateLoadCallback(reg, callback); |
| 234 return GetCode(kind(), Code::FAST, name); | 234 return GetCode(kind(), Code::FAST, name); |
| 235 } | 235 } |
| 236 | 236 |
| 237 | 237 |
| 238 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 238 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
| 239 Handle<Name> name, const CallOptimization& call_optimization, | 239 Handle<Name> name, const CallOptimization& call_optimization, |
| 240 int accessor_index) { | 240 int accessor_index) { |
| 241 DCHECK(call_optimization.is_simple_api_call()); | 241 DCHECK(call_optimization.is_simple_api_call()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 271 PopVectorAndSlot(scratch2(), scratch3()); | 271 PopVectorAndSlot(scratch2(), scratch3()); |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 | 276 |
| 277 | 277 |
| 278 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( | 278 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( |
| 279 LookupIterator* it) { | 279 LookupIterator* it) { |
| 280 // So far the most popular follow ups for interceptor loads are DATA and | 280 // So far the most popular follow ups for interceptor loads are DATA and |
| 281 // ExecutableAccessorInfo, so inline only them. Other cases may be added | 281 // AccessorInfo, so inline only them. Other cases may be added |
| 282 // later. | 282 // later. |
| 283 bool inline_followup = false; | 283 bool inline_followup = false; |
| 284 switch (it->state()) { | 284 switch (it->state()) { |
| 285 case LookupIterator::TRANSITION: | 285 case LookupIterator::TRANSITION: |
| 286 UNREACHABLE(); | 286 UNREACHABLE(); |
| 287 case LookupIterator::ACCESS_CHECK: | 287 case LookupIterator::ACCESS_CHECK: |
| 288 case LookupIterator::INTERCEPTOR: | 288 case LookupIterator::INTERCEPTOR: |
| 289 case LookupIterator::JSPROXY: | 289 case LookupIterator::JSPROXY: |
| 290 case LookupIterator::NOT_FOUND: | 290 case LookupIterator::NOT_FOUND: |
| 291 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 291 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 292 break; | 292 break; |
| 293 case LookupIterator::DATA: | 293 case LookupIterator::DATA: |
| 294 inline_followup = | 294 inline_followup = |
| 295 it->property_details().type() == DATA && !it->is_dictionary_holder(); | 295 it->property_details().type() == DATA && !it->is_dictionary_holder(); |
| 296 break; | 296 break; |
| 297 case LookupIterator::ACCESSOR: { | 297 case LookupIterator::ACCESSOR: { |
| 298 Handle<Object> accessors = it->GetAccessors(); | 298 Handle<Object> accessors = it->GetAccessors(); |
| 299 if (accessors->IsExecutableAccessorInfo()) { | 299 if (accessors->IsAccessorInfo()) { |
| 300 Handle<ExecutableAccessorInfo> info = | 300 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |
| 301 Handle<ExecutableAccessorInfo>::cast(accessors); | 301 inline_followup = |
| 302 inline_followup = info->getter() != NULL && | 302 info->getter() != NULL && |
| 303 ExecutableAccessorInfo::IsCompatibleReceiverMap( | 303 AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map()); |
| 304 isolate(), info, map()); | |
| 305 } else if (accessors->IsAccessorPair()) { | 304 } else if (accessors->IsAccessorPair()) { |
| 306 Handle<JSObject> property_holder(it->GetHolder<JSObject>()); | 305 Handle<JSObject> property_holder(it->GetHolder<JSObject>()); |
| 307 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 306 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
| 308 isolate()); | 307 isolate()); |
| 309 if (!getter->IsJSFunction()) break; | 308 if (!getter->IsJSFunction()) break; |
| 310 if (!property_holder->HasFastProperties()) break; | 309 if (!property_holder->HasFastProperties()) break; |
| 311 auto function = Handle<JSFunction>::cast(getter); | 310 auto function = Handle<JSFunction>::cast(getter); |
| 312 CallOptimization call_optimization(function); | 311 CallOptimization call_optimization(function); |
| 313 Handle<Map> receiver_map = map(); | 312 Handle<Map> receiver_map = map(); |
| 314 inline_followup = call_optimization.is_simple_api_call() && | 313 inline_followup = call_optimization.is_simple_api_call() && |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 case LookupIterator::TRANSITION: | 388 case LookupIterator::TRANSITION: |
| 390 UNREACHABLE(); | 389 UNREACHABLE(); |
| 391 case LookupIterator::DATA: { | 390 case LookupIterator::DATA: { |
| 392 DCHECK_EQ(DATA, it->property_details().type()); | 391 DCHECK_EQ(DATA, it->property_details().type()); |
| 393 __ Move(receiver(), reg); | 392 __ Move(receiver(), reg); |
| 394 LoadFieldStub stub(isolate(), it->GetFieldIndex()); | 393 LoadFieldStub stub(isolate(), it->GetFieldIndex()); |
| 395 GenerateTailCall(masm(), stub.GetCode()); | 394 GenerateTailCall(masm(), stub.GetCode()); |
| 396 break; | 395 break; |
| 397 } | 396 } |
| 398 case LookupIterator::ACCESSOR: | 397 case LookupIterator::ACCESSOR: |
| 399 if (it->GetAccessors()->IsExecutableAccessorInfo()) { | 398 if (it->GetAccessors()->IsAccessorInfo()) { |
| 400 Handle<ExecutableAccessorInfo> info = | 399 Handle<AccessorInfo> info = |
| 401 Handle<ExecutableAccessorInfo>::cast(it->GetAccessors()); | 400 Handle<AccessorInfo>::cast(it->GetAccessors()); |
| 402 DCHECK_NOT_NULL(info->getter()); | 401 DCHECK_NOT_NULL(info->getter()); |
| 403 GenerateLoadCallback(reg, info); | 402 GenerateLoadCallback(reg, info); |
| 404 } else { | 403 } else { |
| 405 auto function = handle(JSFunction::cast( | 404 auto function = handle(JSFunction::cast( |
| 406 AccessorPair::cast(*it->GetAccessors())->getter())); | 405 AccessorPair::cast(*it->GetAccessors())->getter())); |
| 407 CallOptimization call_optimization(function); | 406 CallOptimization call_optimization(function); |
| 408 GenerateApiAccessorCall(masm(), call_optimization, holder_map, | 407 GenerateApiAccessorCall(masm(), call_optimization, holder_map, |
| 409 receiver(), scratch2(), false, no_reg, reg, | 408 receiver(), scratch2(), false, no_reg, reg, |
| 410 it->GetAccessorIndex()); | 409 it->GetAccessorIndex()); |
| 411 } | 410 } |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 : kNoExtraICState); | 604 : kNoExtraICState); |
| 606 cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode(); | 605 cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode(); |
| 607 } | 606 } |
| 608 } | 607 } |
| 609 | 608 |
| 610 handlers->Add(cached_stub); | 609 handlers->Add(cached_stub); |
| 611 } | 610 } |
| 612 } | 611 } |
| 613 } // namespace internal | 612 } // namespace internal |
| 614 } // namespace v8 | 613 } // namespace v8 |
| OLD | NEW |