46 StubCache::StubCache(Isolate* isolate, Zone* zone)
48 ASSERT(isolate == Isolate::Current());
52 void StubCache::Initialize() {
65 ASSERT(!heap()->InNewSpace(name));
76 ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
79 int primary_offset = PrimaryOffset(name, flags, map);
80 Entry* primary = entry(primary_, primary_offset);
85 if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
86 Map* old_map = primary->
map;
88 int seed = PrimaryOffset(primary->
key, old_flags, old_map);
89 int secondary_offset = SecondaryOffset(primary->
key, old_flags, seed);
90 Entry* secondary = entry(secondary_, secondary_offset);
91 *secondary = *primary;
98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
105 ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
113 if (receiver->IsGlobalObject()) cache_name = name;
115 while (last->GetPrototype() != heap()->null_value()) {
117 if (last->IsGlobalObject()) cache_name = name;
123 Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
129 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
130 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
131 JSObject::UpdateMapCodeCache(receiver, cache_name, code);
140 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
142 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
148 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
149 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
150 JSObject::UpdateMapCodeCache(receiver, name, code);
159 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
160 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
163 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
169 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
170 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
171 JSObject::UpdateMapCodeCache(receiver, name, code);
180 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
183 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
189 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
190 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
191 JSObject::UpdateMapCodeCache(receiver, name, code);
200 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
203 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
209 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
210 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
211 JSObject::UpdateMapCodeCache(receiver, name, code);
219 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
222 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
228 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
229 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
230 JSObject::UpdateMapCodeCache(receiver, name, code);
236 return isolate_->builtins()->LoadIC_Normal();
244 bool is_dont_delete) {
245 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
247 Code::ComputeMonomorphicFlags(Code::LOAD_IC,
Code::NORMAL);
248 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
254 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
255 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
256 JSObject::UpdateMapCodeCache(receiver, name, code);
265 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
267 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
Code::FIELD);
268 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
274 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
275 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
276 JSObject::UpdateMapCodeCache(receiver, name, code);
285 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
288 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
294 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
295 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
296 JSObject::UpdateMapCodeCache(receiver, name, code);
304 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
307 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
312 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
313 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
314 JSObject::UpdateMapCodeCache(receiver, name, code);
324 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) ==
OWN_MAP);
327 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
333 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
334 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
335 JSObject::UpdateMapCodeCache(receiver, name, code);
344 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
349 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
350 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
351 JSObject::UpdateMapCodeCache(receiver, name, code);
366 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
367 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
368 Map::UpdateCodeCache(map, name, code);
378 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
383 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
384 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
385 JSObject::UpdateMapCodeCache(receiver, name, code);
398 Code::STORE_IC, type, strict_mode);
399 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
405 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
406 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
407 JSObject::UpdateMapCodeCache(receiver, name, code);
417 KeyedIC::GetGrowModeFromStubKind(stub_kind);
419 Code::ComputeExtraICState(grow_mode, strict_mode);
421 Code::ComputeMonomorphicFlags(
422 stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC
423 : Code::KEYED_STORE_IC,
429 name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol();
431 case KeyedIC::STORE_NO_TRANSITION:
432 name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol();
434 case KeyedIC::STORE_AND_GROW_NO_TRANSITION:
435 name = isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_symbol();
441 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags));
446 case KeyedIC::LOAD: {
451 case KeyedIC::STORE_AND_GROW_NO_TRANSITION: {
457 case KeyedIC::STORE_NO_TRANSITION: {
470 if (stub_kind == KeyedIC::LOAD) {
471 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
473 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
475 Map::UpdateCodeCache(receiver_map, name, code);
482 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()
483 : isolate_->builtins()->Builtins::StoreIC_Normal();
493 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
498 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
499 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
500 JSObject::UpdateMapCodeCache(receiver, name, code);
510 ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
513 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
519 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
520 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
521 JSObject::UpdateMapCodeCache(receiver, name, code);
533 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
539 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
540 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
541 JSObject::UpdateMapCodeCache(receiver, name, code);
551 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
556 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
557 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
558 JSObject::UpdateMapCodeCache(receiver, name, code);
570 Code::KEYED_STORE_IC, type, strict_mode);
571 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
578 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
579 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
580 JSObject::UpdateMapCodeCache(receiver, name, code);
585 #define CALL_LOGGER_TAG(kind, type) \
586 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
597 IC::GetCodeCacheForObject(*
object, *holder);
602 if (object->IsString()) {
604 }
else if (object->IsNumber()) {
606 }
else if (object->IsBoolean()) {
613 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
619 code->set_check_type(check);
623 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
624 JSObject::UpdateMapCodeCache(map_holder, name, code);
638 IC::GetCodeCacheForObject(*
object, *holder);
644 if (object->IsNumber() ||
object->IsBoolean() ||
object->IsString()) {
649 Code::ComputeMonomorphicFlags(kind,
Code::FIELD, extra_state,
651 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
657 holder, index, name);
661 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
662 JSObject::UpdateMapCodeCache(map_holder, name, code);
675 IC::GetCodeCacheForObject(*
object, *holder);
681 if (object->IsNumber() ||
object->IsBoolean() ||
object->IsString()) {
688 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
691 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
698 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
699 JSObject::UpdateMapCodeCache(map_holder, name, code);
713 IC::GetCodeCacheForObject(*receiver, *holder);
714 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
716 Code::ComputeMonomorphicFlags(kind,
Code::NORMAL, extra_state,
718 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
721 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
727 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
728 JSObject::UpdateMapCodeCache(map_holder, name, code);
735 UnseededNumberDictionary::Set(isolate->
factory()->non_monomorphic_cache(),
742 Code* StubCache::FindCallInitialize(
int argc,
743 RelocInfo::Mode mode,
747 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
753 isolate()->
heap()->raw_unchecked_non_monomorphic_cache();
754 int entry = dictionary->
FindEntry(isolate(), flags);
759 return reinterpret_cast<Code*
>(
code);
764 RelocInfo::Mode mode,
768 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
772 isolate_->factory()->non_monomorphic_cache();
773 int entry = cache->FindEntry(isolate_, flags);
774 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
776 StubCompiler compiler(isolate_);
777 Handle<Code> code = compiler.CompileCallInitialize(flags);
778 FillCache(isolate_, code);
783 Handle<Code> StubCache::ComputeCallInitialize(
int argc, RelocInfo::Mode mode) {
784 return ComputeCallInitialize(argc, mode, Code::CALL_IC);
789 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET,
790 Code::KEYED_CALL_IC);
801 isolate_->factory()->non_monomorphic_cache();
802 int entry = cache->FindEntry(isolate_, flags);
803 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
805 StubCompiler compiler(isolate_);
806 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
807 FillCache(isolate_, code);
818 isolate_->factory()->non_monomorphic_cache();
819 int entry = cache->FindEntry(isolate_, flags);
820 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
822 StubCompiler compiler(isolate_);
824 FillCache(isolate_, code);
830 ASSERT(kind == Code::KEYED_CALL_IC);
832 Code::ComputeFlags(kind,
MEGAMORPHIC, Code::kNoExtraICState,
835 isolate_->factory()->non_monomorphic_cache();
836 int entry = cache->FindEntry(isolate_, flags);
837 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
839 StubCompiler compiler(isolate_);
840 Handle<Code> code = compiler.CompileCallArguments(flags);
841 FillCache(isolate_, code);
854 isolate_->factory()->non_monomorphic_cache();
855 int entry = cache->FindEntry(isolate_, flags);
856 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
858 StubCompiler compiler(isolate_);
859 Handle<Code> code = compiler.CompileCallMegamorphic(flags);
860 FillCache(isolate_, code);
874 isolate_->factory()->non_monomorphic_cache();
875 int entry = cache->FindEntry(isolate_, flags);
876 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
878 StubCompiler compiler(isolate_);
880 FillCache(isolate_, code);
885 #ifdef ENABLE_DEBUGGER_SUPPORT
891 Code::ComputeFlags(kind,
DEBUG_BREAK, Code::kNoExtraICState,
894 isolate_->factory()->non_monomorphic_cache();
895 int entry = cache->FindEntry(isolate_, flags);
896 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
898 StubCompiler compiler(isolate_);
899 Handle<Code> code = compiler.CompileCallDebugBreak(flags);
900 FillCache(isolate_, code);
905 Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(
int argc,
913 isolate_->factory()->non_monomorphic_cache();
914 int entry = cache->FindEntry(isolate_, flags);
915 if (entry != -1)
return Handle<Code>(Code::cast(cache->ValueAt(entry)));
917 StubCompiler compiler(isolate_);
918 Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
919 FillCache(isolate_, code);
925 void StubCache::Clear() {
926 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
927 for (
int i = 0; i < kPrimaryTableSize; i++) {
928 primary_[i].key = heap()->empty_string();
929 primary_[i].value = empty;
931 for (
int j = 0; j < kSecondaryTableSize; j++) {
932 secondary_[j].key = heap()->empty_string();
933 secondary_[j].value = empty;
943 for (
int i = 0; i < kPrimaryTableSize; i++) {
944 if (primary_[i].key == name) {
945 Map* map = primary_[i].value->FindFirstMap();
948 if (map ==
NULL)
continue;
950 int offset = PrimaryOffset(name, flags, map);
951 if (entry(primary_, offset) == &primary_[i] &&
952 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
958 for (
int i = 0; i < kSecondaryTableSize; i++) {
959 if (secondary_[i].key == name) {
960 Map* map = secondary_[i].value->FindFirstMap();
963 if (map ==
NULL)
continue;
966 int primary_offset = PrimaryOffset(name, flags, map);
967 Entry* primary_entry = entry(primary_, primary_offset);
968 if (primary_entry->
key == name) {
970 if (map == primary_map)
continue;
974 int offset = SecondaryOffset(name, flags, primary_offset);
975 if (entry(secondary_, offset) == &secondary_[i] &&
976 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
989 ASSERT(args[0]->IsJSObject());
990 ASSERT(args[1]->IsJSObject());
993 Address getter_address = v8::ToCData<Address>(callback->getter());
1002 VMState state(isolate, EXTERNAL);
1003 ExternalCallbackScope call_scope(isolate, getter_address);
1007 if (result.
IsEmpty())
return HEAP->undefined_value();
1009 result_internal->VerifyApiCallResultType();
1010 return *result_internal;
1015 JSObject* recv = JSObject::cast(args[0]);
1017 Address setter_address = v8::ToCData<Address>(callback->setter());
1024 LOG(isolate, ApiNamedPropertyAccess(
"store", recv, *name));
1029 VMState state(isolate, EXTERNAL);
1030 ExternalCallbackScope call_scope(isolate, setter_address);
1038 static const int kAccessorInfoOffsetInInterceptorArgs = 2;
1051 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
1052 ASSERT(args[2]->IsJSObject());
1053 ASSERT(args[3]->IsJSObject());
1054 ASSERT(args[5]->IsSmi());
1055 ASSERT(args.length() == 6);
1057 Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1059 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1065 kAccessorInfoOffsetInInterceptorArgs);
1070 VMState state(isolate, EXTERNAL);
1076 result->VerifyApiCallResultType();
1077 return *v8::Utils::OpenHandle(*r);
1081 return isolate->
heap()->no_interceptor_result_sentinel();
1085 static MaybeObject* ThrowReferenceError(
String* name) {
1089 IC ic(IC::NO_EXTRA_FRAME, Isolate::Current());
1090 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
1091 if (!ic.SlowIsContextual())
return HEAP->undefined_value();
1097 FACTORY->NewReferenceError(
"not_defined",
1099 return Isolate::Current()->Throw(*error);
1103 static MaybeObject* LoadWithInterceptor(Arguments* args,
1105 Handle<String> name_handle = args->at<String>(0);
1106 Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
1107 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
1108 Handle<JSObject> receiver_handle = args->at<JSObject>(2);
1109 Handle<JSObject> holder_handle = args->at<JSObject>(3);
1110 ASSERT(args->length() == 6);
1112 Isolate* isolate = receiver_handle->GetIsolate();
1114 Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1116 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1122 kAccessorInfoOffsetInInterceptorArgs);
1123 HandleScope scope(isolate);
1127 VMState state(isolate, EXTERNAL);
1133 Handle<Object> result = v8::Utils::OpenHandle(*r);
1134 result->VerifyApiCallResultType();
1139 MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
1155 { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr);
1156 if (!maybe_result->ToObject(&result))
return maybe_result;
1160 if (attr !=
ABSENT)
return result;
1161 return ThrowReferenceError(String::cast(args[0]));
1167 MaybeObject* result = LoadWithInterceptor(&args, &attr);
1177 ASSERT(args.length() == 4);
1178 JSObject* recv = JSObject::cast(args[0]);
1179 String* name = String::cast(args[1]);
1183 ASSERT(recv->HasNamedInterceptor());
1185 MaybeObject* result = recv->SetPropertyWithInterceptor(
1186 name, value, attr, strict_mode);
1192 JSObject* receiver = JSObject::cast(args[0]);
1193 ASSERT(args.smi_at(1) >= 0);
1194 uint32_t index = args.smi_at(1);
1199 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
1200 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1201 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1202 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1203 if (kind == Code::CALL_IC) {
1204 CallIC::GenerateInitialize(masm(), argc, extra_state);
1206 KeyedCallIC::GenerateInitialize(masm(), argc);
1208 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallInitialize");
1209 isolate()->counters()->call_initialize_stubs()->Increment();
1212 *code, code->arguments_count()));
1213 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code));
1218 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1219 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1222 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1223 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1224 if (kind == Code::CALL_IC) {
1225 CallIC::GenerateInitialize(masm(), argc, extra_state);
1227 KeyedCallIC::GenerateInitialize(masm(), argc);
1229 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallPreMonomorphic");
1230 isolate()->counters()->call_premonomorphic_stubs()->Increment();
1233 *code, code->arguments_count()));
1234 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
1239 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
1240 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1241 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1242 if (kind == Code::CALL_IC) {
1244 ASSERT(!CallIC::Contextual::decode(
1245 Code::ExtractExtraICStateFromFlags(flags)));
1246 CallIC::GenerateNormal(masm(), argc);
1248 KeyedCallIC::GenerateNormal(masm(), argc);
1250 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallNormal");
1251 isolate()->counters()->call_normal_stubs()->Increment();
1254 *code, code->arguments_count()));
1255 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
1260 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1261 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1262 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1263 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1264 if (kind == Code::CALL_IC) {
1265 CallIC::GenerateMegamorphic(masm(), argc, extra_state);
1267 KeyedCallIC::GenerateMegamorphic(masm(), argc);
1269 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallMegamorphic");
1270 isolate()->counters()->call_megamorphic_stubs()->Increment();
1273 *code, code->arguments_count()));
1274 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1279 Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
1280 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1281 KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
1282 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallArguments");
1285 CALL_MEGAMORPHIC_TAG),
1286 *code, code->arguments_count()));
1287 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1292 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
1293 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1294 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1295 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1296 if (kind == Code::CALL_IC) {
1297 CallIC::GenerateMiss(masm(), argc, extra_state);
1299 KeyedCallIC::GenerateMiss(masm(), argc);
1301 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallMiss");
1302 isolate()->counters()->call_megamorphic_stubs()->Increment();
1305 *code, code->arguments_count()));
1306 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code));
1311 #ifdef ENABLE_DEBUGGER_SUPPORT
1312 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1313 Debug::GenerateCallICDebugBreak(masm());
1314 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallDebugBreak");
1317 CALL_DEBUG_BREAK_TAG),
1318 *code, code->arguments_count()));
1323 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1326 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1327 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1328 if (kind == Code::CALL_IC) {
1330 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState);
1332 KeyedCallIC::GenerateMiss(masm(), argc);
1334 Handle<Code> code = GetCodeWithFlags(flags,
"CompileCallDebugPrepareStepIn");
1339 code->arguments_count()));
1342 #endif // ENABLE_DEBUGGER_SUPPORT
1344 #undef CALL_LOGGER_TAG
1347 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1351 masm_.GetCode(&desc);
1352 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1353 #ifdef ENABLE_DISASSEMBLER
1354 if (FLAG_print_code_stubs) code->Disassemble(name);
1360 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1361 Handle<String> name) {
1362 return (FLAG_print_code_stubs && !name.is_null())
1363 ? GetCodeWithFlags(flags, *name->ToCString())
1364 : GetCodeWithFlags(flags, reinterpret_cast<char*>(
NULL));
1368 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
1369 Handle<String> name,
1370 LookupResult* lookup) {
1371 holder->LocalLookupRealNamedProperty(*name, lookup);
1372 if (lookup->IsFound())
return;
1373 if (holder->GetPrototype()->IsNull())
return;
1374 holder->GetPrototype()->Lookup(*name, lookup);
1378 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type,
1379 Handle<String> name) {
1380 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
1381 Handle<Code> code = GetCodeWithFlags(flags, name);
1382 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
1383 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1388 Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type,
1389 Handle<String> name,
1391 Code::Flags flags = Code::ComputeFlags(
1392 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
1393 Handle<Code> code = GetCodeWithFlags(flags, name);
1394 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
1395 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1400 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
1401 Handle<String> name) {
1403 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
1404 Handle<Code> code = GetCodeWithFlags(flags, name);
1405 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
1406 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
1411 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
1412 Handle<String> name,
1414 Code::ExtraICState extra_state =
1415 Code::ComputeExtraICState(grow_mode_, strict_mode_);
1417 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
1418 Handle<Code> code = GetCodeWithFlags(flags, name);
1419 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
1420 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
1425 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1427 KeyedStoreIC::GenerateSlow(masm);
1431 CallStubCompiler::CallStubCompiler(
Isolate* isolate,
1436 : StubCompiler(isolate),
1439 extra_state_(extra_state),
1440 cache_holder_(cache_holder) {
1445 if (function->shared()->HasBuiltinFunctionId()) {
1447 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
1449 #undef CALL_GENERATOR_CASE
1452 CallOptimization optimization(
function);
1453 return optimization.is_simple_api_call();
1465 if (function->shared()->HasBuiltinFunctionId()) {
1467 #define CALL_GENERATOR_CASE(name) \
1468 if (id == k##name) { \
1469 return CallStubCompiler::Compile##name##Call(object, \
1476 #undef CALL_GENERATOR_CASE
1478 CallOptimization optimization(
function);
1479 ASSERT(optimization.is_simple_api_call());
1480 return CompileFastApiCall(optimization,
1490 Handle<String> name) {
1491 int argc = arguments_.immediate();
1497 return GetCodeWithFlags(flags, name);
1501 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction>
function) {
1502 Handle<String> function_name;
1503 if (function->shared()->name()->IsString()) {
1504 function_name = Handle<String>(
String::cast(function->shared()->name()));
1510 Handle<Code> ConstructStubCompiler::GetCode() {
1512 Handle<Code> code = GetCodeWithFlags(flags,
"ConstructStub");
1513 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code,
"ConstructStub"));
1514 GDBJIT(AddCode(GDBJITInterface::STUB,
"ConstructStub", *code));
1519 CallOptimization::CallOptimization(LookupResult* lookup) {
1520 if (lookup->IsFound() &&
1521 lookup->IsCacheable() &&
1524 Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
1526 Initialize(Handle<JSFunction>::null());
1530 CallOptimization::CallOptimization(Handle<JSFunction>
function) {
1531 Initialize(
function);
1535 int CallOptimization::GetPrototypeDepthOfExpectedType(
1536 Handle<JSObject>
object,
1537 Handle<JSObject> holder)
const {
1538 ASSERT(is_simple_api_call());
1539 if (expected_receiver_type_.is_null())
return 0;
1541 while (!
object.is_identical_to(holder)) {
1542 if (object->IsInstanceOf(*expected_receiver_type_))
return depth;
1543 object = Handle<JSObject>(
JSObject::cast(object->GetPrototype()));
1546 if (holder->IsInstanceOf(*expected_receiver_type_))
return depth;
1551 void CallOptimization::Initialize(Handle<JSFunction>
function) {
1553 is_simple_api_call_ =
false;
1557 if (
function.is_null() || !function->is_compiled())
return;
1559 constant_function_ =
function;
1560 AnalyzePossibleApiFunction(
function);
1564 void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction>
function) {
1565 if (!function->shared()->IsApiFunction())
return;
1566 Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
1569 if (info->call_code()->IsUndefined())
return;
1575 if (!info->signature()->IsUndefined()) {
1576 Handle<SignatureInfo> signature =
1578 if (!signature->args()->IsUndefined())
return;
1579 if (!signature->receiver()->IsUndefined()) {
1580 expected_receiver_type_ =
1581 Handle<FunctionTemplateInfo>(
1586 is_simple_api_call_ =
true;
MUST_USE_RESULT MaybeObject * GetElementWithInterceptor(Object *receiver, uint32_t index)
Handle< Code > CompileLoadFunctionPrototype(Handle< String > name)
Handle< Code > CompileLoadCallback(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< AccessorInfo > callback)
static CallHandlerInfo * cast(Object *obj)
Handle< Code > CompileStoreField(Handle< JSObject > object, int index, Handle< Map > transition, Handle< String > name)
#define RETURN_IF_SCHEDULED_EXCEPTION(isolate)
Handle< Code > CompileLoadNonexistent(Handle< String > name, Handle< JSObject > object, Handle< JSObject > last)
static String * cast(Object *obj)
Handle< Code > CompileStoreElement(Handle< Map > receiver_map)
#define LOG(isolate, Call)
#define RUNTIME_FUNCTION(Type, Name)
#define CALL_GENERATOR_CASE(name)
#define ASSERT(condition)
#define CUSTOM_CALL_IC_GENERATORS(V)
#define PROFILE(isolate, Call)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
Handle< Code > CompileLoadField(Handle< JSObject > object, Handle< JSObject > holder, int index, Handle< String > name)
Handle< Code > CompileStoreInterceptor(Handle< JSObject > object, Handle< String > name)
Handle< Code > CompileStoreField(Handle< JSObject > object, int index, Handle< Map > transition, Handle< String > name)
Object * ValueAt(int entry)
Handle< Code > CompileLoadInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
Handle< Value >(* NamedPropertyGetter)(Local< String > property, const AccessorInfo &info)
Handle< Code > CompileCallGlobal(Handle< JSObject > object, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< JSFunction > function, Handle< String > name)
Handle< Code > CompileLoadField(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, int index)
Handle< Code > CompileStoreGlobal(Handle< GlobalObject > object, Handle< JSGlobalPropertyCell > holder, Handle< String > name)
Handle< Code > CompileLoadViaGetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > getter)
Handle< Code > CompileLoadConstant(Handle< JSObject > object, Handle< JSObject > holder, Handle< JSFunction > value, Handle< String > name)
Handle< Code > CompileLoadConstant(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< JSFunction > value)
Handle< Code > CompileCallField(Handle< JSObject > object, Handle< JSObject > holder, int index, Handle< String > name)
Handle< Code > CompileLoadStringLength(Handle< String > name)
void(* AccessorSetter)(Local< String > property, Local< Value > value, const AccessorInfo &info)
static FunctionTemplateInfo * cast(Object *obj)
Handle< Code > CompileLoadGlobal(Handle< JSObject > object, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< String > name, bool is_dont_delete)
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, StubType type=NORMAL, int argc=-1, InlineCacheHolderFlag holder=OWN_MAP)
Handle< Code > CompileStoreCallback(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< AccessorInfo > callback)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
#define CALL_LOGGER_TAG(kind, type)
Handle< Code > CompileCallInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
static Handle< T > null()
#define ASSERT_EQ(v1, v2)
Handle< Code > CompileLoadArrayLength(Handle< String > name)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
void public_set_non_monomorphic_cache(UnseededNumberDictionary *value)
Handle< Code > CompileCallConstant(Handle< Object > object, Handle< JSObject > holder, Handle< JSFunction > function, Handle< String > name, CheckType check)
bool IsCompatibleReceiver(Object *receiver)
static bool HasCustomCallGenerator(Handle< JSFunction > function)
const int kInvalidProtoDepth
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
Vector< Handle< Object > > HandleVector(v8::internal::Handle< T > *elms, int length)
Handle< Code > CompileLoadCallback(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< AccessorInfo > callback)
#define STATIC_ASSERT(test)
void Add(Handle< Map > handle, Zone *zone)
static SignatureInfo * cast(Object *obj)
Handle< Code > CompileLoadInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
void check(i::Vector< const char > string)
Handle< Value >(* AccessorGetter)(Local< String > property, const AccessorInfo &info)
Handle< Code > CompileLoadElement(Handle< Map > receiver_map)
Handle< Code > CompileStoreViaSetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > setter)
static JSObject * cast(Object *obj)
static Flags ComputeMonomorphicFlags(Kind kind, StubType type, ExtraICState extra_ic_state=kNoExtraICState, InlineCacheHolderFlag holder=OWN_MAP, int argc=-1)