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

Side by Side Diff: src/ic/ic-compiler.cc

Issue 480413008: Move PropertyAccessCompiler and CallOptimization to their own files (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/x64/access-compiler-x64.cc » ('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 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/ic-inl.h" 8 #include "src/ic/ic-inl.h"
8 #include "src/ic/ic-compiler.h" 9 #include "src/ic/ic-compiler.h"
9 10
10 11
11 namespace v8 { 12 namespace v8 {
12 namespace internal { 13 namespace internal {
13 14
14 15
15 Handle<Code> PropertyICCompiler::Find(Handle<Name> name, 16 Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
16 Handle<Map> stub_holder, Code::Kind kind, 17 Handle<Map> stub_holder, Code::Kind kind,
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 Handle<Code> code = 172 Handle<Code> code =
172 compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode); 173 compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
173 174
174 Map::UpdateCodeCache(receiver_map, name, code); 175 Map::UpdateCodeCache(receiver_map, name, code);
175 DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) == 176 DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) ==
176 store_mode); 177 store_mode);
177 return code; 178 return code;
178 } 179 }
179 180
180 181
181 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
182
183
184 Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind, 182 Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
185 ExtraICState state) { 183 ExtraICState state) {
186 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 184 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
187 UnseededNumberDictionary* dictionary = 185 UnseededNumberDictionary* dictionary =
188 isolate->heap()->non_monomorphic_cache(); 186 isolate->heap()->non_monomorphic_cache();
189 int entry = dictionary->FindEntry(isolate, flags); 187 int entry = dictionary->FindEntry(isolate, flags);
190 DCHECK(entry != -1); 188 DCHECK(entry != -1);
191 Object* code = dictionary->ValueAt(entry); 189 Object* code = dictionary->ValueAt(entry);
192 // This might be called during the marking phase of the collector 190 // This might be called during the marking phase of the collector
193 // hence the unchecked cast. 191 // hence the unchecked cast.
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 393
396 394
397 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) { 395 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
398 StoreIC::GenerateMegamorphic(masm()); 396 StoreIC::GenerateMegamorphic(masm());
399 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); 397 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
400 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); 398 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
401 return code; 399 return code;
402 } 400 }
403 401
404 402
405 #undef CALL_LOGGER_TAG
406
407
408 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
409 const char* name) {
410 // Create code object in the heap.
411 CodeDesc desc;
412 masm()->GetCode(&desc);
413 Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject());
414 if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
415 #ifdef ENABLE_DISASSEMBLER
416 if (FLAG_print_code_stubs) {
417 OFStream os(stdout);
418 code->Disassemble(name, os);
419 }
420 #endif
421 return code;
422 }
423
424
425 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
426 Handle<Name> name) {
427 return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
428 ? GetCodeWithFlags(flags,
429 Handle<String>::cast(name)->ToCString().get())
430 : GetCodeWithFlags(flags, NULL);
431 }
432
433
434 #define __ ACCESS_MASM(masm()) 403 #define __ ACCESS_MASM(masm())
435 404
436 405
437 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, 406 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
438 Handle<Name> name, 407 Handle<Name> name,
439 Label* miss) { 408 Label* miss) {
440 PrototypeCheckType check_type = CHECK_ALL_MAPS; 409 PrototypeCheckType check_type = CHECK_ALL_MAPS;
441 int function_index = -1; 410 int function_index = -1;
442 if (type()->Is(HeapType::String())) { 411 if (type()->Is(HeapType::String())) {
443 function_index = Context::STRING_FUNCTION_INDEX; 412 function_index = Context::STRING_FUNCTION_INDEX;
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 717
749 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); 718 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
750 719
751 return GetCode(kind(), Code::NORMAL, factory()->empty_string()); 720 return GetCode(kind(), Code::NORMAL, factory()->empty_string());
752 } 721 }
753 722
754 723
755 #undef __ 724 #undef __
756 725
757 726
758 void PropertyAccessCompiler::TailCallBuiltin(MacroAssembler* masm,
759 Builtins::Name name) {
760 Handle<Code> code(masm->isolate()->builtins()->builtin(name));
761 GenerateTailCall(masm, code);
762 }
763
764
765 Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) {
766 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
767 return load_calling_convention();
768 }
769 DCHECK(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
770 return store_calling_convention();
771 }
772
773
774 Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type, 727 Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type,
775 Handle<Name> name, 728 Handle<Name> name,
776 InlineCacheState state) { 729 InlineCacheState state) {
777 Code::Flags flags = 730 Code::Flags flags =
778 Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder()); 731 Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder());
779 Handle<Code> code = GetCodeWithFlags(flags, name); 732 Handle<Code> code = GetCodeWithFlags(flags, name);
780 IC::RegisterWeakMapDependency(code); 733 IC::RegisterWeakMapDependency(code);
781 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 734 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
782 return code; 735 return code;
783 } 736 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 return code; 826 return code;
874 } 827 }
875 828
876 829
877 void ElementHandlerCompiler::GenerateStoreDictionaryElement( 830 void ElementHandlerCompiler::GenerateStoreDictionaryElement(
878 MacroAssembler* masm) { 831 MacroAssembler* masm) {
879 KeyedStoreIC::GenerateSlow(masm); 832 KeyedStoreIC::GenerateSlow(masm);
880 } 833 }
881 834
882 835
883 CallOptimization::CallOptimization(Handle<JSFunction> function) {
884 Initialize(function);
885 }
886
887
888 Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
889 Handle<Map> object_map, HolderLookup* holder_lookup) const {
890 DCHECK(is_simple_api_call());
891 if (!object_map->IsJSObjectMap()) {
892 *holder_lookup = kHolderNotFound;
893 return Handle<JSObject>::null();
894 }
895 if (expected_receiver_type_.is_null() ||
896 expected_receiver_type_->IsTemplateFor(*object_map)) {
897 *holder_lookup = kHolderIsReceiver;
898 return Handle<JSObject>::null();
899 }
900 while (true) {
901 if (!object_map->prototype()->IsJSObject()) break;
902 Handle<JSObject> prototype(JSObject::cast(object_map->prototype()));
903 if (!prototype->map()->is_hidden_prototype()) break;
904 object_map = handle(prototype->map());
905 if (expected_receiver_type_->IsTemplateFor(*object_map)) {
906 *holder_lookup = kHolderFound;
907 return prototype;
908 }
909 }
910 *holder_lookup = kHolderNotFound;
911 return Handle<JSObject>::null();
912 }
913
914
915 bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
916 Handle<JSObject> holder) const {
917 DCHECK(is_simple_api_call());
918 if (!receiver->IsJSObject()) return false;
919 Handle<Map> map(JSObject::cast(*receiver)->map());
920 HolderLookup holder_lookup;
921 Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
922 switch (holder_lookup) {
923 case kHolderNotFound:
924 return false;
925 case kHolderIsReceiver:
926 return true;
927 case kHolderFound:
928 if (api_holder.is_identical_to(holder)) return true;
929 // Check if holder is in prototype chain of api_holder.
930 {
931 JSObject* object = *api_holder;
932 while (true) {
933 Object* prototype = object->map()->prototype();
934 if (!prototype->IsJSObject()) return false;
935 if (prototype == *holder) return true;
936 object = JSObject::cast(prototype);
937 }
938 }
939 break;
940 }
941 UNREACHABLE();
942 return false;
943 }
944
945
946 void CallOptimization::Initialize(Handle<JSFunction> function) {
947 constant_function_ = Handle<JSFunction>::null();
948 is_simple_api_call_ = false;
949 expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
950 api_call_info_ = Handle<CallHandlerInfo>::null();
951
952 if (function.is_null() || !function->is_compiled()) return;
953
954 constant_function_ = function;
955 AnalyzePossibleApiFunction(function);
956 }
957
958
959 void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
960 if (!function->shared()->IsApiFunction()) return;
961 Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
962
963 // Require a C++ callback.
964 if (info->call_code()->IsUndefined()) return;
965 api_call_info_ =
966 Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
967
968 // Accept signatures that either have no restrictions at all or
969 // only have restrictions on the receiver.
970 if (!info->signature()->IsUndefined()) {
971 Handle<SignatureInfo> signature =
972 Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
973 if (!signature->args()->IsUndefined()) return;
974 if (!signature->receiver()->IsUndefined()) {
975 expected_receiver_type_ = Handle<FunctionTemplateInfo>(
976 FunctionTemplateInfo::cast(signature->receiver()));
977 }
978 }
979
980 is_simple_api_call_ = true;
981 }
982 } 836 }
983 } // namespace v8::internal 837 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/x64/access-compiler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698