Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(839)

Side by Side Diff: src/stub-cache.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/stub-cache.h ('k') | src/token.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "arguments.h" 31 #include "arguments.h"
32 #include "ic-inl.h" 32 #include "ic-inl.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 #include "vm-state-inl.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 // ----------------------------------------------------------------------- 39 // -----------------------------------------------------------------------
39 // StubCache implementation. 40 // StubCache implementation.
40 41
41 42
42 StubCache::StubCache(Isolate* isolate) : isolate_(isolate) { 43 StubCache::StubCache(Isolate* isolate) : isolate_(isolate) {
43 ASSERT(isolate == Isolate::Current()); 44 ASSERT(isolate == Isolate::Current());
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 Object* result; 423 Object* result;
423 { MaybeObject* maybe_result = 424 { MaybeObject* maybe_result =
424 receiver->UpdateMapCodeCache(name, Code::cast(code)); 425 receiver->UpdateMapCodeCache(name, Code::cast(code));
425 if (!maybe_result->ToObject(&result)) return maybe_result; 426 if (!maybe_result->ToObject(&result)) return maybe_result;
426 } 427 }
427 } 428 }
428 return code; 429 return code;
429 } 430 }
430 431
431 432
433 MaybeObject* StubCache::ComputeKeyedLoadSpecialized(JSObject* receiver) {
434 Code::Flags flags =
435 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, NORMAL);
436 String* name = isolate_->heap()->KeyedLoadSpecialized_symbol();
437 Object* code = receiver->map()->FindInCodeCache(name, flags);
438 if (code->IsUndefined()) {
439 KeyedLoadStubCompiler compiler;
440 { MaybeObject* maybe_code = compiler.CompileLoadSpecialized(receiver);
441 if (!maybe_code->ToObject(&code)) return maybe_code;
442 }
443 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), 0));
444 Object* result;
445 { MaybeObject* maybe_result =
446 receiver->UpdateMapCodeCache(name, Code::cast(code));
447 if (!maybe_result->ToObject(&result)) return maybe_result;
448 }
449 }
450 return code;
451 }
452
453
432 MaybeObject* StubCache::ComputeStoreField(String* name, 454 MaybeObject* StubCache::ComputeStoreField(String* name,
433 JSObject* receiver, 455 JSObject* receiver,
434 int field_index, 456 int field_index,
435 Map* transition) { 457 Map* transition) {
436 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; 458 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
437 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type); 459 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type);
438 Object* code = receiver->map()->FindInCodeCache(name, flags); 460 Object* code = receiver->map()->FindInCodeCache(name, flags);
439 if (code->IsUndefined()) { 461 if (code->IsUndefined()) {
440 StoreStubCompiler compiler; 462 StoreStubCompiler compiler;
441 { MaybeObject* maybe_code = 463 { MaybeObject* maybe_code =
442 compiler.CompileStoreField(receiver, field_index, transition, name); 464 compiler.CompileStoreField(receiver, field_index, transition, name);
443 if (!maybe_code->ToObject(&code)) return maybe_code; 465 if (!maybe_code->ToObject(&code)) return maybe_code;
444 } 466 }
445 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); 467 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
446 Object* result; 468 Object* result;
447 { MaybeObject* maybe_result = 469 { MaybeObject* maybe_result =
448 receiver->UpdateMapCodeCache(name, Code::cast(code)); 470 receiver->UpdateMapCodeCache(name, Code::cast(code));
449 if (!maybe_result->ToObject(&result)) return maybe_result; 471 if (!maybe_result->ToObject(&result)) return maybe_result;
450 } 472 }
451 } 473 }
452 return code; 474 return code;
453 } 475 }
454 476
455 477
478 MaybeObject* StubCache::ComputeKeyedStoreSpecialized(JSObject* receiver) {
479 Code::Flags flags =
480 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, NORMAL);
481 String* name = isolate_->heap()->KeyedStoreSpecialized_symbol();
482 Object* code = receiver->map()->FindInCodeCache(name, flags);
483 if (code->IsUndefined()) {
484 KeyedStoreStubCompiler compiler;
485 { MaybeObject* maybe_code = compiler.CompileStoreSpecialized(receiver);
486 if (!maybe_code->ToObject(&code)) return maybe_code;
487 }
488 PROFILE(CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, Code::cast(code), 0));
489 Object* result;
490 { MaybeObject* maybe_result =
491 receiver->UpdateMapCodeCache(name, Code::cast(code));
492 if (!maybe_result->ToObject(&result)) return maybe_result;
493 }
494 }
495 return code;
496 }
497
498
456 MaybeObject* StubCache::ComputeStoreNormal() { 499 MaybeObject* StubCache::ComputeStoreNormal() {
457 return isolate_->builtins()->builtin(Builtins::StoreIC_Normal); 500 return isolate_->builtins()->builtin(Builtins::StoreIC_Normal);
458 } 501 }
459 502
460 503
461 MaybeObject* StubCache::ComputeStoreGlobal(String* name, 504 MaybeObject* StubCache::ComputeStoreGlobal(String* name,
462 GlobalObject* receiver, 505 GlobalObject* receiver,
463 JSGlobalPropertyCell* cell) { 506 JSGlobalPropertyCell* cell) {
464 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); 507 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
465 Object* code = receiver->map()->FindInCodeCache(name, flags); 508 Object* code = receiver->map()->FindInCodeCache(name, flags);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 String* name, 601 String* name,
559 Object* object, 602 Object* object,
560 JSObject* holder, 603 JSObject* holder,
561 JSFunction* function) { 604 JSFunction* function) {
562 // Compute the check type and the map. 605 // Compute the check type and the map.
563 InlineCacheHolderFlag cache_holder = 606 InlineCacheHolderFlag cache_holder =
564 IC::GetCodeCacheForObject(object, holder); 607 IC::GetCodeCacheForObject(object, holder);
565 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 608 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
566 609
567 // Compute check type based on receiver/holder. 610 // Compute check type based on receiver/holder.
568 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; 611 CheckType check = RECEIVER_MAP_CHECK;
569 if (object->IsString()) { 612 if (object->IsString()) {
570 check = StubCompiler::STRING_CHECK; 613 check = STRING_CHECK;
571 } else if (object->IsNumber()) { 614 } else if (object->IsNumber()) {
572 check = StubCompiler::NUMBER_CHECK; 615 check = NUMBER_CHECK;
573 } else if (object->IsBoolean()) { 616 } else if (object->IsBoolean()) {
574 check = StubCompiler::BOOLEAN_CHECK; 617 check = BOOLEAN_CHECK;
575 } 618 }
576 619
577 Code::Flags flags = 620 Code::Flags flags =
578 Code::ComputeMonomorphicFlags(kind, 621 Code::ComputeMonomorphicFlags(kind,
579 CONSTANT_FUNCTION, 622 CONSTANT_FUNCTION,
580 cache_holder, 623 cache_holder,
581 in_loop, 624 in_loop,
582 argc); 625 argc);
583 Object* code = map_holder->map()->FindInCodeCache(name, flags); 626 Object* code = map_holder->map()->FindInCodeCache(name, flags);
584 if (code->IsUndefined()) { 627 if (code->IsUndefined()) {
585 // If the function hasn't been compiled yet, we cannot do it now 628 // If the function hasn't been compiled yet, we cannot do it now
586 // because it may cause GC. To avoid this issue, we return an 629 // because it may cause GC. To avoid this issue, we return an
587 // internal error which will make sure we do not update any 630 // internal error which will make sure we do not update any
588 // caches. 631 // caches.
589 if (!function->is_compiled()) return Failure::InternalError(); 632 if (!function->is_compiled()) return Failure::InternalError();
590 // Compile the stub - only create stubs for fully compiled functions. 633 // Compile the stub - only create stubs for fully compiled functions.
591 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); 634 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
592 { MaybeObject* maybe_code = 635 { MaybeObject* maybe_code =
593 compiler.CompileCallConstant(object, holder, function, name, check); 636 compiler.CompileCallConstant(object, holder, function, name, check);
594 if (!maybe_code->ToObject(&code)) return maybe_code; 637 if (!maybe_code->ToObject(&code)) return maybe_code;
595 } 638 }
639 Code::cast(code)->set_check_type(check);
596 ASSERT_EQ(flags, Code::cast(code)->flags()); 640 ASSERT_EQ(flags, Code::cast(code)->flags());
597 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 641 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
598 Code::cast(code), name)); 642 Code::cast(code), name));
599 Object* result; 643 Object* result;
600 { MaybeObject* maybe_result = 644 { MaybeObject* maybe_result =
601 map_holder->UpdateMapCodeCache(name, Code::cast(code)); 645 map_holder->UpdateMapCodeCache(name, Code::cast(code));
602 if (!maybe_result->ToObject(&result)) return maybe_result; 646 if (!maybe_result->ToObject(&result)) return maybe_result;
603 } 647 }
604 } 648 }
605 return code; 649 return code;
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 Builtins::Illegal); 1001 Builtins::Illegal);
958 } 1002 }
959 for (int j = 0; j < kSecondaryTableSize; j++) { 1003 for (int j = 0; j < kSecondaryTableSize; j++) {
960 secondary_[j].key = isolate_->heap()->empty_string(); 1004 secondary_[j].key = isolate_->heap()->empty_string();
961 secondary_[j].value = isolate_->builtins()->builtin( 1005 secondary_[j].value = isolate_->builtins()->builtin(
962 Builtins::Illegal); 1006 Builtins::Illegal);
963 } 1007 }
964 } 1008 }
965 1009
966 1010
1011 void StubCache::CollectMatchingMaps(ZoneMapList* types,
1012 String* name,
1013 Code::Flags flags) {
1014 for (int i = 0; i < kPrimaryTableSize; i++) {
1015 if (primary_[i].key == name) {
1016 Map* map = primary_[i].value->FindFirstMap();
1017 // Map can be NULL, if the stub is constant function call
1018 // with a primitive receiver.
1019 if (map == NULL) continue;
1020
1021 int offset = PrimaryOffset(name, flags, map);
1022 if (entry(primary_, offset) == &primary_[i]) {
1023 types->Add(Handle<Map>(map));
1024 }
1025 }
1026 }
1027
1028 for (int i = 0; i < kSecondaryTableSize; i++) {
1029 if (secondary_[i].key == name) {
1030 Map* map = secondary_[i].value->FindFirstMap();
1031 // Map can be NULL, if the stub is constant function call
1032 // with a primitive receiver.
1033 if (map == NULL) continue;
1034
1035 // Lookup in primary table and skip duplicates.
1036 int primary_offset = PrimaryOffset(name, flags, map);
1037 Entry* primary_entry = entry(primary_, primary_offset);
1038 if (primary_entry->key == name) {
1039 Map* primary_map = primary_entry->value->FindFirstMap();
1040 if (map == primary_map) continue;
1041 }
1042
1043 // Lookup in secondary table and add matches.
1044 int offset = SecondaryOffset(name, flags, primary_offset);
1045 if (entry(secondary_, offset) == &secondary_[i]) {
1046 types->Add(Handle<Map>(map));
1047 }
1048 }
1049 }
1050 }
1051
1052
967 // ------------------------------------------------------------------------ 1053 // ------------------------------------------------------------------------
968 // StubCompiler implementation. 1054 // StubCompiler implementation.
969 1055
970 1056
971 MaybeObject* LoadCallbackProperty(RUNTIME_CALLING_CONVENTION) { 1057 MaybeObject* LoadCallbackProperty(RUNTIME_CALLING_CONVENTION) {
972 RUNTIME_GET_ISOLATE; 1058 RUNTIME_GET_ISOLATE;
973 ASSERT(args[0]->IsJSObject()); 1059 ASSERT(args[0]->IsJSObject());
974 ASSERT(args[1]->IsJSObject()); 1060 ASSERT(args[1]->IsJSObject());
975 AccessorInfo* callback = AccessorInfo::cast(args[3]); 1061 AccessorInfo* callback = AccessorInfo::cast(args[3]);
976 Address getter_address = v8::ToCData<Address>(callback->getter()); 1062 Address getter_address = v8::ToCData<Address>(callback->getter());
977 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); 1063 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
978 ASSERT(fun != NULL); 1064 ASSERT(fun != NULL);
979 v8::AccessorInfo info(&args[0]); 1065 v8::AccessorInfo info(&args[0]);
980 HandleScope scope(isolate); 1066 HandleScope scope(isolate);
981 v8::Handle<v8::Value> result; 1067 v8::Handle<v8::Value> result;
982 { 1068 {
983 // Leaving JavaScript. 1069 // Leaving JavaScript.
984 VMState state(isolate, EXTERNAL); 1070 VMState state(isolate, EXTERNAL);
985 #ifdef ENABLE_LOGGING_AND_PROFILING 1071 ExternalCallbackScope call_scope(isolate, getter_address);
986 state.set_external_callback(getter_address);
987 #endif
988 result = fun(v8::Utils::ToLocal(args.at<String>(4)), info); 1072 result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
989 } 1073 }
990 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1074 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
991 if (result.IsEmpty()) return HEAP->undefined_value(); 1075 if (result.IsEmpty()) return HEAP->undefined_value();
992 return *v8::Utils::OpenHandle(*result); 1076 return *v8::Utils::OpenHandle(*result);
993 } 1077 }
994 1078
995 1079
996 MaybeObject* StoreCallbackProperty(RUNTIME_CALLING_CONVENTION) { 1080 MaybeObject* StoreCallbackProperty(RUNTIME_CALLING_CONVENTION) {
997 RUNTIME_GET_ISOLATE; 1081 RUNTIME_GET_ISOLATE;
998 JSObject* recv = JSObject::cast(args[0]); 1082 JSObject* recv = JSObject::cast(args[0]);
999 AccessorInfo* callback = AccessorInfo::cast(args[1]); 1083 AccessorInfo* callback = AccessorInfo::cast(args[1]);
1000 Address setter_address = v8::ToCData<Address>(callback->setter()); 1084 Address setter_address = v8::ToCData<Address>(callback->setter());
1001 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); 1085 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
1002 ASSERT(fun != NULL); 1086 ASSERT(fun != NULL);
1003 Handle<String> name = args.at<String>(2); 1087 Handle<String> name = args.at<String>(2);
1004 Handle<Object> value = args.at<Object>(3); 1088 Handle<Object> value = args.at<Object>(3);
1005 HandleScope scope(isolate); 1089 HandleScope scope(isolate);
1006 LOG(ApiNamedPropertyAccess("store", recv, *name)); 1090 LOG(ApiNamedPropertyAccess("store", recv, *name));
1007 CustomArguments custom_args(isolate, callback->data(), recv, recv); 1091 CustomArguments custom_args(isolate, callback->data(), recv, recv);
1008 v8::AccessorInfo info(custom_args.end()); 1092 v8::AccessorInfo info(custom_args.end());
1009 { 1093 {
1010 // Leaving JavaScript. 1094 // Leaving JavaScript.
1011 VMState state(isolate, EXTERNAL); 1095 VMState state(isolate, EXTERNAL);
1012 #ifdef ENABLE_LOGGING_AND_PROFILING 1096 ExternalCallbackScope call_scope(isolate, setter_address);
1013 state.set_external_callback(setter_address);
1014 #endif
1015 fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); 1097 fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
1016 } 1098 }
1017 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1099 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1018 return *value; 1100 return *value;
1019 } 1101 }
1020 1102
1021 1103
1022 static const int kAccessorInfoOffsetInInterceptorArgs = 2; 1104 static const int kAccessorInfoOffsetInInterceptorArgs = 2;
1023 1105
1024 1106
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 expected_receiver_type_ = 1637 expected_receiver_type_ =
1556 FunctionTemplateInfo::cast(signature->receiver()); 1638 FunctionTemplateInfo::cast(signature->receiver());
1557 } 1639 }
1558 } 1640 }
1559 1641
1560 is_simple_api_call_ = true; 1642 is_simple_api_call_ = true;
1561 } 1643 }
1562 1644
1563 1645
1564 } } // namespace v8::internal 1646 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698