| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 LoadStubCompiler compiler(isolate_); | 154 LoadStubCompiler compiler(isolate_); |
| 155 Handle<Code> code = | 155 Handle<Code> code = |
| 156 compiler.CompileLoadField(receiver, holder, field_index, name); | 156 compiler.CompileLoadField(receiver, holder, field_index, name); |
| 157 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 157 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
| 158 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 158 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 159 JSObject::UpdateMapCodeCache(receiver, name, code); | 159 JSObject::UpdateMapCodeCache(receiver, name, code); |
| 160 return code; | 160 return code; |
| 161 } | 161 } |
| 162 | 162 |
| 163 | 163 |
| 164 Handle<Code> LoadStubCompiler::CompileLoadCallback( | |
| 165 Handle<String> name, | |
| 166 Handle<JSObject> object, | |
| 167 Handle<JSObject> holder, | |
| 168 Handle<AccessorInfo> callback) { | |
| 169 CALL_HEAP_FUNCTION(isolate(), | |
| 170 (set_failure(NULL), | |
| 171 CompileLoadCallback(*name, *object, *holder, *callback)), | |
| 172 Code); | |
| 173 } | |
| 174 | |
| 175 | |
| 176 Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name, | 164 Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name, |
| 177 Handle<JSObject> receiver, | 165 Handle<JSObject> receiver, |
| 178 Handle<JSObject> holder, | 166 Handle<JSObject> holder, |
| 179 Handle<AccessorInfo> callback) { | 167 Handle<AccessorInfo> callback) { |
| 180 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 168 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
| 181 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); | 169 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
| 182 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); | 170 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); |
| 183 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); | 171 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
| 184 if (probe->IsCode()) return Handle<Code>::cast(probe); | 172 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 185 | 173 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 206 LoadStubCompiler compiler(isolate_); | 194 LoadStubCompiler compiler(isolate_); |
| 207 Handle<Code> code = | 195 Handle<Code> code = |
| 208 compiler.CompileLoadConstant(receiver, holder, value, name); | 196 compiler.CompileLoadConstant(receiver, holder, value, name); |
| 209 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 197 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
| 210 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 198 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 211 JSObject::UpdateMapCodeCache(receiver, name, code); | 199 JSObject::UpdateMapCodeCache(receiver, name, code); |
| 212 return code; | 200 return code; |
| 213 } | 201 } |
| 214 | 202 |
| 215 | 203 |
| 216 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object, | |
| 217 Handle<JSObject> holder, | |
| 218 Handle<String> name) { | |
| 219 CALL_HEAP_FUNCTION(isolate(), | |
| 220 (set_failure(NULL), | |
| 221 CompileLoadInterceptor(*object, *holder, *name)), | |
| 222 Code); | |
| 223 } | |
| 224 | |
| 225 | |
| 226 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, | 204 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, |
| 227 Handle<JSObject> receiver, | 205 Handle<JSObject> receiver, |
| 228 Handle<JSObject> holder) { | 206 Handle<JSObject> holder) { |
| 229 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); | 207 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
| 230 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); | 208 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); |
| 231 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); | 209 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
| 232 if (probe->IsCode()) return Handle<Code>::cast(probe); | 210 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 233 | 211 |
| 234 LoadStubCompiler compiler(isolate_); | 212 LoadStubCompiler compiler(isolate_); |
| 235 Handle<Code> code = | 213 Handle<Code> code = |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 KeyedLoadStubCompiler compiler(isolate_); | 276 KeyedLoadStubCompiler compiler(isolate_); |
| 299 Handle<Code> code = | 277 Handle<Code> code = |
| 300 compiler.CompileLoadConstant(name, receiver, holder, value); | 278 compiler.CompileLoadConstant(name, receiver, holder, value); |
| 301 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 279 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
| 302 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 280 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
| 303 JSObject::UpdateMapCodeCache(receiver, name, code); | 281 JSObject::UpdateMapCodeCache(receiver, name, code); |
| 304 return code; | 282 return code; |
| 305 } | 283 } |
| 306 | 284 |
| 307 | 285 |
| 308 Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( | |
| 309 Handle<JSObject> object, | |
| 310 Handle<JSObject> holder, | |
| 311 Handle<String> name) { | |
| 312 CALL_HEAP_FUNCTION(isolate(), | |
| 313 (set_failure(NULL), | |
| 314 CompileLoadInterceptor(*object, *holder, *name)), | |
| 315 Code); | |
| 316 } | |
| 317 | |
| 318 | |
| 319 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, | 286 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, |
| 320 Handle<JSObject> receiver, | 287 Handle<JSObject> receiver, |
| 321 Handle<JSObject> holder) { | 288 Handle<JSObject> holder) { |
| 322 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); | 289 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
| 323 Code::Flags flags = | 290 Code::Flags flags = |
| 324 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); | 291 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); |
| 325 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); | 292 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
| 326 if (probe->IsCode()) return Handle<Code>::cast(probe); | 293 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 327 | 294 |
| 328 KeyedLoadStubCompiler compiler(isolate_); | 295 KeyedLoadStubCompiler compiler(isolate_); |
| 329 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); | 296 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); |
| 330 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 297 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
| 331 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 298 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
| 332 JSObject::UpdateMapCodeCache(receiver, name, code); | 299 JSObject::UpdateMapCodeCache(receiver, name, code); |
| 333 return code; | 300 return code; |
| 334 } | 301 } |
| 335 | 302 |
| 336 | 303 |
| 337 Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( | |
| 338 Handle<String> name, | |
| 339 Handle<JSObject> object, | |
| 340 Handle<JSObject> holder, | |
| 341 Handle<AccessorInfo> callback) { | |
| 342 CALL_HEAP_FUNCTION(isolate(), | |
| 343 (set_failure(NULL), | |
| 344 CompileLoadCallback(*name, *object, *holder, *callback)), | |
| 345 Code); | |
| 346 } | |
| 347 | |
| 348 | |
| 349 Handle<Code> StubCache::ComputeKeyedLoadCallback( | 304 Handle<Code> StubCache::ComputeKeyedLoadCallback( |
| 350 Handle<String> name, | 305 Handle<String> name, |
| 351 Handle<JSObject> receiver, | 306 Handle<JSObject> receiver, |
| 352 Handle<JSObject> holder, | 307 Handle<JSObject> holder, |
| 353 Handle<AccessorInfo> callback) { | 308 Handle<AccessorInfo> callback) { |
| 354 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); | 309 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
| 355 Code::Flags flags = | 310 Code::Flags flags = |
| 356 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 311 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
| 357 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); | 312 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
| 358 if (probe->IsCode()) return Handle<Code>::cast(probe); | 313 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); | 525 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); |
| 571 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); | 526 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); |
| 572 JSObject::UpdateMapCodeCache(receiver, name, code); | 527 JSObject::UpdateMapCodeCache(receiver, name, code); |
| 573 return code; | 528 return code; |
| 574 } | 529 } |
| 575 | 530 |
| 576 | 531 |
| 577 #define CALL_LOGGER_TAG(kind, type) \ | 532 #define CALL_LOGGER_TAG(kind, type) \ |
| 578 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 533 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
| 579 | 534 |
| 580 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | |
| 581 Handle<JSObject> holder, | |
| 582 Handle<JSFunction> function, | |
| 583 Handle<String> name, | |
| 584 CheckType check) { | |
| 585 CALL_HEAP_FUNCTION( | |
| 586 isolate(), | |
| 587 (set_failure(NULL), | |
| 588 CompileCallConstant(*object, *holder, *function, *name, check)), | |
| 589 Code); | |
| 590 } | |
| 591 | |
| 592 | |
| 593 Handle<Code> StubCache::ComputeCallConstant(int argc, | 535 Handle<Code> StubCache::ComputeCallConstant(int argc, |
| 594 Code::Kind kind, | 536 Code::Kind kind, |
| 595 Code::ExtraICState extra_state, | 537 Code::ExtraICState extra_state, |
| 596 Handle<String> name, | 538 Handle<String> name, |
| 597 Handle<Object> object, | 539 Handle<Object> object, |
| 598 Handle<JSObject> holder, | 540 Handle<JSObject> holder, |
| 599 Handle<JSFunction> function) { | 541 Handle<JSFunction> function) { |
| 600 // Compute the check type and the map. | 542 // Compute the check type and the map. |
| 601 InlineCacheHolderFlag cache_holder = | 543 InlineCacheHolderFlag cache_holder = |
| 602 IC::GetCodeCacheForObject(*object, *holder); | 544 IC::GetCodeCacheForObject(*object, *holder); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 holder, index, name); | 604 holder, index, name); |
| 663 ASSERT_EQ(flags, code->flags()); | 605 ASSERT_EQ(flags, code->flags()); |
| 664 PROFILE(isolate_, | 606 PROFILE(isolate_, |
| 665 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 607 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
| 666 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 608 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
| 667 JSObject::UpdateMapCodeCache(map_holder, name, code); | 609 JSObject::UpdateMapCodeCache(map_holder, name, code); |
| 668 return code; | 610 return code; |
| 669 } | 611 } |
| 670 | 612 |
| 671 | 613 |
| 672 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | |
| 673 Handle<JSObject> holder, | |
| 674 Handle<String> name) { | |
| 675 CALL_HEAP_FUNCTION( | |
| 676 isolate(), | |
| 677 (set_failure(NULL), CompileCallInterceptor(*object, *holder, *name)), | |
| 678 Code); | |
| 679 } | |
| 680 | |
| 681 | |
| 682 Handle<Code> StubCache::ComputeCallInterceptor(int argc, | 614 Handle<Code> StubCache::ComputeCallInterceptor(int argc, |
| 683 Code::Kind kind, | 615 Code::Kind kind, |
| 684 Code::ExtraICState extra_state, | 616 Code::ExtraICState extra_state, |
| 685 Handle<String> name, | 617 Handle<String> name, |
| 686 Handle<Object> object, | 618 Handle<Object> object, |
| 687 Handle<JSObject> holder) { | 619 Handle<JSObject> holder) { |
| 688 // Compute the check type and the map. | 620 // Compute the check type and the map. |
| 689 InlineCacheHolderFlag cache_holder = | 621 InlineCacheHolderFlag cache_holder = |
| 690 IC::GetCodeCacheForObject(*object, *holder); | 622 IC::GetCodeCacheForObject(*object, *holder); |
| 691 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); | 623 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 709 holder, name); | 641 holder, name); |
| 710 ASSERT_EQ(flags, code->flags()); | 642 ASSERT_EQ(flags, code->flags()); |
| 711 PROFILE(isolate(), | 643 PROFILE(isolate(), |
| 712 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 644 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
| 713 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 645 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
| 714 JSObject::UpdateMapCodeCache(map_holder, name, code); | 646 JSObject::UpdateMapCodeCache(map_holder, name, code); |
| 715 return code; | 647 return code; |
| 716 } | 648 } |
| 717 | 649 |
| 718 | 650 |
| 719 Handle<Code> CallStubCompiler::CompileCallGlobal( | |
| 720 Handle<JSObject> object, | |
| 721 Handle<GlobalObject> holder, | |
| 722 Handle<JSGlobalPropertyCell> cell, | |
| 723 Handle<JSFunction> function, | |
| 724 Handle<String> name) { | |
| 725 CALL_HEAP_FUNCTION( | |
| 726 isolate(), | |
| 727 (set_failure(NULL), | |
| 728 CompileCallGlobal(*object, *holder, *cell, *function, *name)), | |
| 729 Code); | |
| 730 } | |
| 731 | |
| 732 | |
| 733 Handle<Code> StubCache::ComputeCallGlobal(int argc, | 651 Handle<Code> StubCache::ComputeCallGlobal(int argc, |
| 734 Code::Kind kind, | 652 Code::Kind kind, |
| 735 Code::ExtraICState extra_state, | 653 Code::ExtraICState extra_state, |
| 736 Handle<String> name, | 654 Handle<String> name, |
| 737 Handle<JSObject> receiver, | 655 Handle<JSObject> receiver, |
| 738 Handle<GlobalObject> holder, | 656 Handle<GlobalObject> holder, |
| 739 Handle<JSGlobalPropertyCell> cell, | 657 Handle<JSGlobalPropertyCell> cell, |
| 740 Handle<JSFunction> function) { | 658 Handle<JSFunction> function) { |
| 741 InlineCacheHolderFlag cache_holder = | 659 InlineCacheHolderFlag cache_holder = |
| 742 IC::GetCodeCacheForObject(*receiver, *holder); | 660 IC::GetCodeCacheForObject(*receiver, *holder); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 int entry = cache->FindEntry(isolate_, flags); | 817 int entry = cache->FindEntry(isolate_, flags); |
| 900 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 818 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 901 | 819 |
| 902 StubCompiler compiler(isolate_); | 820 StubCompiler compiler(isolate_); |
| 903 Handle<Code> code = compiler.CompileCallMiss(flags); | 821 Handle<Code> code = compiler.CompileCallMiss(flags); |
| 904 FillCache(isolate_, code); | 822 FillCache(isolate_, code); |
| 905 return code; | 823 return code; |
| 906 } | 824 } |
| 907 | 825 |
| 908 | 826 |
| 909 // The CallStubCompiler needs a version of ComputeCallMiss that does not | |
| 910 // perform GC. This function is temporary, because the stub cache but not | |
| 911 // yet the stub compiler uses handles. | |
| 912 MaybeObject* StubCache::TryComputeCallMiss(int argc, | |
| 913 Code::Kind kind, | |
| 914 Code::ExtraICState extra_state) { | |
| 915 Code::Flags flags = | |
| 916 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, | |
| 917 NORMAL, argc, OWN_MAP); | |
| 918 NumberDictionary* cache = isolate_->heap()->non_monomorphic_cache(); | |
| 919 int entry = cache->FindEntry(isolate_, flags); | |
| 920 if (entry != -1) return cache->ValueAt(entry); | |
| 921 | |
| 922 StubCompiler compiler(isolate_); | |
| 923 Code* code = NULL; | |
| 924 MaybeObject* maybe_code = compiler.TryCompileCallMiss(flags); | |
| 925 if (!maybe_code->To(&code)) return maybe_code; | |
| 926 | |
| 927 NumberDictionary* new_cache = NULL; | |
| 928 MaybeObject* maybe_new_cache = cache->AtNumberPut(flags, code); | |
| 929 if (!maybe_new_cache->To(&new_cache)) return maybe_new_cache; | |
| 930 isolate_->heap()->public_set_non_monomorphic_cache(new_cache); | |
| 931 | |
| 932 return code; | |
| 933 } | |
| 934 | |
| 935 | |
| 936 #ifdef ENABLE_DEBUGGER_SUPPORT | 827 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 937 Handle<Code> StubCache::ComputeCallDebugBreak(int argc, | 828 Handle<Code> StubCache::ComputeCallDebugBreak(int argc, |
| 938 Code::Kind kind) { | 829 Code::Kind kind) { |
| 939 // Extra IC state is irrelevant for debug break ICs. They jump to | 830 // Extra IC state is irrelevant for debug break ICs. They jump to |
| 940 // the actual call ic to carry out the work. | 831 // the actual call ic to carry out the work. |
| 941 Code::Flags flags = | 832 Code::Flags flags = |
| 942 Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState, | 833 Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState, |
| 943 NORMAL, argc); | 834 NORMAL, argc); |
| 944 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); | 835 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
| 945 int entry = cache->FindEntry(isolate_, flags); | 836 int entry = cache->FindEntry(isolate_, flags); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); | 1227 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); |
| 1337 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1228 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1338 PROFILE(isolate(), | 1229 PROFILE(isolate(), |
| 1339 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), | 1230 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), |
| 1340 *code, code->arguments_count())); | 1231 *code, code->arguments_count())); |
| 1341 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code)); | 1232 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code)); |
| 1342 return code; | 1233 return code; |
| 1343 } | 1234 } |
| 1344 | 1235 |
| 1345 | 1236 |
| 1346 // TODO(kmillikin): This annoying raw pointer implementation should be | |
| 1347 // eliminated when the stub compiler no longer needs it. | |
| 1348 MaybeObject* StubCompiler::TryCompileCallMiss(Code::Flags flags) { | |
| 1349 HandleScope scope(isolate()); | |
| 1350 int argc = Code::ExtractArgumentsCountFromFlags(flags); | |
| 1351 Code::Kind kind = Code::ExtractKindFromFlags(flags); | |
| 1352 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | |
| 1353 if (kind == Code::CALL_IC) { | |
| 1354 CallIC::GenerateMiss(masm(), argc, extra_state); | |
| 1355 } else { | |
| 1356 KeyedCallIC::GenerateMiss(masm(), argc); | |
| 1357 } | |
| 1358 Object* result; | |
| 1359 { MaybeObject* maybe_result = TryGetCodeWithFlags(flags, "CompileCallMiss"); | |
| 1360 if (!maybe_result->ToObject(&result)) return maybe_result; | |
| 1361 } | |
| 1362 isolate()->counters()->call_megamorphic_stubs()->Increment(); | |
| 1363 Code* code = Code::cast(result); | |
| 1364 USE(code); | |
| 1365 PROFILE(isolate(), | |
| 1366 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), | |
| 1367 code, code->arguments_count())); | |
| 1368 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, Code::cast(code))); | |
| 1369 return result; | |
| 1370 } | |
| 1371 | |
| 1372 | |
| 1373 #ifdef ENABLE_DEBUGGER_SUPPORT | 1237 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1374 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) { | 1238 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) { |
| 1375 Debug::GenerateCallICDebugBreak(masm()); | 1239 Debug::GenerateCallICDebugBreak(masm()); |
| 1376 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak"); | 1240 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak"); |
| 1377 PROFILE(isolate(), | 1241 PROFILE(isolate(), |
| 1378 CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags), | 1242 CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags), |
| 1379 CALL_DEBUG_BREAK_TAG), | 1243 CALL_DEBUG_BREAK_TAG), |
| 1380 *code, code->arguments_count())); | 1244 *code, code->arguments_count())); |
| 1381 return code; | 1245 return code; |
| 1382 } | 1246 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1447 | 1311 |
| 1448 MaybeObject* StubCompiler::TryGetCodeWithFlags(Code::Flags flags, | 1312 MaybeObject* StubCompiler::TryGetCodeWithFlags(Code::Flags flags, |
| 1449 String* name) { | 1313 String* name) { |
| 1450 if (FLAG_print_code_stubs && name != NULL) { | 1314 if (FLAG_print_code_stubs && name != NULL) { |
| 1451 return TryGetCodeWithFlags(flags, *name->ToCString()); | 1315 return TryGetCodeWithFlags(flags, *name->ToCString()); |
| 1452 } | 1316 } |
| 1453 return TryGetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); | 1317 return TryGetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); |
| 1454 } | 1318 } |
| 1455 | 1319 |
| 1456 | 1320 |
| 1457 void StubCompiler::LookupPostInterceptor(JSObject* holder, | 1321 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, |
| 1458 String* name, | 1322 Handle<String> name, |
| 1459 LookupResult* lookup) { | 1323 LookupResult* lookup) { |
| 1460 holder->LocalLookupRealNamedProperty(name, lookup); | 1324 holder->LocalLookupRealNamedProperty(*name, lookup); |
| 1461 if (!lookup->IsProperty()) { | 1325 if (lookup->IsProperty()) return; |
| 1462 lookup->NotFound(); | 1326 |
| 1463 Object* proto = holder->GetPrototype(); | 1327 lookup->NotFound(); |
| 1464 if (!proto->IsNull()) { | 1328 if (holder->GetPrototype()->IsNull()) return; |
| 1465 proto->Lookup(name, lookup); | 1329 |
| 1466 } | 1330 holder->GetPrototype()->Lookup(*name, lookup); |
| 1467 } | |
| 1468 } | 1331 } |
| 1469 | 1332 |
| 1470 | 1333 |
| 1471 Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) { | 1334 Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) { |
| 1472 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); | 1335 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); |
| 1473 Handle<Code> code = GetCodeWithFlags(flags, name); | 1336 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1474 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 1337 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
| 1475 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1338 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 1476 return code; | 1339 return code; |
| 1477 } | 1340 } |
| 1478 | 1341 |
| 1479 | 1342 |
| 1480 // TODO(ulan): Eliminate this function when the stub cache is fully | |
| 1481 // handlified. | |
| 1482 MaybeObject* LoadStubCompiler::TryGetCode(PropertyType type, String* name) { | |
| 1483 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); | |
| 1484 MaybeObject* result = TryGetCodeWithFlags(flags, name); | |
| 1485 if (!result->IsFailure()) { | |
| 1486 PROFILE(isolate(), | |
| 1487 CodeCreateEvent(Logger::LOAD_IC_TAG, | |
| 1488 Code::cast(result->ToObjectUnchecked()), | |
| 1489 name)); | |
| 1490 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, | |
| 1491 name, | |
| 1492 Code::cast(result->ToObjectUnchecked()))); | |
| 1493 } | |
| 1494 return result; | |
| 1495 } | |
| 1496 | |
| 1497 | |
| 1498 Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type, | 1343 Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type, |
| 1499 Handle<String> name, | 1344 Handle<String> name, |
| 1500 InlineCacheState state) { | 1345 InlineCacheState state) { |
| 1501 Code::Flags flags = Code::ComputeFlags( | 1346 Code::Flags flags = Code::ComputeFlags( |
| 1502 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); | 1347 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); |
| 1503 Handle<Code> code = GetCodeWithFlags(flags, name); | 1348 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1504 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); | 1349 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
| 1505 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1350 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 1506 return code; | 1351 return code; |
| 1507 } | 1352 } |
| 1508 | 1353 |
| 1509 // TODO(ulan): Eliminate this function when the stub cache is fully | |
| 1510 // handlified. | |
| 1511 MaybeObject* KeyedLoadStubCompiler::TryGetCode(PropertyType type, | |
| 1512 String* name, | |
| 1513 InlineCacheState state) { | |
| 1514 Code::Flags flags = Code::ComputeFlags( | |
| 1515 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); | |
| 1516 MaybeObject* result = TryGetCodeWithFlags(flags, name); | |
| 1517 if (!result->IsFailure()) { | |
| 1518 PROFILE(isolate(), | |
| 1519 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, | |
| 1520 Code::cast(result->ToObjectUnchecked()), | |
| 1521 name)); | |
| 1522 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, | |
| 1523 name, | |
| 1524 Code::cast(result->ToObjectUnchecked()))); | |
| 1525 } | |
| 1526 return result; | |
| 1527 } | |
| 1528 | |
| 1529 | 1354 |
| 1530 Handle<Code> StoreStubCompiler::GetCode(PropertyType type, | 1355 Handle<Code> StoreStubCompiler::GetCode(PropertyType type, |
| 1531 Handle<String> name) { | 1356 Handle<String> name) { |
| 1532 Code::Flags flags = | 1357 Code::Flags flags = |
| 1533 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); | 1358 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); |
| 1534 Handle<Code> code = GetCodeWithFlags(flags, name); | 1359 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1535 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); | 1360 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
| 1536 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 1361 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
| 1537 return code; | 1362 return code; |
| 1538 } | 1363 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1562 Code::ExtraICState extra_state, | 1387 Code::ExtraICState extra_state, |
| 1563 InlineCacheHolderFlag cache_holder) | 1388 InlineCacheHolderFlag cache_holder) |
| 1564 : StubCompiler(isolate), | 1389 : StubCompiler(isolate), |
| 1565 arguments_(argc), | 1390 arguments_(argc), |
| 1566 kind_(kind), | 1391 kind_(kind), |
| 1567 extra_state_(extra_state), | 1392 extra_state_(extra_state), |
| 1568 cache_holder_(cache_holder) { | 1393 cache_holder_(cache_holder) { |
| 1569 } | 1394 } |
| 1570 | 1395 |
| 1571 | 1396 |
| 1572 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) { | 1397 bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) { |
| 1573 SharedFunctionInfo* info = function->shared(); | 1398 if (function->shared()->HasBuiltinFunctionId()) { |
| 1574 if (info->HasBuiltinFunctionId()) { | 1399 BuiltinFunctionId id = function->shared()->builtin_function_id(); |
| 1575 BuiltinFunctionId id = info->builtin_function_id(); | |
| 1576 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; | 1400 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; |
| 1577 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) | 1401 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) |
| 1578 #undef CALL_GENERATOR_CASE | 1402 #undef CALL_GENERATOR_CASE |
| 1579 } | 1403 } |
| 1404 |
| 1580 CallOptimization optimization(function); | 1405 CallOptimization optimization(function); |
| 1581 if (optimization.is_simple_api_call()) { | 1406 return optimization.is_simple_api_call(); |
| 1582 return true; | |
| 1583 } | |
| 1584 return false; | |
| 1585 } | 1407 } |
| 1586 | 1408 |
| 1587 | 1409 |
| 1588 MaybeObject* CallStubCompiler::CompileCustomCall(Object* object, | 1410 Handle<Code> CallStubCompiler::CompileCustomCall( |
| 1589 JSObject* holder, | 1411 Handle<Object> object, |
| 1590 JSGlobalPropertyCell* cell, | 1412 Handle<JSObject> holder, |
| 1591 JSFunction* function, | 1413 Handle<JSGlobalPropertyCell> cell, |
| 1592 String* fname) { | 1414 Handle<JSFunction> function, |
| 1415 Handle<String> fname) { |
| 1593 ASSERT(HasCustomCallGenerator(function)); | 1416 ASSERT(HasCustomCallGenerator(function)); |
| 1594 | 1417 |
| 1595 SharedFunctionInfo* info = function->shared(); | 1418 if (function->shared()->HasBuiltinFunctionId()) { |
| 1596 if (info->HasBuiltinFunctionId()) { | 1419 BuiltinFunctionId id = function->shared()->builtin_function_id(); |
| 1597 BuiltinFunctionId id = info->builtin_function_id(); | 1420 #define CALL_GENERATOR_CASE(name) \ |
| 1598 #define CALL_GENERATOR_CASE(name) \ | 1421 if (id == k##name) { \ |
| 1599 if (id == k##name) { \ | 1422 return CallStubCompiler::Compile##name##Call(object, \ |
| 1600 return CallStubCompiler::Compile##name##Call(object, \ | 1423 holder, \ |
| 1601 holder, \ | 1424 cell, \ |
| 1602 cell, \ | 1425 function, \ |
| 1603 function, \ | 1426 fname); \ |
| 1604 fname); \ | |
| 1605 } | 1427 } |
| 1606 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) | 1428 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) |
| 1607 #undef CALL_GENERATOR_CASE | 1429 #undef CALL_GENERATOR_CASE |
| 1608 } | 1430 } |
| 1609 CallOptimization optimization(function); | 1431 CallOptimization optimization(function); |
| 1610 ASSERT(optimization.is_simple_api_call()); | 1432 ASSERT(optimization.is_simple_api_call()); |
| 1611 return CompileFastApiCall(optimization, | 1433 return CompileFastApiCall(optimization, |
| 1612 object, | 1434 object, |
| 1613 holder, | 1435 holder, |
| 1614 cell, | 1436 cell, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1630 | 1452 |
| 1631 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { | 1453 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { |
| 1632 Handle<String> function_name; | 1454 Handle<String> function_name; |
| 1633 if (function->shared()->name()->IsString()) { | 1455 if (function->shared()->name()->IsString()) { |
| 1634 function_name = Handle<String>(String::cast(function->shared()->name())); | 1456 function_name = Handle<String>(String::cast(function->shared()->name())); |
| 1635 } | 1457 } |
| 1636 return GetCode(CONSTANT_FUNCTION, function_name); | 1458 return GetCode(CONSTANT_FUNCTION, function_name); |
| 1637 } | 1459 } |
| 1638 | 1460 |
| 1639 | 1461 |
| 1640 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 1641 // handlified. | |
| 1642 MaybeObject* CallStubCompiler::TryGetCode(PropertyType type, String* name) { | |
| 1643 int argc = arguments_.immediate(); | |
| 1644 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, | |
| 1645 type, | |
| 1646 extra_state_, | |
| 1647 cache_holder_, | |
| 1648 argc); | |
| 1649 return TryGetCodeWithFlags(flags, name); | |
| 1650 } | |
| 1651 | |
| 1652 | |
| 1653 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 1654 // handlified. | |
| 1655 MaybeObject* CallStubCompiler::TryGetCode(JSFunction* function) { | |
| 1656 String* function_name = NULL; | |
| 1657 if (function->shared()->name()->IsString()) { | |
| 1658 function_name = String::cast(function->shared()->name()); | |
| 1659 } | |
| 1660 return TryGetCode(CONSTANT_FUNCTION, function_name); | |
| 1661 } | |
| 1662 | |
| 1663 | |
| 1664 MaybeObject* ConstructStubCompiler::GetCode() { | 1462 MaybeObject* ConstructStubCompiler::GetCode() { |
| 1665 Code::Flags flags = Code::ComputeFlags(Code::STUB); | 1463 Code::Flags flags = Code::ComputeFlags(Code::STUB); |
| 1666 Object* result; | 1464 Object* result; |
| 1667 { MaybeObject* maybe_result = TryGetCodeWithFlags(flags, "ConstructStub"); | 1465 { MaybeObject* maybe_result = TryGetCodeWithFlags(flags, "ConstructStub"); |
| 1668 if (!maybe_result->ToObject(&result)) return maybe_result; | 1466 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1669 } | 1467 } |
| 1670 Code* code = Code::cast(result); | 1468 Code* code = Code::cast(result); |
| 1671 USE(code); | 1469 USE(code); |
| 1672 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); | 1470 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); |
| 1673 GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", Code::cast(code))); | 1471 GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", Code::cast(code))); |
| 1674 return result; | 1472 return result; |
| 1675 } | 1473 } |
| 1676 | 1474 |
| 1677 | 1475 |
| 1678 CallOptimization::CallOptimization(LookupResult* lookup) { | 1476 CallOptimization::CallOptimization(LookupResult* lookup) { |
| 1679 if (!lookup->IsProperty() || !lookup->IsCacheable() || | 1477 if (!lookup->IsProperty() || |
| 1478 !lookup->IsCacheable() || |
| 1680 lookup->type() != CONSTANT_FUNCTION) { | 1479 lookup->type() != CONSTANT_FUNCTION) { |
| 1681 Initialize(NULL); | 1480 Initialize(Handle<JSFunction>::null()); |
| 1682 } else { | 1481 } else { |
| 1683 // We only optimize constant function calls. | 1482 // We only optimize constant function calls. |
| 1684 Initialize(lookup->GetConstantFunction()); | 1483 Initialize(Handle<JSFunction>(lookup->GetConstantFunction())); |
| 1685 } | 1484 } |
| 1686 } | 1485 } |
| 1687 | 1486 |
| 1688 CallOptimization::CallOptimization(JSFunction* function) { | 1487 CallOptimization::CallOptimization(Handle<JSFunction> function) { |
| 1689 Initialize(function); | 1488 Initialize(function); |
| 1690 } | 1489 } |
| 1691 | 1490 |
| 1692 | 1491 |
| 1693 int CallOptimization::GetPrototypeDepthOfExpectedType(JSObject* object, | 1492 int CallOptimization::GetPrototypeDepthOfExpectedType( |
| 1694 JSObject* holder) const { | 1493 Handle<JSObject> object, |
| 1695 ASSERT(is_simple_api_call_); | 1494 Handle<JSObject> holder) const { |
| 1696 if (expected_receiver_type_ == NULL) return 0; | 1495 ASSERT(is_simple_api_call()); |
| 1496 if (expected_receiver_type_.is_null()) return 0; |
| 1697 int depth = 0; | 1497 int depth = 0; |
| 1698 while (object != holder) { | 1498 while (!object.is_identical_to(holder)) { |
| 1699 if (object->IsInstanceOf(expected_receiver_type_)) return depth; | 1499 if (object->IsInstanceOf(*expected_receiver_type_)) return depth; |
| 1700 object = JSObject::cast(object->GetPrototype()); | 1500 object = Handle<JSObject>(JSObject::cast(object->GetPrototype())); |
| 1701 ++depth; | 1501 ++depth; |
| 1702 } | 1502 } |
| 1703 if (holder->IsInstanceOf(expected_receiver_type_)) return depth; | 1503 if (holder->IsInstanceOf(*expected_receiver_type_)) return depth; |
| 1704 return kInvalidProtoDepth; | 1504 return kInvalidProtoDepth; |
| 1705 } | 1505 } |
| 1706 | 1506 |
| 1707 | 1507 |
| 1708 void CallOptimization::Initialize(JSFunction* function) { | 1508 void CallOptimization::Initialize(Handle<JSFunction> function) { |
| 1709 constant_function_ = NULL; | 1509 constant_function_ = Handle<JSFunction>::null(); |
| 1710 is_simple_api_call_ = false; | 1510 is_simple_api_call_ = false; |
| 1711 expected_receiver_type_ = NULL; | 1511 expected_receiver_type_ = Handle<FunctionTemplateInfo>::null(); |
| 1712 api_call_info_ = NULL; | 1512 api_call_info_ = Handle<CallHandlerInfo>::null(); |
| 1713 | 1513 |
| 1714 if (function == NULL || !function->is_compiled()) return; | 1514 if (function.is_null() || !function->is_compiled()) return; |
| 1715 | 1515 |
| 1716 constant_function_ = function; | 1516 constant_function_ = function; |
| 1717 AnalyzePossibleApiFunction(function); | 1517 AnalyzePossibleApiFunction(function); |
| 1718 } | 1518 } |
| 1719 | 1519 |
| 1720 | 1520 |
| 1721 void CallOptimization::AnalyzePossibleApiFunction(JSFunction* function) { | 1521 void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) { |
| 1722 SharedFunctionInfo* sfi = function->shared(); | 1522 if (!function->shared()->IsApiFunction()) return; |
| 1723 if (!sfi->IsApiFunction()) return; | 1523 Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data()); |
| 1724 FunctionTemplateInfo* info = sfi->get_api_func_data(); | |
| 1725 | 1524 |
| 1726 // Require a C++ callback. | 1525 // Require a C++ callback. |
| 1727 if (info->call_code()->IsUndefined()) return; | 1526 if (info->call_code()->IsUndefined()) return; |
| 1728 api_call_info_ = CallHandlerInfo::cast(info->call_code()); | 1527 api_call_info_ = |
| 1528 Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code())); |
| 1729 | 1529 |
| 1730 // Accept signatures that either have no restrictions at all or | 1530 // Accept signatures that either have no restrictions at all or |
| 1731 // only have restrictions on the receiver. | 1531 // only have restrictions on the receiver. |
| 1732 if (!info->signature()->IsUndefined()) { | 1532 if (!info->signature()->IsUndefined()) { |
| 1733 SignatureInfo* signature = SignatureInfo::cast(info->signature()); | 1533 Handle<SignatureInfo> signature = |
| 1534 Handle<SignatureInfo>(SignatureInfo::cast(info->signature())); |
| 1734 if (!signature->args()->IsUndefined()) return; | 1535 if (!signature->args()->IsUndefined()) return; |
| 1735 if (!signature->receiver()->IsUndefined()) { | 1536 if (!signature->receiver()->IsUndefined()) { |
| 1736 expected_receiver_type_ = | 1537 expected_receiver_type_ = |
| 1737 FunctionTemplateInfo::cast(signature->receiver()); | 1538 Handle<FunctionTemplateInfo>( |
| 1539 FunctionTemplateInfo::cast(signature->receiver())); |
| 1738 } | 1540 } |
| 1739 } | 1541 } |
| 1740 | 1542 |
| 1741 is_simple_api_call_ = true; | 1543 is_simple_api_call_ = true; |
| 1742 } | 1544 } |
| 1743 | 1545 |
| 1744 | 1546 |
| 1745 } } // namespace v8::internal | 1547 } } // namespace v8::internal |
| OLD | NEW |