| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "arguments.h" | 31 #include "arguments.h" |
| 32 #include "ic-inl.h" | 32 #include "ic-inl.h" |
| 33 #include "stub-cache.h" | 33 #include "stub-cache.h" |
| 34 | 34 |
| 35 namespace v8 { | 35 namespace v8 { |
| 36 namespace internal { | 36 namespace internal { |
| 37 | 37 |
| 38 // ----------------------------------------------------------------------- | 38 // ----------------------------------------------------------------------- |
| 39 // StubCache implementation. | 39 // StubCache implementation. |
| 40 | 40 |
| 41 StubCacheData::StubCacheData() { |
| 42 for (int i = 0; i < kPrimaryTableSize; ++i) { |
| 43 primary_[i].key = NULL; |
| 44 primary_[i].value = NULL; |
| 45 } |
| 41 | 46 |
| 42 StubCache::Entry StubCache::primary_[StubCache::kPrimaryTableSize]; | 47 for (int i = 0; i < kSecondaryTableSize; ++i) { |
| 43 StubCache::Entry StubCache::secondary_[StubCache::kSecondaryTableSize]; | 48 secondary_[i].key = NULL; |
| 49 secondary_[i].value = NULL; |
| 50 } |
| 51 } |
| 44 | 52 |
| 45 void StubCache::Initialize(bool create_heap_objects) { | 53 void StubCache::Initialize(bool create_heap_objects) { |
| 46 ASSERT(IsPowerOf2(kPrimaryTableSize)); | 54 ASSERT(IsPowerOf2(kPrimaryTableSize)); |
| 47 ASSERT(IsPowerOf2(kSecondaryTableSize)); | 55 ASSERT(IsPowerOf2(kSecondaryTableSize)); |
| 48 if (create_heap_objects) { | 56 if (create_heap_objects) { |
| 49 HandleScope scope; | 57 HandleScope scope; |
| 50 Clear(); | 58 Clear(); |
| 51 } | 59 } |
| 52 } | 60 } |
| 53 | 61 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 66 // the bits are the least significant so they will be the ones | 74 // the bits are the least significant so they will be the ones |
| 67 // masked out. | 75 // masked out. |
| 68 ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); | 76 ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); |
| 69 ASSERT(Code::kFlagsICStateShift == 0); | 77 ASSERT(Code::kFlagsICStateShift == 0); |
| 70 | 78 |
| 71 // Make sure that the code type is not included in the hash. | 79 // Make sure that the code type is not included in the hash. |
| 72 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 80 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); |
| 73 | 81 |
| 74 // Compute the primary entry. | 82 // Compute the primary entry. |
| 75 int primary_offset = PrimaryOffset(name, flags, map); | 83 int primary_offset = PrimaryOffset(name, flags, map); |
| 76 Entry* primary = entry(primary_, primary_offset); | 84 StubCacheData& stub_cache_data = v8_context()->stub_cache_data_; |
| 85 Entry* primary = entry(stub_cache_data.primary_, primary_offset); |
| 77 Code* hit = primary->value; | 86 Code* hit = primary->value; |
| 78 | 87 |
| 79 // If the primary entry has useful data in it, we retire it to the | 88 // If the primary entry has useful data in it, we retire it to the |
| 80 // secondary cache before overwriting it. | 89 // secondary cache before overwriting it. |
| 81 if (hit != Builtins::builtin(Builtins::Illegal)) { | 90 if (hit != Builtins::builtin(Builtins::Illegal)) { |
| 82 Code::Flags primary_flags = Code::RemoveTypeFromFlags(hit->flags()); | 91 Code::Flags primary_flags = Code::RemoveTypeFromFlags(hit->flags()); |
| 83 int secondary_offset = | 92 int secondary_offset = |
| 84 SecondaryOffset(primary->key, primary_flags, primary_offset); | 93 SecondaryOffset(primary->key, primary_flags, primary_offset); |
| 85 Entry* secondary = entry(secondary_, secondary_offset); | 94 Entry* secondary = entry(stub_cache_data.secondary_, secondary_offset); |
| 86 *secondary = *primary; | 95 *secondary = *primary; |
| 87 } | 96 } |
| 88 | 97 |
| 89 // Update primary cache. | 98 // Update primary cache. |
| 90 primary->key = name; | 99 primary->key = name; |
| 91 primary->value = code; | 100 primary->value = code; |
| 92 return code; | 101 return code; |
| 93 } | 102 } |
| 94 | 103 |
| 95 | 104 |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 Code* code = Code::cast(result); | 714 Code* code = Code::cast(result); |
| 706 USE(code); | 715 USE(code); |
| 707 LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, | 716 LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, |
| 708 code, code->arguments_count())); | 717 code, code->arguments_count())); |
| 709 } | 718 } |
| 710 return result; | 719 return result; |
| 711 } | 720 } |
| 712 | 721 |
| 713 | 722 |
| 714 void StubCache::Clear() { | 723 void StubCache::Clear() { |
| 724 StubCacheData& stub_cache_data = v8_context()->stub_cache_data_; |
| 715 for (int i = 0; i < kPrimaryTableSize; i++) { | 725 for (int i = 0; i < kPrimaryTableSize; i++) { |
| 716 primary_[i].key = Heap::empty_string(); | 726 stub_cache_data.primary_[i].key = Heap::empty_string(); |
| 717 primary_[i].value = Builtins::builtin(Builtins::Illegal); | 727 stub_cache_data.primary_[i].value = Builtins::builtin(Builtins::Illegal); |
| 718 } | 728 } |
| 719 for (int j = 0; j < kSecondaryTableSize; j++) { | 729 for (int j = 0; j < kSecondaryTableSize; j++) { |
| 720 secondary_[j].key = Heap::empty_string(); | 730 stub_cache_data.secondary_[j].key = Heap::empty_string(); |
| 721 secondary_[j].value = Builtins::builtin(Builtins::Illegal); | 731 stub_cache_data.secondary_[j].value = Builtins::builtin(Builtins::Illegal); |
| 722 } | 732 } |
| 723 } | 733 } |
| 724 | 734 |
| 725 | 735 |
| 726 // ------------------------------------------------------------------------ | 736 // ------------------------------------------------------------------------ |
| 727 // StubCompiler implementation. | 737 // StubCompiler implementation. |
| 728 | 738 |
| 729 | 739 |
| 730 // Support function for computing call IC miss stubs. | 740 // Support function for computing call IC miss stubs. |
| 731 Handle<Code> ComputeCallMiss(int argc) { | 741 Handle<Code> ComputeCallMiss(int argc) { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 return result; | 929 return result; |
| 920 } | 930 } |
| 921 | 931 |
| 922 | 932 |
| 923 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { | 933 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { |
| 924 HandleScope scope; | 934 HandleScope scope; |
| 925 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 935 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 926 CallIC::GenerateInitialize(masm(), argc); | 936 CallIC::GenerateInitialize(masm(), argc); |
| 927 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); | 937 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); |
| 928 if (!result->IsFailure()) { | 938 if (!result->IsFailure()) { |
| 929 Counters::call_initialize_stubs.Increment(); | 939 INC_COUNTER(call_initialize_stubs); |
| 930 Code* code = Code::cast(result); | 940 Code* code = Code::cast(result); |
| 931 USE(code); | 941 USE(code); |
| 932 LOG(CodeCreateEvent(Logger::CALL_INITIALIZE_TAG, | 942 LOG(CodeCreateEvent(Logger::CALL_INITIALIZE_TAG, |
| 933 code, code->arguments_count())); | 943 code, code->arguments_count())); |
| 934 } | 944 } |
| 935 return result; | 945 return result; |
| 936 } | 946 } |
| 937 | 947 |
| 938 | 948 |
| 939 Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { | 949 Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { |
| 940 HandleScope scope; | 950 HandleScope scope; |
| 941 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 951 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 942 // The code of the PreMonomorphic stub is the same as the code | 952 // The code of the PreMonomorphic stub is the same as the code |
| 943 // of the Initialized stub. They just differ on the code object flags. | 953 // of the Initialized stub. They just differ on the code object flags. |
| 944 CallIC::GenerateInitialize(masm(), argc); | 954 CallIC::GenerateInitialize(masm(), argc); |
| 945 Object* result = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); | 955 Object* result = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); |
| 946 if (!result->IsFailure()) { | 956 if (!result->IsFailure()) { |
| 947 Counters::call_premonomorphic_stubs.Increment(); | 957 INC_COUNTER(call_premonomorphic_stubs); |
| 948 Code* code = Code::cast(result); | 958 Code* code = Code::cast(result); |
| 949 USE(code); | 959 USE(code); |
| 950 LOG(CodeCreateEvent(Logger::CALL_PRE_MONOMORPHIC_TAG, | 960 LOG(CodeCreateEvent(Logger::CALL_PRE_MONOMORPHIC_TAG, |
| 951 code, code->arguments_count())); | 961 code, code->arguments_count())); |
| 952 } | 962 } |
| 953 return result; | 963 return result; |
| 954 } | 964 } |
| 955 | 965 |
| 956 | 966 |
| 957 Object* StubCompiler::CompileCallNormal(Code::Flags flags) { | 967 Object* StubCompiler::CompileCallNormal(Code::Flags flags) { |
| 958 HandleScope scope; | 968 HandleScope scope; |
| 959 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 969 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 960 CallIC::GenerateNormal(masm(), argc); | 970 CallIC::GenerateNormal(masm(), argc); |
| 961 Object* result = GetCodeWithFlags(flags, "CompileCallNormal"); | 971 Object* result = GetCodeWithFlags(flags, "CompileCallNormal"); |
| 962 if (!result->IsFailure()) { | 972 if (!result->IsFailure()) { |
| 963 Counters::call_normal_stubs.Increment(); | 973 INC_COUNTER(call_normal_stubs); |
| 964 Code* code = Code::cast(result); | 974 Code* code = Code::cast(result); |
| 965 USE(code); | 975 USE(code); |
| 966 LOG(CodeCreateEvent(Logger::CALL_NORMAL_TAG, | 976 LOG(CodeCreateEvent(Logger::CALL_NORMAL_TAG, |
| 967 code, code->arguments_count())); | 977 code, code->arguments_count())); |
| 968 } | 978 } |
| 969 return result; | 979 return result; |
| 970 } | 980 } |
| 971 | 981 |
| 972 | 982 |
| 973 Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { | 983 Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { |
| 974 HandleScope scope; | 984 HandleScope scope; |
| 975 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 985 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 976 CallIC::GenerateMegamorphic(masm(), argc); | 986 CallIC::GenerateMegamorphic(masm(), argc); |
| 977 Object* result = GetCodeWithFlags(flags, "CompileCallMegamorphic"); | 987 Object* result = GetCodeWithFlags(flags, "CompileCallMegamorphic"); |
| 978 if (!result->IsFailure()) { | 988 if (!result->IsFailure()) { |
| 979 Counters::call_megamorphic_stubs.Increment(); | 989 INC_COUNTER(call_megamorphic_stubs); |
| 980 Code* code = Code::cast(result); | 990 Code* code = Code::cast(result); |
| 981 USE(code); | 991 USE(code); |
| 982 LOG(CodeCreateEvent(Logger::CALL_MEGAMORPHIC_TAG, | 992 LOG(CodeCreateEvent(Logger::CALL_MEGAMORPHIC_TAG, |
| 983 code, code->arguments_count())); | 993 code, code->arguments_count())); |
| 984 } | 994 } |
| 985 return result; | 995 return result; |
| 986 } | 996 } |
| 987 | 997 |
| 988 | 998 |
| 989 Object* StubCompiler::CompileCallMiss(Code::Flags flags) { | 999 Object* StubCompiler::CompileCallMiss(Code::Flags flags) { |
| 990 HandleScope scope; | 1000 HandleScope scope; |
| 991 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1001 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 992 CallIC::GenerateMiss(masm(), argc); | 1002 CallIC::GenerateMiss(masm(), argc); |
| 993 Object* result = GetCodeWithFlags(flags, "CompileCallMiss"); | 1003 Object* result = GetCodeWithFlags(flags, "CompileCallMiss"); |
| 994 if (!result->IsFailure()) { | 1004 if (!result->IsFailure()) { |
| 995 Counters::call_megamorphic_stubs.Increment(); | 1005 INC_COUNTER(call_megamorphic_stubs); |
| 996 Code* code = Code::cast(result); | 1006 Code* code = Code::cast(result); |
| 997 USE(code); | 1007 USE(code); |
| 998 LOG(CodeCreateEvent(Logger::CALL_MISS_TAG, code, code->arguments_count())); | 1008 LOG(CodeCreateEvent(Logger::CALL_MISS_TAG, code, code->arguments_count())); |
| 999 } | 1009 } |
| 1000 return result; | 1010 return result; |
| 1001 } | 1011 } |
| 1002 | 1012 |
| 1003 | 1013 |
| 1004 #ifdef ENABLE_DEBUGGER_SUPPORT | 1014 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1005 Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { | 1015 Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 if (!result->IsFailure()) { | 1109 if (!result->IsFailure()) { |
| 1100 Code* code = Code::cast(result); | 1110 Code* code = Code::cast(result); |
| 1101 USE(code); | 1111 USE(code); |
| 1102 LOG(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); | 1112 LOG(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); |
| 1103 } | 1113 } |
| 1104 return result; | 1114 return result; |
| 1105 } | 1115 } |
| 1106 | 1116 |
| 1107 | 1117 |
| 1108 } } // namespace v8::internal | 1118 } } // namespace v8::internal |
| OLD | NEW |