| OLD | NEW |
| 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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 return *v8::Utils::OpenHandle(*r); | 868 return *v8::Utils::OpenHandle(*r); |
| 877 } | 869 } |
| 878 } | 870 } |
| 879 | 871 |
| 880 return isolate->heap()->no_interceptor_result_sentinel(); | 872 return isolate->heap()->no_interceptor_result_sentinel(); |
| 881 } | 873 } |
| 882 | 874 |
| 883 | 875 |
| 884 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) { | 876 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) { |
| 885 // If the load is non-contextual, just return the undefined result. | 877 // 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 | 878 // 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); | 879 HandleScope scope(isolate); |
| 889 IC ic(IC::NO_EXTRA_FRAME, isolate); | 880 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 890 ASSERT(ic.IsLoadStub()); | 881 if (ic.contextual_mode() != CONTEXTUAL) { |
| 891 if (!ic.IsContextual()) { | |
| 892 return isolate->heap()->undefined_value(); | 882 return isolate->heap()->undefined_value(); |
| 893 } | 883 } |
| 894 | 884 |
| 895 // Throw a reference error. | 885 // Throw a reference error. |
| 896 Handle<Name> name_handle(name); | 886 Handle<Name> name_handle(name); |
| 897 Handle<Object> error = | 887 Handle<Object> error = |
| 898 isolate->factory()->NewReferenceError("not_defined", | 888 isolate->factory()->NewReferenceError("not_defined", |
| 899 HandleVector(&name_handle, 1)); | 889 HandleVector(&name_handle, 1)); |
| 900 return isolate->Throw(*error); | 890 return isolate->Throw(*error); |
| 901 } | 891 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 *code, code->arguments_count())); | 1030 *code, code->arguments_count())); |
| 1041 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code)); | 1031 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code)); |
| 1042 return code; | 1032 return code; |
| 1043 } | 1033 } |
| 1044 | 1034 |
| 1045 | 1035 |
| 1046 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) { | 1036 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) { |
| 1047 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1037 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1048 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1038 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1049 if (kind == Code::CALL_IC) { | 1039 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); | 1040 CallIC::GenerateNormal(masm(), argc); |
| 1054 } else { | 1041 } else { |
| 1055 KeyedCallIC::GenerateNormal(masm(), argc); | 1042 KeyedCallIC::GenerateNormal(masm(), argc); |
| 1056 } | 1043 } |
| 1057 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal"); | 1044 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal"); |
| 1058 isolate()->counters()->call_normal_stubs()->Increment(); | 1045 isolate()->counters()->call_normal_stubs()->Increment(); |
| 1059 PROFILE(isolate(), | 1046 PROFILE(isolate(), |
| 1060 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), | 1047 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), |
| 1061 *code, code->arguments_count())); | 1048 *code, code->arguments_count())); |
| 1062 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); | 1049 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); | 1085 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); |
| 1099 PROFILE(isolate(), | 1086 PROFILE(isolate(), |
| 1100 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); | 1087 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); |
| 1101 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); | 1088 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); |
| 1102 return code; | 1089 return code; |
| 1103 } | 1090 } |
| 1104 | 1091 |
| 1105 | 1092 |
| 1106 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) { | 1093 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) { |
| 1107 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 1094 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1108 ContextualMode mode = IC::GetContextualMode(extra_state); | 1095 ContextualMode mode = LoadIC::GetContextualMode(extra_state); |
| 1109 LoadIC::GenerateMegamorphic(masm(), mode); | 1096 LoadIC::GenerateMegamorphic(masm(), mode); |
| 1110 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); | 1097 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); |
| 1111 PROFILE(isolate(), | 1098 PROFILE(isolate(), |
| 1112 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0)); | 1099 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0)); |
| 1113 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); | 1100 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); |
| 1114 return code; | 1101 return code; |
| 1115 } | 1102 } |
| 1116 | 1103 |
| 1117 | 1104 |
| 1118 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) { | 1105 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) { |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1895 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; | 1882 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; |
| 1896 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) | 1883 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) |
| 1897 #undef CALL_GENERATOR_CASE | 1884 #undef CALL_GENERATOR_CASE |
| 1898 } | 1885 } |
| 1899 | 1886 |
| 1900 CallOptimization optimization(function); | 1887 CallOptimization optimization(function); |
| 1901 return optimization.is_simple_api_call(); | 1888 return optimization.is_simple_api_call(); |
| 1902 } | 1889 } |
| 1903 | 1890 |
| 1904 | 1891 |
| 1905 bool CallStubCompiler::CanBeCached(Handle<JSFunction> function) { | |
| 1906 if (function->shared()->HasBuiltinFunctionId()) { | |
| 1907 BuiltinFunctionId id = function->shared()->builtin_function_id(); | |
| 1908 #define CALL_GENERATOR_CASE(name) if (id == k##name) return false; | |
| 1909 SITE_SPECIFIC_CALL_GENERATORS(CALL_GENERATOR_CASE) | |
| 1910 #undef CALL_GENERATOR_CASE | |
| 1911 } | |
| 1912 | |
| 1913 return true; | |
| 1914 } | |
| 1915 | |
| 1916 | |
| 1917 Handle<Code> CallStubCompiler::CompileCustomCall( | 1892 Handle<Code> CallStubCompiler::CompileCustomCall( |
| 1918 Handle<Object> object, | 1893 Handle<Object> object, |
| 1919 Handle<JSObject> holder, | 1894 Handle<JSObject> holder, |
| 1920 Handle<Cell> cell, | 1895 Handle<Cell> cell, |
| 1921 Handle<JSFunction> function, | 1896 Handle<JSFunction> function, |
| 1922 Handle<String> fname, | 1897 Handle<String> fname, |
| 1923 Code::StubType type) { | 1898 Code::StubType type) { |
| 1924 ASSERT(HasCustomCallGenerator(function)); | 1899 ASSERT(HasCustomCallGenerator(function)); |
| 1925 | 1900 |
| 1926 if (function->shared()->HasBuiltinFunctionId()) { | 1901 if (function->shared()->HasBuiltinFunctionId()) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2033 Handle<FunctionTemplateInfo>( | 2008 Handle<FunctionTemplateInfo>( |
| 2034 FunctionTemplateInfo::cast(signature->receiver())); | 2009 FunctionTemplateInfo::cast(signature->receiver())); |
| 2035 } | 2010 } |
| 2036 } | 2011 } |
| 2037 | 2012 |
| 2038 is_simple_api_call_ = true; | 2013 is_simple_api_call_ = true; |
| 2039 } | 2014 } |
| 2040 | 2015 |
| 2041 | 2016 |
| 2042 } } // namespace v8::internal | 2017 } } // namespace v8::internal |
| OLD | NEW |