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

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

Issue 143633007: A64: Synchronize with r18764. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/sweeper-thread.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind); 121 Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind);
122 122
123 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); 123 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_);
124 if (probe->IsCode()) return Handle<Code>::cast(probe); 124 if (probe->IsCode()) return Handle<Code>::cast(probe);
125 return Handle<Code>::null(); 125 return Handle<Code>::null();
126 } 126 }
127 127
128 128
129 Handle<Code> StubCache::ComputeMonomorphicIC( 129 Handle<Code> StubCache::ComputeMonomorphicIC(
130 Handle<Name> name, 130 Handle<Name> name,
131 Handle<Type> type, 131 Handle<HeapType> type,
132 Handle<Code> handler, 132 Handle<Code> handler,
133 ExtraICState extra_ic_state) { 133 ExtraICState extra_ic_state) {
134 Code::Kind kind = handler->handler_kind(); 134 Code::Kind kind = handler->handler_kind();
135 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); 135 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
136 136
137 Handle<Map> stub_holder; 137 Handle<Map> stub_holder;
138 Handle<Code> ic; 138 Handle<Code> ic;
139 // There are multiple string maps that all use the same prototype. That 139 // There are multiple string maps that all use the same prototype. That
140 // prototype cannot hold multiple handlers, one for each of the string maps, 140 // prototype cannot hold multiple handlers, one for each of the string maps,
141 // for a single name. Hence, turn off caching of the IC. 141 // for a single name. Hence, turn off caching of the IC.
142 bool can_be_cached = !type->Is(Type::String()); 142 bool can_be_cached = !type->Is(HeapType::String());
143 if (can_be_cached) { 143 if (can_be_cached) {
144 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); 144 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
145 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag); 145 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag);
146 if (!ic.is_null()) return ic; 146 if (!ic.is_null()) return ic;
147 } 147 }
148 148
149 if (kind == Code::LOAD_IC) { 149 if (kind == Code::LOAD_IC) {
150 LoadStubCompiler ic_compiler(isolate(), extra_ic_state, flag); 150 LoadStubCompiler ic_compiler(isolate(), extra_ic_state, flag);
151 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); 151 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
152 } else if (kind == Code::KEYED_LOAD_IC) { 152 } else if (kind == Code::KEYED_LOAD_IC) {
153 KeyedLoadStubCompiler ic_compiler(isolate(), extra_ic_state, flag); 153 KeyedLoadStubCompiler ic_compiler(isolate(), extra_ic_state, flag);
154 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); 154 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
155 } else if (kind == Code::STORE_IC) { 155 } else if (kind == Code::STORE_IC) {
156 StoreStubCompiler ic_compiler(isolate(), extra_ic_state); 156 StoreStubCompiler ic_compiler(isolate(), extra_ic_state);
157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); 157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
158 } else { 158 } else {
159 ASSERT(kind == Code::KEYED_STORE_IC); 159 ASSERT(kind == Code::KEYED_STORE_IC);
160 ASSERT(STANDARD_STORE == 160 ASSERT(STANDARD_STORE ==
161 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); 161 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
162 KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state); 162 KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state);
163 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); 163 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
164 } 164 }
165 165
166 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); 166 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
167 return ic; 167 return ic;
168 } 168 }
169 169
170 170
171 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, 171 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
172 Handle<Type> type) { 172 Handle<HeapType> type) {
173 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); 173 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
174 Handle<Map> stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); 174 Handle<Map> stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
175 // If no dictionary mode objects are present in the prototype chain, the load 175 // If no dictionary mode objects are present in the prototype chain, the load
176 // nonexistent IC stub can be shared for all names for a given map and we use 176 // nonexistent IC stub can be shared for all names for a given map and we use
177 // the empty string for the map cache in that case. If there are dictionary 177 // the empty string for the map cache in that case. If there are dictionary
178 // mode objects involved, we need to do negative lookups in the stub and 178 // mode objects involved, we need to do negative lookups in the stub and
179 // therefore the stub will be specific to the name. 179 // therefore the stub will be specific to the name.
180 Handle<Map> current_map = stub_holder; 180 Handle<Map> current_map = stub_holder;
181 Handle<Name> cache_name = current_map->is_dictionary_map() 181 Handle<Name> cache_name = current_map->is_dictionary_map()
182 ? name : Handle<Name>::cast(isolate()->factory()->empty_string()); 182 ? name : Handle<Name>::cast(isolate()->factory()->empty_string());
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 290
291 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 291 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
292 Handle<Code> code = 292 Handle<Code> code =
293 compiler.CompileCallConstant(object, holder, name, check, function); 293 compiler.CompileCallConstant(object, holder, name, check, function);
294 code->set_check_type(check); 294 code->set_check_type(check);
295 ASSERT(flags == code->flags()); 295 ASSERT(flags == code->flags());
296 PROFILE(isolate_, 296 PROFILE(isolate_,
297 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 297 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
298 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 298 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
299 299
300 if (CallStubCompiler::CanBeCached(function)) { 300 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
301 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
302 }
303 return code; 301 return code;
304 } 302 }
305 303
306 304
307 Handle<Code> StubCache::ComputeCallField(int argc, 305 Handle<Code> StubCache::ComputeCallField(int argc,
308 Code::Kind kind, 306 Code::Kind kind,
309 ExtraICState extra_state, 307 ExtraICState extra_state,
310 Handle<Name> name, 308 Handle<Name> name,
311 Handle<Object> object, 309 Handle<Object> object,
312 Handle<JSObject> holder, 310 Handle<JSObject> holder,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 isolate_); 393 isolate_);
396 if (probe->IsCode()) return Handle<Code>::cast(probe); 394 if (probe->IsCode()) return Handle<Code>::cast(probe);
397 395
398 CallStubCompiler compiler(isolate(), argc, kind, extra_state); 396 CallStubCompiler compiler(isolate(), argc, kind, extra_state);
399 Handle<Code> code = 397 Handle<Code> code =
400 compiler.CompileCallGlobal(receiver, holder, cell, function, name); 398 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
401 ASSERT(flags == code->flags()); 399 ASSERT(flags == code->flags());
402 PROFILE(isolate(), 400 PROFILE(isolate(),
403 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 401 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
404 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 402 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
405 if (CallStubCompiler::CanBeCached(function)) { 403 HeapObject::UpdateMapCodeCache(receiver, name, code);
406 HeapObject::UpdateMapCodeCache(receiver, name, code);
407 }
408 return code; 404 return code;
409 } 405 }
410 406
411 407
412 static void FillCache(Isolate* isolate, Handle<Code> code) { 408 static void FillCache(Isolate* isolate, Handle<Code> code) {
413 Handle<UnseededNumberDictionary> dictionary = 409 Handle<UnseededNumberDictionary> dictionary =
414 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 410 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
415 code->flags(), 411 code->flags(),
416 code); 412 code);
417 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 413 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
418 } 414 }
419 415
420 416
421 Code* StubCache::FindCallInitialize(int argc, Code::Kind kind) { 417 Code* StubCache::FindCallInitialize(int argc, Code::Kind kind) {
422 ExtraICState extra_state = 418 Code::Flags flags = Code::ComputeFlags(
423 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB); 419 kind, UNINITIALIZED, kNoExtraICState, Code::NORMAL, argc);
424 Code::Flags flags =
425 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
426 UnseededNumberDictionary* dictionary = 420 UnseededNumberDictionary* dictionary =
427 isolate()->heap()->non_monomorphic_cache(); 421 isolate()->heap()->non_monomorphic_cache();
428 int entry = dictionary->FindEntry(isolate(), flags); 422 int entry = dictionary->FindEntry(isolate(), flags);
429 ASSERT(entry != -1); 423 ASSERT(entry != -1);
430 Object* code = dictionary->ValueAt(entry); 424 Object* code = dictionary->ValueAt(entry);
431 // This might be called during the marking phase of the collector 425 // This might be called during the marking phase of the collector
432 // hence the unchecked cast. 426 // hence the unchecked cast.
433 return reinterpret_cast<Code*>(code); 427 return reinterpret_cast<Code*>(code);
434 } 428 }
435 429
436 430
437 Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) { 431 Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) {
438 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 432 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
439 UnseededNumberDictionary* dictionary = 433 UnseededNumberDictionary* dictionary =
440 isolate()->heap()->non_monomorphic_cache(); 434 isolate()->heap()->non_monomorphic_cache();
441 int entry = dictionary->FindEntry(isolate(), flags); 435 int entry = dictionary->FindEntry(isolate(), flags);
442 ASSERT(entry != -1); 436 ASSERT(entry != -1);
443 Object* code = dictionary->ValueAt(entry); 437 Object* code = dictionary->ValueAt(entry);
444 // This might be called during the marking phase of the collector 438 // This might be called during the marking phase of the collector
445 // hence the unchecked cast. 439 // hence the unchecked cast.
446 return reinterpret_cast<Code*>(code); 440 return reinterpret_cast<Code*>(code);
447 } 441 }
448 442
449 443
450 Handle<Code> StubCache::ComputeCallInitialize(int argc, Code::Kind kind) { 444 Handle<Code> StubCache::ComputeCallInitialize(int argc, Code::Kind kind) {
451 ExtraICState extra_state = 445 Code::Flags flags = Code::ComputeFlags(
452 CallICBase::ComputeExtraICState(DEFAULT_STRING_STUB); 446 kind, UNINITIALIZED, kNoExtraICState, Code::NORMAL, argc);
453 Code::Flags flags =
454 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
455 Handle<UnseededNumberDictionary> cache = 447 Handle<UnseededNumberDictionary> cache =
456 isolate_->factory()->non_monomorphic_cache(); 448 isolate_->factory()->non_monomorphic_cache();
457 int entry = cache->FindEntry(isolate_, flags); 449 int entry = cache->FindEntry(isolate_, flags);
458 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 450 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
459 451
460 StubCompiler compiler(isolate_); 452 StubCompiler compiler(isolate_);
461 Handle<Code> code = compiler.CompileCallInitialize(flags); 453 Handle<Code> code = compiler.CompileCallInitialize(flags);
462 FillCache(isolate_, code); 454 FillCache(isolate_, code);
463 return code; 455 return code;
464 } 456 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 Handle<Code> StubCache::ComputeLoadElementPolymorphic( 631 Handle<Code> StubCache::ComputeLoadElementPolymorphic(
640 MapHandleList* receiver_maps) { 632 MapHandleList* receiver_maps) {
641 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 633 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
642 Handle<PolymorphicCodeCache> cache = 634 Handle<PolymorphicCodeCache> cache =
643 isolate_->factory()->polymorphic_code_cache(); 635 isolate_->factory()->polymorphic_code_cache();
644 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 636 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
645 if (probe->IsCode()) return Handle<Code>::cast(probe); 637 if (probe->IsCode()) return Handle<Code>::cast(probe);
646 638
647 TypeHandleList types(receiver_maps->length()); 639 TypeHandleList types(receiver_maps->length());
648 for (int i = 0; i < receiver_maps->length(); i++) { 640 for (int i = 0; i < receiver_maps->length(); i++) {
649 types.Add(Type::Class(receiver_maps->at(i), isolate())); 641 types.Add(HeapType::Class(receiver_maps->at(i), isolate()));
650 } 642 }
651 CodeHandleList handlers(receiver_maps->length()); 643 CodeHandleList handlers(receiver_maps->length());
652 KeyedLoadStubCompiler compiler(isolate_); 644 KeyedLoadStubCompiler compiler(isolate_);
653 compiler.CompileElementHandlers(receiver_maps, &handlers); 645 compiler.CompileElementHandlers(receiver_maps, &handlers);
654 Handle<Code> code = compiler.CompilePolymorphicIC( 646 Handle<Code> code = compiler.CompilePolymorphicIC(
655 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); 647 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT);
656 648
657 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); 649 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
658 650
659 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 651 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 } 795 }
804 } 796 }
805 } 797 }
806 798
807 799
808 // ------------------------------------------------------------------------ 800 // ------------------------------------------------------------------------
809 // StubCompiler implementation. 801 // StubCompiler implementation.
810 802
811 803
812 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) { 804 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
813 JSObject* recv = JSObject::cast(args[0]); 805 JSObject* receiver = JSObject::cast(args[0]);
814 ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[1]); 806 JSObject* holder = JSObject::cast(args[1]);
807 ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[2]);
815 Address setter_address = v8::ToCData<Address>(callback->setter()); 808 Address setter_address = v8::ToCData<Address>(callback->setter());
816 v8::AccessorSetterCallback fun = 809 v8::AccessorSetterCallback fun =
817 FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address); 810 FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
818 ASSERT(fun != NULL); 811 ASSERT(fun != NULL);
819 ASSERT(callback->IsCompatibleReceiver(recv)); 812 ASSERT(callback->IsCompatibleReceiver(receiver));
820 Handle<Name> name = args.at<Name>(2); 813 Handle<Name> name = args.at<Name>(3);
821 Handle<Object> value = args.at<Object>(3); 814 Handle<Object> value = args.at<Object>(4);
822 HandleScope scope(isolate); 815 HandleScope scope(isolate);
823 816
824 // TODO(rossberg): Support symbols in the API. 817 // TODO(rossberg): Support symbols in the API.
825 if (name->IsSymbol()) return *value; 818 if (name->IsSymbol()) return *value;
826 Handle<String> str = Handle<String>::cast(name); 819 Handle<String> str = Handle<String>::cast(name);
827 820
828 LOG(isolate, ApiNamedPropertyAccess("store", recv, *name)); 821 LOG(isolate, ApiNamedPropertyAccess("store", receiver, *name));
829 PropertyCallbackArguments 822 PropertyCallbackArguments
830 custom_args(isolate, callback->data(), recv, recv); 823 custom_args(isolate, callback->data(), receiver, holder);
831 custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value)); 824 custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
832 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 825 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
833 return *value; 826 return *value;
834 } 827 }
835 828
836 829
837 /** 830 /**
838 * Attempts to load a property with an interceptor (which must be present), 831 * Attempts to load a property with an interceptor (which must be present),
839 * but doesn't search the prototype chain. 832 * but doesn't search the prototype chain.
840 * 833 *
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 return *v8::Utils::OpenHandle(*r); 869 return *v8::Utils::OpenHandle(*r);
877 } 870 }
878 } 871 }
879 872
880 return isolate->heap()->no_interceptor_result_sentinel(); 873 return isolate->heap()->no_interceptor_result_sentinel();
881 } 874 }
882 875
883 876
884 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) { 877 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
885 // If the load is non-contextual, just return the undefined result. 878 // If the load is non-contextual, just return the undefined result.
886 // Note that both keyed and non-keyed loads may end up here, so we 879 // Note that both keyed and non-keyed loads may end up here.
887 // can't use either LoadIC or KeyedLoadIC constructors.
888 HandleScope scope(isolate); 880 HandleScope scope(isolate);
889 IC ic(IC::NO_EXTRA_FRAME, isolate); 881 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
890 ASSERT(ic.IsLoadStub()); 882 if (ic.contextual_mode() != CONTEXTUAL) {
891 if (!ic.IsContextual()) {
892 return isolate->heap()->undefined_value(); 883 return isolate->heap()->undefined_value();
893 } 884 }
894 885
895 // Throw a reference error. 886 // Throw a reference error.
896 Handle<Name> name_handle(name); 887 Handle<Name> name_handle(name);
897 Handle<Object> error = 888 Handle<Object> error =
898 isolate->factory()->NewReferenceError("not_defined", 889 isolate->factory()->NewReferenceError("not_defined",
899 HandleVector(&name_handle, 1)); 890 HandleVector(&name_handle, 1));
900 return isolate->Throw(*error); 891 return isolate->Throw(*error);
901 } 892 }
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 *code, code->arguments_count())); 1031 *code, code->arguments_count()));
1041 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code)); 1032 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
1042 return code; 1033 return code;
1043 } 1034 }
1044 1035
1045 1036
1046 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) { 1037 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
1047 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1038 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1048 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1039 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1049 if (kind == Code::CALL_IC) { 1040 if (kind == Code::CALL_IC) {
1050 // Call normal is always with a explict receiver.
1051 ASSERT(!CallIC::Contextual::decode(
1052 Code::ExtractExtraICStateFromFlags(flags)));
1053 CallIC::GenerateNormal(masm(), argc); 1041 CallIC::GenerateNormal(masm(), argc);
1054 } else { 1042 } else {
1055 KeyedCallIC::GenerateNormal(masm(), argc); 1043 KeyedCallIC::GenerateNormal(masm(), argc);
1056 } 1044 }
1057 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal"); 1045 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal");
1058 isolate()->counters()->call_normal_stubs()->Increment(); 1046 isolate()->counters()->call_normal_stubs()->Increment();
1059 PROFILE(isolate(), 1047 PROFILE(isolate(),
1060 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), 1048 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1061 *code, code->arguments_count())); 1049 *code, code->arguments_count()));
1062 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); 1050 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); 1086 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic");
1099 PROFILE(isolate(), 1087 PROFILE(isolate(),
1100 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); 1088 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0));
1101 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); 1089 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code));
1102 return code; 1090 return code;
1103 } 1091 }
1104 1092
1105 1093
1106 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) { 1094 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) {
1107 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 1095 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1108 ContextualMode mode = IC::GetContextualMode(extra_state); 1096 ContextualMode mode = LoadIC::GetContextualMode(extra_state);
1109 LoadIC::GenerateMegamorphic(masm(), mode); 1097 LoadIC::GenerateMegamorphic(masm(), mode);
1110 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); 1098 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic");
1111 PROFILE(isolate(), 1099 PROFILE(isolate(),
1112 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0)); 1100 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
1113 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); 1101 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code));
1114 return code; 1102 return code;
1115 } 1103 }
1116 1104
1117 1105
1118 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) { 1106 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, 1275 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
1288 Register actual_closure, 1276 Register actual_closure,
1289 Handle<JSFunction> function) { 1277 Handle<JSFunction> function) {
1290 PatchImplicitReceiver(object); 1278 PatchImplicitReceiver(object);
1291 ParameterCount expected(function); 1279 ParameterCount expected(function);
1292 __ InvokeFunction(actual_closure, expected, arguments(), 1280 __ InvokeFunction(actual_closure, expected, arguments(),
1293 JUMP_FUNCTION, NullCallWrapper()); 1281 JUMP_FUNCTION, NullCallWrapper());
1294 } 1282 }
1295 1283
1296 1284
1285 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1286 Handle<Object> object,
1287 Handle<JSObject> holder,
1288 Handle<Cell> cell,
1289 Handle<JSFunction> function,
1290 Handle<String> name,
1291 Code::StubType type) {
1292 // If object is not an array or is observed or sealed, bail out to regular
1293 // call.
1294 if (!object->IsJSArray() ||
1295 !cell.is_null() ||
1296 Handle<JSArray>::cast(object)->map()->is_observed() ||
1297 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1298 return Handle<Code>::null();
1299 }
1300
1301 Label miss;
1302
1303 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1304
1305 Handle<Map> map(Handle<JSArray>::cast(object)->map());
1306 ElementsKind elements_kind = map->elements_kind();
1307 const int argc = arguments().immediate();
1308
1309 ArrayPushStub stub(elements_kind, argc);
1310 Handle<Code> code = stub.GetCode(isolate());
1311 StubCompiler::GenerateTailCall(masm(), code);
1312
1313 HandlerFrontendFooter(&miss);
1314
1315 // Return the generated code.
1316 return GetCode(type, name);
1317 }
1318
1319
1297 Handle<Code> CallStubCompiler::CompileCallConstant( 1320 Handle<Code> CallStubCompiler::CompileCallConstant(
1298 Handle<Object> object, 1321 Handle<Object> object,
1299 Handle<JSObject> holder, 1322 Handle<JSObject> holder,
1300 Handle<Name> name, 1323 Handle<Name> name,
1301 CheckType check, 1324 CheckType check,
1302 Handle<JSFunction> function) { 1325 Handle<JSFunction> function) {
1303 if (HasCustomCallGenerator(function)) { 1326 if (HasCustomCallGenerator(function)) {
1304 Handle<Code> code = CompileCustomCall(object, holder, 1327 Handle<Code> code = CompileCustomCall(object, holder,
1305 Handle<Cell>::null(), 1328 Handle<Cell>::null(),
1306 function, Handle<String>::cast(name), 1329 function, Handle<String>::cast(name),
1307 Code::FAST); 1330 Code::FAST);
1308 // A null handle means bail out to the regular compiler code below. 1331 // A null handle means bail out to the regular compiler code below.
1309 if (!code.is_null()) return code; 1332 if (!code.is_null()) return code;
1310 } 1333 }
1311 1334
1312 Label miss; 1335 Label miss;
1313 HandlerFrontendHeader(object, holder, name, check, &miss); 1336 HandlerFrontendHeader(object, holder, name, check, &miss);
1314 GenerateJumpFunction(object, function); 1337 GenerateJumpFunction(object, function);
1315 HandlerFrontendFooter(&miss); 1338 HandlerFrontendFooter(&miss);
1316 1339
1317 // Return the generated code. 1340 // Return the generated code.
1318 return GetCode(function); 1341 return GetCode(function);
1319 } 1342 }
1320 1343
1321 1344
1322 Register LoadStubCompiler::HandlerFrontendHeader( 1345 Register LoadStubCompiler::HandlerFrontendHeader(
1323 Handle<Type> type, 1346 Handle<HeapType> type,
1324 Register object_reg, 1347 Register object_reg,
1325 Handle<JSObject> holder, 1348 Handle<JSObject> holder,
1326 Handle<Name> name, 1349 Handle<Name> name,
1327 Label* miss) { 1350 Label* miss) {
1328 PrototypeCheckType check_type = CHECK_ALL_MAPS; 1351 PrototypeCheckType check_type = CHECK_ALL_MAPS;
1329 int function_index = -1; 1352 int function_index = -1;
1330 if (type->Is(Type::String())) { 1353 if (type->Is(HeapType::String())) {
1331 function_index = Context::STRING_FUNCTION_INDEX; 1354 function_index = Context::STRING_FUNCTION_INDEX;
1332 } else if (type->Is(Type::Symbol())) { 1355 } else if (type->Is(HeapType::Symbol())) {
1333 function_index = Context::SYMBOL_FUNCTION_INDEX; 1356 function_index = Context::SYMBOL_FUNCTION_INDEX;
1334 } else if (type->Is(Type::Number())) { 1357 } else if (type->Is(HeapType::Number())) {
1335 function_index = Context::NUMBER_FUNCTION_INDEX; 1358 function_index = Context::NUMBER_FUNCTION_INDEX;
1336 } else if (type->Is(Type::Boolean())) { 1359 } else if (type->Is(HeapType::Boolean())) {
1337 // Booleans use the generic oddball map, so an additional check is needed to 1360 // Booleans use the generic oddball map, so an additional check is needed to
1338 // ensure the receiver is really a boolean. 1361 // ensure the receiver is really a boolean.
1339 GenerateBooleanCheck(object_reg, miss); 1362 GenerateBooleanCheck(object_reg, miss);
1340 function_index = Context::BOOLEAN_FUNCTION_INDEX; 1363 function_index = Context::BOOLEAN_FUNCTION_INDEX;
1341 } else { 1364 } else {
1342 check_type = SKIP_RECEIVER; 1365 check_type = SKIP_RECEIVER;
1343 } 1366 }
1344 1367
1345 if (check_type == CHECK_ALL_MAPS) { 1368 if (check_type == CHECK_ALL_MAPS) {
1346 GenerateDirectLoadGlobalFunctionPrototype( 1369 GenerateDirectLoadGlobalFunctionPrototype(
1347 masm(), function_index, scratch1(), miss); 1370 masm(), function_index, scratch1(), miss);
1348 Object* function = isolate()->native_context()->get(function_index); 1371 Object* function = isolate()->native_context()->get(function_index);
1349 Object* prototype = JSFunction::cast(function)->instance_prototype(); 1372 Object* prototype = JSFunction::cast(function)->instance_prototype();
1350 type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate()); 1373 type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate());
1351 object_reg = scratch1(); 1374 object_reg = scratch1();
1352 } 1375 }
1353 1376
1354 // Check that the maps starting from the prototype haven't changed. 1377 // Check that the maps starting from the prototype haven't changed.
1355 return CheckPrototypes( 1378 return CheckPrototypes(
1356 type, object_reg, holder, scratch1(), scratch2(), scratch3(), 1379 type, object_reg, holder, scratch1(), scratch2(), scratch3(),
1357 name, miss, check_type); 1380 name, miss, check_type);
1358 } 1381 }
1359 1382
1360 1383
1361 // HandlerFrontend for store uses the name register. It has to be restored 1384 // HandlerFrontend for store uses the name register. It has to be restored
1362 // before a miss. 1385 // before a miss.
1363 Register StoreStubCompiler::HandlerFrontendHeader( 1386 Register StoreStubCompiler::HandlerFrontendHeader(
1364 Handle<Type> type, 1387 Handle<HeapType> type,
1365 Register object_reg, 1388 Register object_reg,
1366 Handle<JSObject> holder, 1389 Handle<JSObject> holder,
1367 Handle<Name> name, 1390 Handle<Name> name,
1368 Label* miss) { 1391 Label* miss) {
1369 return CheckPrototypes(type, object_reg, holder, this->name(), 1392 return CheckPrototypes(type, object_reg, holder, this->name(),
1370 scratch1(), scratch2(), name, miss, SKIP_RECEIVER); 1393 scratch1(), scratch2(), name, miss, SKIP_RECEIVER);
1371 } 1394 }
1372 1395
1373 1396
1374 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { 1397 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) {
1375 for (int i = 0; i < types->length(); ++i) { 1398 for (int i = 0; i < types->length(); ++i) {
1376 if (types->at(i)->Is(Type::Number())) return true; 1399 if (types->at(i)->Is(HeapType::Number())) return true;
1377 } 1400 }
1378 return false; 1401 return false;
1379 } 1402 }
1380 1403
1381 1404
1382 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Type> type, 1405 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<HeapType> type,
1383 Register object_reg, 1406 Register object_reg,
1384 Handle<JSObject> holder, 1407 Handle<JSObject> holder,
1385 Handle<Name> name) { 1408 Handle<Name> name) {
1386 Label miss; 1409 Label miss;
1387 1410
1388 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 1411 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
1389 1412
1390 HandlerFrontendFooter(name, &miss); 1413 HandlerFrontendFooter(name, &miss);
1391 1414
1392 return reg; 1415 return reg;
1393 } 1416 }
1394 1417
1395 1418
1396 void LoadStubCompiler::NonexistentHandlerFrontend(Handle<Type> type, 1419 void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type,
1397 Handle<JSObject> last, 1420 Handle<JSObject> last,
1398 Handle<Name> name) { 1421 Handle<Name> name) {
1399 Label miss; 1422 Label miss;
1400 1423
1401 Register holder; 1424 Register holder;
1402 Handle<Map> last_map; 1425 Handle<Map> last_map;
1403 if (last.is_null()) { 1426 if (last.is_null()) {
1404 holder = receiver(); 1427 holder = receiver();
1405 last_map = IC::TypeToMap(*type, isolate()); 1428 last_map = IC::TypeToMap(*type, isolate());
1406 // If |type| has null as its prototype, |last| is Handle<JSObject>::null(). 1429 // If |type| has null as its prototype, |last| is Handle<JSObject>::null().
(...skipping 24 matching lines...) Expand all
1431 ? Handle<JSGlobalObject>::cast(type->AsConstant()) 1454 ? Handle<JSGlobalObject>::cast(type->AsConstant())
1432 : Handle<JSGlobalObject>::cast(last); 1455 : Handle<JSGlobalObject>::cast(last);
1433 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1456 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1434 } 1457 }
1435 1458
1436 HandlerFrontendFooter(name, &miss); 1459 HandlerFrontendFooter(name, &miss);
1437 } 1460 }
1438 1461
1439 1462
1440 Handle<Code> LoadStubCompiler::CompileLoadField( 1463 Handle<Code> LoadStubCompiler::CompileLoadField(
1441 Handle<Type> type, 1464 Handle<HeapType> type,
1442 Handle<JSObject> holder, 1465 Handle<JSObject> holder,
1443 Handle<Name> name, 1466 Handle<Name> name,
1444 PropertyIndex field, 1467 PropertyIndex field,
1445 Representation representation) { 1468 Representation representation) {
1446 Label miss; 1469 Label miss;
1447 1470
1448 Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss); 1471 Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss);
1449 1472
1450 GenerateLoadField(reg, holder, field, representation); 1473 GenerateLoadField(reg, holder, field, representation);
1451 1474
1452 __ bind(&miss); 1475 __ bind(&miss);
1453 TailCallBuiltin(masm(), MissBuiltin(kind())); 1476 TailCallBuiltin(masm(), MissBuiltin(kind()));
1454 1477
1455 // Return the generated code. 1478 // Return the generated code.
1456 return GetCode(kind(), Code::FAST, name); 1479 return GetCode(kind(), Code::FAST, name);
1457 } 1480 }
1458 1481
1459 1482
1460 Handle<Code> LoadStubCompiler::CompileLoadConstant( 1483 Handle<Code> LoadStubCompiler::CompileLoadConstant(
1461 Handle<Type> type, 1484 Handle<HeapType> type,
1462 Handle<JSObject> holder, 1485 Handle<JSObject> holder,
1463 Handle<Name> name, 1486 Handle<Name> name,
1464 Handle<Object> value) { 1487 Handle<Object> value) {
1465 HandlerFrontend(type, receiver(), holder, name); 1488 HandlerFrontend(type, receiver(), holder, name);
1466 GenerateLoadConstant(value); 1489 GenerateLoadConstant(value);
1467 1490
1468 // Return the generated code. 1491 // Return the generated code.
1469 return GetCode(kind(), Code::FAST, name); 1492 return GetCode(kind(), Code::FAST, name);
1470 } 1493 }
1471 1494
1472 1495
1473 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1496 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1474 Handle<Type> type, 1497 Handle<HeapType> type,
1475 Handle<JSObject> holder, 1498 Handle<JSObject> holder,
1476 Handle<Name> name, 1499 Handle<Name> name,
1477 Handle<ExecutableAccessorInfo> callback) { 1500 Handle<ExecutableAccessorInfo> callback) {
1478 Register reg = CallbackHandlerFrontend( 1501 Register reg = CallbackHandlerFrontend(
1479 type, receiver(), holder, name, callback); 1502 type, receiver(), holder, name, callback);
1480 GenerateLoadCallback(reg, callback); 1503 GenerateLoadCallback(reg, callback);
1481 1504
1482 // Return the generated code. 1505 // Return the generated code.
1483 return GetCode(kind(), Code::FAST, name); 1506 return GetCode(kind(), Code::FAST, name);
1484 } 1507 }
1485 1508
1486 1509
1487 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1510 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1488 Handle<Type> type, 1511 Handle<HeapType> type,
1489 Handle<JSObject> holder, 1512 Handle<JSObject> holder,
1490 Handle<Name> name, 1513 Handle<Name> name,
1491 const CallOptimization& call_optimization) { 1514 const CallOptimization& call_optimization) {
1492 ASSERT(call_optimization.is_simple_api_call()); 1515 ASSERT(call_optimization.is_simple_api_call());
1493 Handle<JSFunction> callback = call_optimization.constant_function(); 1516 Handle<JSFunction> callback = call_optimization.constant_function();
1494 CallbackHandlerFrontend(type, receiver(), holder, name, callback); 1517 CallbackHandlerFrontend(type, receiver(), holder, name, callback);
1495 GenerateLoadCallback(call_optimization); 1518 GenerateLoadCallback(call_optimization);
1496 1519
1497 // Return the generated code. 1520 // Return the generated code.
1498 return GetCode(kind(), Code::FAST, name); 1521 return GetCode(kind(), Code::FAST, name);
1499 } 1522 }
1500 1523
1501 1524
1502 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( 1525 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(
1503 Handle<Type> type, 1526 Handle<HeapType> type,
1504 Handle<JSObject> holder, 1527 Handle<JSObject> holder,
1505 Handle<Name> name) { 1528 Handle<Name> name) {
1506 LookupResult lookup(isolate()); 1529 LookupResult lookup(isolate());
1507 LookupPostInterceptor(holder, name, &lookup); 1530 LookupPostInterceptor(holder, name, &lookup);
1508 1531
1509 Register reg = HandlerFrontend(type, receiver(), holder, name); 1532 Register reg = HandlerFrontend(type, receiver(), holder, name);
1510 // TODO(368): Compile in the whole chain: all the interceptors in 1533 // TODO(368): Compile in the whole chain: all the interceptors in
1511 // prototypes and ultimate answer. 1534 // prototypes and ultimate answer.
1512 GenerateLoadInterceptor(reg, type, holder, &lookup, name); 1535 GenerateLoadInterceptor(reg, type, holder, &lookup, name);
1513 1536
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 1569
1547 Register reg = CallbackHandlerFrontend( 1570 Register reg = CallbackHandlerFrontend(
1548 IC::CurrentTypeOf(interceptor_holder, isolate()), 1571 IC::CurrentTypeOf(interceptor_holder, isolate()),
1549 interceptor_reg, holder, name, callback); 1572 interceptor_reg, holder, name, callback);
1550 GenerateLoadCallback(reg, callback); 1573 GenerateLoadCallback(reg, callback);
1551 } 1574 }
1552 } 1575 }
1553 1576
1554 1577
1555 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( 1578 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
1556 Handle<Type> type, 1579 Handle<HeapType> type,
1557 Handle<Code> handler, 1580 Handle<Code> handler,
1558 Handle<Name> name) { 1581 Handle<Name> name) {
1559 TypeHandleList types(1); 1582 TypeHandleList types(1);
1560 CodeHandleList handlers(1); 1583 CodeHandleList handlers(1);
1561 types.Add(type); 1584 types.Add(type);
1562 handlers.Add(handler); 1585 handlers.Add(handler);
1563 Code::StubType stub_type = handler->type(); 1586 Code::StubType stub_type = handler->type();
1564 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); 1587 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY);
1565 } 1588 }
1566 1589
1567 1590
1568 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 1591 Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
1569 Handle<Type> type, 1592 Handle<HeapType> type,
1570 Handle<JSObject> holder, 1593 Handle<JSObject> holder,
1571 Handle<Name> name, 1594 Handle<Name> name,
1572 Handle<JSFunction> getter) { 1595 Handle<JSFunction> getter) {
1573 HandlerFrontend(type, receiver(), holder, name); 1596 HandlerFrontend(type, receiver(), holder, name);
1574 GenerateLoadViaGetter(masm(), receiver(), getter); 1597 GenerateLoadViaGetter(masm(), receiver(), getter);
1575 1598
1576 // Return the generated code. 1599 // Return the generated code.
1577 return GetCode(kind(), Code::FAST, name); 1600 return GetCode(kind(), Code::FAST, name);
1578 } 1601 }
1579 1602
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 GenerateStoreViaSetter(masm(), setter); 1692 GenerateStoreViaSetter(masm(), setter);
1670 1693
1671 return GetCode(kind(), Code::FAST, name); 1694 return GetCode(kind(), Code::FAST, name);
1672 } 1695 }
1673 1696
1674 1697
1675 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 1698 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
1676 Handle<Map> receiver_map) { 1699 Handle<Map> receiver_map) {
1677 ElementsKind elements_kind = receiver_map->elements_kind(); 1700 ElementsKind elements_kind = receiver_map->elements_kind();
1678 if (receiver_map->has_fast_elements() || 1701 if (receiver_map->has_fast_elements() ||
1679 receiver_map->has_external_array_elements()) { 1702 receiver_map->has_external_array_elements() ||
1703 receiver_map->has_fixed_typed_array_elements()) {
1680 Handle<Code> stub = KeyedLoadFastElementStub( 1704 Handle<Code> stub = KeyedLoadFastElementStub(
1681 receiver_map->instance_type() == JS_ARRAY_TYPE, 1705 receiver_map->instance_type() == JS_ARRAY_TYPE,
1682 elements_kind).GetCode(isolate()); 1706 elements_kind).GetCode(isolate());
1683 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1707 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1684 } else { 1708 } else {
1685 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads 1709 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads
1686 ? KeyedLoadDictionaryElementStub().GetCode(isolate()) 1710 ? KeyedLoadDictionaryElementStub().GetCode(isolate())
1687 : KeyedLoadDictionaryElementPlatformStub().GetCode(isolate()); 1711 : KeyedLoadDictionaryElementPlatformStub().GetCode(isolate());
1688 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1712 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1689 } 1713 }
1690 1714
1691 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss); 1715 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
1692 1716
1693 // Return the generated code. 1717 // Return the generated code.
1694 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 1718 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
1695 } 1719 }
1696 1720
1697 1721
1698 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( 1722 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
1699 Handle<Map> receiver_map) { 1723 Handle<Map> receiver_map) {
1700 ElementsKind elements_kind = receiver_map->elements_kind(); 1724 ElementsKind elements_kind = receiver_map->elements_kind();
1701 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 1725 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
1702 Handle<Code> stub; 1726 Handle<Code> stub;
1703 if (receiver_map->has_fast_elements() || 1727 if (receiver_map->has_fast_elements() ||
1704 receiver_map->has_external_array_elements()) { 1728 receiver_map->has_external_array_elements() ||
1729 receiver_map->has_fixed_typed_array_elements()) {
1705 stub = KeyedStoreFastElementStub( 1730 stub = KeyedStoreFastElementStub(
1706 is_jsarray, 1731 is_jsarray,
1707 elements_kind, 1732 elements_kind,
1708 store_mode()).GetCode(isolate()); 1733 store_mode()).GetCode(isolate());
1709 } else { 1734 } else {
1710 stub = KeyedStoreElementStub(is_jsarray, 1735 stub = KeyedStoreElementStub(is_jsarray,
1711 elements_kind, 1736 elements_kind,
1712 store_mode()).GetCode(isolate()); 1737 store_mode()).GetCode(isolate());
1713 } 1738 }
1714 1739
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 1817
1793 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1818 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1794 cached_stub = isolate()->builtins()->KeyedLoadIC_String(); 1819 cached_stub = isolate()->builtins()->KeyedLoadIC_String();
1795 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 1820 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1796 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow(); 1821 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
1797 } else { 1822 } else {
1798 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1823 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1799 ElementsKind elements_kind = receiver_map->elements_kind(); 1824 ElementsKind elements_kind = receiver_map->elements_kind();
1800 1825
1801 if (IsFastElementsKind(elements_kind) || 1826 if (IsFastElementsKind(elements_kind) ||
1802 IsExternalArrayElementsKind(elements_kind)) { 1827 IsExternalArrayElementsKind(elements_kind) ||
1828 IsFixedTypedArrayElementsKind(elements_kind)) {
1803 cached_stub = 1829 cached_stub =
1804 KeyedLoadFastElementStub(is_js_array, 1830 KeyedLoadFastElementStub(is_js_array,
1805 elements_kind).GetCode(isolate()); 1831 elements_kind).GetCode(isolate());
1806 } else { 1832 } else {
1807 ASSERT(elements_kind == DICTIONARY_ELEMENTS); 1833 ASSERT(elements_kind == DICTIONARY_ELEMENTS);
1808 cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate()); 1834 cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate());
1809 } 1835 }
1810 } 1836 }
1811 1837
1812 handlers->Add(cached_stub); 1838 handlers->Add(cached_stub);
(...skipping 22 matching lines...) Expand all
1835 if (!transitioned_map.is_null()) { 1861 if (!transitioned_map.is_null()) {
1836 cached_stub = ElementsTransitionAndStoreStub( 1862 cached_stub = ElementsTransitionAndStoreStub(
1837 elements_kind, 1863 elements_kind,
1838 transitioned_map->elements_kind(), 1864 transitioned_map->elements_kind(),
1839 is_js_array, 1865 is_js_array,
1840 store_mode()).GetCode(isolate()); 1866 store_mode()).GetCode(isolate());
1841 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 1867 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1842 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow(); 1868 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
1843 } else { 1869 } else {
1844 if (receiver_map->has_fast_elements() || 1870 if (receiver_map->has_fast_elements() ||
1845 receiver_map->has_external_array_elements()) { 1871 receiver_map->has_external_array_elements() ||
1872 receiver_map->has_fixed_typed_array_elements()) {
1846 cached_stub = KeyedStoreFastElementStub( 1873 cached_stub = KeyedStoreFastElementStub(
1847 is_js_array, 1874 is_js_array,
1848 elements_kind, 1875 elements_kind,
1849 store_mode()).GetCode(isolate()); 1876 store_mode()).GetCode(isolate());
1850 } else { 1877 } else {
1851 cached_stub = KeyedStoreElementStub( 1878 cached_stub = KeyedStoreElementStub(
1852 is_js_array, 1879 is_js_array,
1853 elements_kind, 1880 elements_kind,
1854 store_mode()).GetCode(isolate()); 1881 store_mode()).GetCode(isolate());
1855 } 1882 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; 1918 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
1892 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 1919 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1893 #undef CALL_GENERATOR_CASE 1920 #undef CALL_GENERATOR_CASE
1894 } 1921 }
1895 1922
1896 CallOptimization optimization(function); 1923 CallOptimization optimization(function);
1897 return optimization.is_simple_api_call(); 1924 return optimization.is_simple_api_call();
1898 } 1925 }
1899 1926
1900 1927
1901 bool CallStubCompiler::CanBeCached(Handle<JSFunction> function) {
1902 if (function->shared()->HasBuiltinFunctionId()) {
1903 BuiltinFunctionId id = function->shared()->builtin_function_id();
1904 #define CALL_GENERATOR_CASE(name) if (id == k##name) return false;
1905 SITE_SPECIFIC_CALL_GENERATORS(CALL_GENERATOR_CASE)
1906 #undef CALL_GENERATOR_CASE
1907 }
1908
1909 return true;
1910 }
1911
1912
1913 Handle<Code> CallStubCompiler::CompileCustomCall( 1928 Handle<Code> CallStubCompiler::CompileCustomCall(
1914 Handle<Object> object, 1929 Handle<Object> object,
1915 Handle<JSObject> holder, 1930 Handle<JSObject> holder,
1916 Handle<Cell> cell, 1931 Handle<Cell> cell,
1917 Handle<JSFunction> function, 1932 Handle<JSFunction> function,
1918 Handle<String> fname, 1933 Handle<String> fname,
1919 Code::StubType type) { 1934 Code::StubType type) {
1920 ASSERT(HasCustomCallGenerator(function)); 1935 ASSERT(HasCustomCallGenerator(function));
1921 1936
1922 if (function->shared()->HasBuiltinFunctionId()) { 1937 if (function->shared()->HasBuiltinFunctionId()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 Initialize(Handle<JSFunction>::null()); 1987 Initialize(Handle<JSFunction>::null());
1973 } 1988 }
1974 } 1989 }
1975 1990
1976 1991
1977 CallOptimization::CallOptimization(Handle<JSFunction> function) { 1992 CallOptimization::CallOptimization(Handle<JSFunction> function) {
1978 Initialize(function); 1993 Initialize(function);
1979 } 1994 }
1980 1995
1981 1996
1982 int CallOptimization::GetPrototypeDepthOfExpectedType( 1997 Handle<Map> CallOptimization::LookupHolderOfExpectedType(
1998 Handle<JSObject> receiver,
1983 Handle<JSObject> object, 1999 Handle<JSObject> object,
1984 Handle<JSObject> holder) const { 2000 Handle<JSObject> holder,
2001 HolderLookup* holder_lookup) const {
1985 ASSERT(is_simple_api_call()); 2002 ASSERT(is_simple_api_call());
1986 if (expected_receiver_type_.is_null()) return 0; 2003 ASSERT_EQ(kHolderNotFound, *holder_lookup);
1987 int depth = 0; 2004 *holder_lookup = kHolderIsReceiver;
2005 Handle<Map> map_to_holder;
2006 if (expected_receiver_type_.is_null()) {
2007 // no expected type, load from receiver.
2008 return map_to_holder;
2009 }
2010 // walk down the prototype chain to the object
2011 while (!receiver.is_identical_to(object)) {
2012 *holder_lookup = kHolderIsPrototypeOfMap;
2013 map_to_holder = Handle<Map>(receiver->map());
2014 receiver = Handle<JSObject>(JSObject::cast(map_to_holder->prototype()));
2015 }
2016 // start looking for the holder
1988 while (!object.is_identical_to(holder)) { 2017 while (!object.is_identical_to(holder)) {
1989 if (expected_receiver_type_->IsTemplateFor(object->map())) return depth; 2018 Handle<Map> object_map(object->map());
1990 object = Handle<JSObject>(JSObject::cast(object->GetPrototype())); 2019 if (expected_receiver_type_->IsTemplateFor(*object_map)) {
1991 if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth; 2020 return map_to_holder;
1992 ++depth; 2021 }
2022 if (!object_map->is_hidden_prototype()) {
2023 *holder_lookup = kHolderNotFound;
2024 return Handle<Map>::null();
2025 }
2026 *holder_lookup = kHolderIsPrototypeOfMap;
2027 map_to_holder = object_map;
2028 object = Handle<JSObject>(JSObject::cast(object_map->prototype()));
1993 } 2029 }
1994 if (expected_receiver_type_->IsTemplateFor(holder->map())) return depth; 2030 if (expected_receiver_type_->IsTemplateFor(holder->map())) {
1995 return kInvalidProtoDepth; 2031 return map_to_holder;
2032 }
2033 *holder_lookup = kHolderNotFound;
2034 return Handle<Map>::null();
1996 } 2035 }
1997 2036
1998 2037
1999 void CallOptimization::Initialize(Handle<JSFunction> function) { 2038 void CallOptimization::Initialize(Handle<JSFunction> function) {
2000 constant_function_ = Handle<JSFunction>::null(); 2039 constant_function_ = Handle<JSFunction>::null();
2001 is_simple_api_call_ = false; 2040 is_simple_api_call_ = false;
2002 expected_receiver_type_ = Handle<FunctionTemplateInfo>::null(); 2041 expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
2003 api_call_info_ = Handle<CallHandlerInfo>::null(); 2042 api_call_info_ = Handle<CallHandlerInfo>::null();
2004 2043
2005 if (function.is_null() || !function->is_compiled()) return; 2044 if (function.is_null() || !function->is_compiled()) return;
(...skipping 23 matching lines...) Expand all
2029 Handle<FunctionTemplateInfo>( 2068 Handle<FunctionTemplateInfo>(
2030 FunctionTemplateInfo::cast(signature->receiver())); 2069 FunctionTemplateInfo::cast(signature->receiver()));
2031 } 2070 }
2032 } 2071 }
2033 2072
2034 is_simple_api_call_ = true; 2073 is_simple_api_call_ = true;
2035 } 2074 }
2036 2075
2037 2076
2038 } } // namespace v8::internal 2077 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/sweeper-thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698