| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 | 860 |
| 861 private: | 861 private: |
| 862 bool is_pre_parsing_; | 862 bool is_pre_parsing_; |
| 863 }; | 863 }; |
| 864 | 864 |
| 865 | 865 |
| 866 class ParserLog BASE_EMBEDDED { | 866 class ParserLog BASE_EMBEDDED { |
| 867 public: | 867 public: |
| 868 virtual ~ParserLog() { } | 868 virtual ~ParserLog() { } |
| 869 | 869 |
| 870 // Records the occurrence of a function. The returned object is | 870 // Records the occurrence of a function. |
| 871 // only guaranteed to be valid until the next function has been | |
| 872 // logged. | |
| 873 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } | 871 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } |
| 874 | 872 // Return the current position in the function entry log. |
| 873 virtual int position() { return 0; } |
| 875 virtual void LogError() { } | 874 virtual void LogError() { } |
| 876 }; | 875 }; |
| 877 | 876 |
| 878 | 877 |
| 879 class AstBuildingParserFactory : public ParserFactory { | 878 class AstBuildingParserFactory : public ParserFactory { |
| 880 public: | 879 public: |
| 881 AstBuildingParserFactory() : ParserFactory(false) { } | 880 AstBuildingParserFactory() : ParserFactory(false) { } |
| 882 | 881 |
| 883 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); | 882 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); |
| 884 | 883 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 906 | 905 |
| 907 class ParserRecorder: public ParserLog { | 906 class ParserRecorder: public ParserLog { |
| 908 public: | 907 public: |
| 909 ParserRecorder(); | 908 ParserRecorder(); |
| 910 virtual FunctionEntry LogFunction(int start); | 909 virtual FunctionEntry LogFunction(int start); |
| 911 virtual void LogError() { } | 910 virtual void LogError() { } |
| 912 virtual void LogMessage(Scanner::Location loc, | 911 virtual void LogMessage(Scanner::Location loc, |
| 913 const char* message, | 912 const char* message, |
| 914 Vector<const char*> args); | 913 Vector<const char*> args); |
| 915 Vector<unsigned> ExtractData() { | 914 Vector<unsigned> ExtractData() { |
| 916 return store_.ToVector(); | 915 int total_size = ScriptDataImpl::kHeaderSize + store_.size(); |
| 916 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 917 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 918 if (ScriptDataImpl::kHeaderSize < total_size) { |
| 919 store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, total_size)); |
| 920 } |
| 921 return data; |
| 917 } | 922 } |
| 923 virtual int position() { return store_.size(); } |
| 918 private: | 924 private: |
| 919 bool has_error_; | |
| 920 Collector<unsigned> store_; | 925 Collector<unsigned> store_; |
| 921 Vector<unsigned> preamble_; | 926 unsigned preamble_[ScriptDataImpl::kHeaderSize]; |
| 927 #ifdef DEBUG |
| 928 int prev_start; |
| 929 #endif |
| 922 | 930 |
| 923 Collector<unsigned>* store() { return &store_; } | 931 bool has_error() { |
| 932 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); |
| 933 } |
| 924 void WriteString(Vector<const char> str); | 934 void WriteString(Vector<const char> str); |
| 925 }; | 935 }; |
| 926 | 936 |
| 927 | 937 |
| 928 FunctionEntry ScriptDataImpl::GetFunctionEnd(int start) { | 938 void ScriptDataImpl::SkipFunctionEntry(int start) { |
| 929 if (nth(last_entry_).start_pos() > start) { | 939 ASSERT(index_ + FunctionEntry::kSize <= store_.length()); |
| 930 // If the last entry we looked up is higher than what we're | 940 ASSERT(static_cast<int>(store_[index_]) == start); |
| 931 // looking for then it's useless and we reset it. | 941 index_ += FunctionEntry::kSize; |
| 932 last_entry_ = 0; | 942 } |
| 933 } | 943 |
| 934 for (int i = last_entry_; i < EntryCount(); i++) { | 944 |
| 935 FunctionEntry entry = nth(i); | 945 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| 936 if (entry.start_pos() == start) { | 946 // The current pre-data entry must be a FunctionEntry with the given |
| 937 last_entry_ = i; | 947 // start position. |
| 938 return entry; | 948 if ((index_ + FunctionEntry::kSize <= store_.length()) |
| 939 } | 949 && (static_cast<int>(store_[index_]) == start)) { |
| 950 int index = index_; |
| 951 index_ += FunctionEntry::kSize; |
| 952 return FunctionEntry(store_.SubVector(index, |
| 953 index + FunctionEntry::kSize)); |
| 940 } | 954 } |
| 941 return FunctionEntry(); | 955 return FunctionEntry(); |
| 942 } | 956 } |
| 943 | 957 |
| 944 | 958 |
| 945 bool ScriptDataImpl::SanityCheck() { | 959 bool ScriptDataImpl::SanityCheck() { |
| 946 if (store_.length() < static_cast<int>(ScriptDataImpl::kHeaderSize)) { | 960 if (store_.length() < static_cast<int>(ScriptDataImpl::kHeaderSize)) { |
| 947 return false; | 961 return false; |
| 948 } | 962 } |
| 949 if (magic() != ScriptDataImpl::kMagicNumber) return false; | 963 if (magic() != ScriptDataImpl::kMagicNumber) return false; |
| 950 if (version() != ScriptDataImpl::kCurrentVersion) return false; | 964 if (version() != ScriptDataImpl::kCurrentVersion) return false; |
| 951 return true; | 965 return true; |
| 952 } | 966 } |
| 953 | 967 |
| 954 | 968 |
| 955 int ScriptDataImpl::EntryCount() { | |
| 956 return (store_.length() - kHeaderSize) / FunctionEntry::kSize; | |
| 957 } | |
| 958 | |
| 959 | |
| 960 FunctionEntry ScriptDataImpl::nth(int n) { | |
| 961 int offset = kHeaderSize + n * FunctionEntry::kSize; | |
| 962 return FunctionEntry(Vector<unsigned>(store_.start() + offset, | |
| 963 FunctionEntry::kSize)); | |
| 964 } | |
| 965 | |
| 966 | |
| 967 ParserRecorder::ParserRecorder() | 969 ParserRecorder::ParserRecorder() |
| 968 : has_error_(false), store_(ScriptDataImpl::kHeaderSize) { | 970 : store_(0) { |
| 969 preamble_ = store()->AddBlock(ScriptDataImpl::kHeaderSize, 0); | 971 #ifdef DEBUG |
| 972 prev_start = -1; |
| 973 #endif |
| 970 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | 974 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; |
| 971 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; | 975 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; |
| 972 preamble_[ScriptDataImpl::kHasErrorOffset] = false; | 976 preamble_[ScriptDataImpl::kHasErrorOffset] = false; |
| 977 preamble_[ScriptDataImpl::kSizeOffset] = 0; |
| 978 ASSERT_EQ(4, ScriptDataImpl::kHeaderSize); |
| 973 } | 979 } |
| 974 | 980 |
| 975 | 981 |
| 976 void ParserRecorder::WriteString(Vector<const char> str) { | 982 void ParserRecorder::WriteString(Vector<const char> str) { |
| 977 store()->Add(str.length()); | 983 store_.Add(str.length()); |
| 978 for (int i = 0; i < str.length(); i++) { | 984 for (int i = 0; i < str.length(); i++) { |
| 979 store()->Add(str[i]); | 985 store_.Add(str[i]); |
| 980 } | 986 } |
| 981 } | 987 } |
| 982 | 988 |
| 983 | 989 |
| 984 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { | 990 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { |
| 985 int length = start[0]; | 991 int length = start[0]; |
| 986 char* result = NewArray<char>(length + 1); | 992 char* result = NewArray<char>(length + 1); |
| 987 for (int i = 0; i < length; i++) { | 993 for (int i = 0; i < length; i++) { |
| 988 result[i] = start[i + 1]; | 994 result[i] = start[i + 1]; |
| 989 } | 995 } |
| 990 result[length] = '\0'; | 996 result[length] = '\0'; |
| 991 if (chars != NULL) *chars = length; | 997 if (chars != NULL) *chars = length; |
| 992 return result; | 998 return result; |
| 993 } | 999 } |
| 994 | 1000 |
| 995 | 1001 |
| 996 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, | 1002 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, |
| 997 Vector<const char*> args) { | 1003 Vector<const char*> args) { |
| 998 if (has_error_) return; | 1004 if (has_error()) return; |
| 999 store()->Reset(); | |
| 1000 preamble_ = store()->AddBlock(ScriptDataImpl::kHeaderSize, 0); | |
| 1001 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | |
| 1002 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; | |
| 1003 preamble_[ScriptDataImpl::kHasErrorOffset] = true; | 1005 preamble_[ScriptDataImpl::kHasErrorOffset] = true; |
| 1004 store()->Add(loc.beg_pos); | 1006 store_.Reset(); |
| 1005 store()->Add(loc.end_pos); | 1007 store_.Add(loc.beg_pos); |
| 1006 store()->Add(args.length()); | 1008 store_.Add(loc.end_pos); |
| 1009 store_.Add(args.length()); |
| 1007 WriteString(CStrVector(message)); | 1010 WriteString(CStrVector(message)); |
| 1008 for (int i = 0; i < args.length(); i++) { | 1011 for (int i = 0; i < args.length(); i++) { |
| 1009 WriteString(CStrVector(args[i])); | 1012 WriteString(CStrVector(args[i])); |
| 1010 } | 1013 } |
| 1011 } | 1014 } |
| 1012 | 1015 |
| 1013 | 1016 |
| 1014 Scanner::Location ScriptDataImpl::MessageLocation() { | 1017 Scanner::Location ScriptDataImpl::MessageLocation() { |
| 1015 int beg_pos = Read(0); | 1018 int beg_pos = Read(0); |
| 1016 int end_pos = Read(1); | 1019 int end_pos = Read(1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1039 | 1042 |
| 1040 unsigned ScriptDataImpl::Read(int position) { | 1043 unsigned ScriptDataImpl::Read(int position) { |
| 1041 return store_[ScriptDataImpl::kHeaderSize + position]; | 1044 return store_[ScriptDataImpl::kHeaderSize + position]; |
| 1042 } | 1045 } |
| 1043 | 1046 |
| 1044 | 1047 |
| 1045 unsigned* ScriptDataImpl::ReadAddress(int position) { | 1048 unsigned* ScriptDataImpl::ReadAddress(int position) { |
| 1046 return &store_[ScriptDataImpl::kHeaderSize + position]; | 1049 return &store_[ScriptDataImpl::kHeaderSize + position]; |
| 1047 } | 1050 } |
| 1048 | 1051 |
| 1052 void ScriptDataImpl::FindStart(int position) { |
| 1053 // Only search forwards, and linearly for now. |
| 1054 while ((index_ < store_.length()) |
| 1055 && (static_cast<int>(store_[index_])) < position) { |
| 1056 index_ += FunctionEntry::kSize; |
| 1057 } |
| 1058 } |
| 1059 |
| 1049 | 1060 |
| 1050 FunctionEntry ParserRecorder::LogFunction(int start) { | 1061 FunctionEntry ParserRecorder::LogFunction(int start) { |
| 1051 if (has_error_) return FunctionEntry(); | 1062 #ifdef DEBUG |
| 1052 FunctionEntry result(store()->AddBlock(FunctionEntry::kSize, 0)); | 1063 ASSERT(start > prev_start); |
| 1064 prev_start = start; |
| 1065 #endif |
| 1066 if (has_error()) return FunctionEntry(); |
| 1067 FunctionEntry result(store_.AddBlock(FunctionEntry::kSize, 0)); |
| 1053 result.set_start_pos(start); | 1068 result.set_start_pos(start); |
| 1054 return result; | 1069 return result; |
| 1055 } | 1070 } |
| 1056 | 1071 |
| 1057 | 1072 |
| 1058 class AstBuildingParser : public Parser { | 1073 class AstBuildingParser : public Parser { |
| 1059 public: | 1074 public: |
| 1060 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, | 1075 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, |
| 1061 v8::Extension* extension, ScriptDataImpl* pre_data) | 1076 v8::Extension* extension, ScriptDataImpl* pre_data) |
| 1062 : Parser(script, allow_natives_syntax, extension, PARSE, | 1077 : Parser(script, allow_natives_syntax, extension, PARSE, |
| (...skipping 2869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3932 new Assignment(Token::INIT_CONST, fproxy, | 3947 new Assignment(Token::INIT_CONST, fproxy, |
| 3933 NEW(ThisFunction()), | 3948 NEW(ThisFunction()), |
| 3934 RelocInfo::kNoPosition))); | 3949 RelocInfo::kNoPosition))); |
| 3935 } | 3950 } |
| 3936 | 3951 |
| 3937 // Determine if the function will be lazily compiled. The mode can | 3952 // Determine if the function will be lazily compiled. The mode can |
| 3938 // only be PARSE_LAZILY if the --lazy flag is true. | 3953 // only be PARSE_LAZILY if the --lazy flag is true. |
| 3939 bool is_lazily_compiled = | 3954 bool is_lazily_compiled = |
| 3940 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); | 3955 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); |
| 3941 | 3956 |
| 3957 int function_block_pos = scanner_.location().beg_pos; |
| 3942 int materialized_literal_count; | 3958 int materialized_literal_count; |
| 3943 int expected_property_count; | 3959 int expected_property_count; |
| 3960 int end_pos; |
| 3944 bool only_simple_this_property_assignments; | 3961 bool only_simple_this_property_assignments; |
| 3945 Handle<FixedArray> this_property_assignments; | 3962 Handle<FixedArray> this_property_assignments; |
| 3946 if (is_lazily_compiled && pre_data() != NULL) { | 3963 if (is_lazily_compiled && pre_data() != NULL) { |
| 3947 FunctionEntry entry = pre_data()->GetFunctionEnd(start_pos); | 3964 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); |
| 3948 if (!entry.is_valid()) { | 3965 if (!entry.is_valid()) { |
| 3949 ReportInvalidPreparseData(name, CHECK_OK); | 3966 ReportInvalidPreparseData(name, CHECK_OK); |
| 3950 } | 3967 } |
| 3951 int end_pos = entry.end_pos(); | 3968 end_pos = entry.end_pos(); |
| 3952 if (end_pos <= start_pos) { | 3969 if (end_pos <= function_block_pos) { |
| 3953 // End position greater than end of stream is safe, and hard to check. | 3970 // End position greater than end of stream is safe, and hard to check. |
| 3954 ReportInvalidPreparseData(name, CHECK_OK); | 3971 ReportInvalidPreparseData(name, CHECK_OK); |
| 3955 } | 3972 } |
| 3956 Counters::total_preparse_skipped.Increment(end_pos - start_pos); | 3973 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); |
| 3957 scanner_.SeekForward(end_pos); | 3974 scanner_.SeekForward(end_pos); |
| 3975 pre_data()->Skip(entry.predata_skip()); |
| 3958 materialized_literal_count = entry.literal_count(); | 3976 materialized_literal_count = entry.literal_count(); |
| 3959 expected_property_count = entry.property_count(); | 3977 expected_property_count = entry.property_count(); |
| 3960 only_simple_this_property_assignments = false; | 3978 only_simple_this_property_assignments = false; |
| 3961 this_property_assignments = Factory::empty_fixed_array(); | 3979 this_property_assignments = Factory::empty_fixed_array(); |
| 3980 Expect(Token::RBRACE, CHECK_OK); |
| 3962 } else { | 3981 } else { |
| 3982 if (pre_data() != NULL) { |
| 3983 // Skip pre-data entry for non-lazily compiled function. |
| 3984 pre_data()->SkipFunctionEntry(function_block_pos); |
| 3985 } |
| 3986 FunctionEntry entry = log()->LogFunction(function_block_pos); |
| 3987 int predata_position_before = log()->position(); |
| 3963 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | 3988 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); |
| 3964 materialized_literal_count = temp_scope.materialized_literal_count(); | 3989 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3965 expected_property_count = temp_scope.expected_property_count(); | 3990 expected_property_count = temp_scope.expected_property_count(); |
| 3966 only_simple_this_property_assignments = | 3991 only_simple_this_property_assignments = |
| 3967 temp_scope.only_simple_this_property_assignments(); | 3992 temp_scope.only_simple_this_property_assignments(); |
| 3968 this_property_assignments = temp_scope.this_property_assignments(); | 3993 this_property_assignments = temp_scope.this_property_assignments(); |
| 3969 } | |
| 3970 | 3994 |
| 3971 Expect(Token::RBRACE, CHECK_OK); | 3995 Expect(Token::RBRACE, CHECK_OK); |
| 3972 int end_pos = scanner_.location().end_pos; | 3996 end_pos = scanner_.location().end_pos; |
| 3973 | 3997 if (entry.is_valid()) { |
| 3974 FunctionEntry entry = log()->LogFunction(start_pos); | 3998 entry.set_end_pos(end_pos); |
| 3975 if (entry.is_valid()) { | 3999 entry.set_literal_count(materialized_literal_count); |
| 3976 entry.set_end_pos(end_pos); | 4000 entry.set_property_count(expected_property_count); |
| 3977 entry.set_literal_count(materialized_literal_count); | 4001 entry.set_predata_skip(log()->position() - predata_position_before); |
| 3978 entry.set_property_count(expected_property_count); | 4002 } |
| 3979 } | 4003 } |
| 3980 | 4004 |
| 3981 FunctionLiteral* function_literal = | 4005 FunctionLiteral* function_literal = |
| 3982 NEW(FunctionLiteral(name, | 4006 NEW(FunctionLiteral(name, |
| 3983 top_scope_, | 4007 top_scope_, |
| 3984 body.elements(), | 4008 body.elements(), |
| 3985 materialized_literal_count, | 4009 materialized_literal_count, |
| 3986 expected_property_count, | 4010 expected_property_count, |
| 3987 only_simple_this_property_assignments, | 4011 only_simple_this_property_assignments, |
| 3988 this_property_assignments, | 4012 this_property_assignments, |
| (...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5330 parser.ParseLazy(script_source, name, | 5354 parser.ParseLazy(script_source, name, |
| 5331 start_position, end_position, is_expression); | 5355 start_position, end_position, is_expression); |
| 5332 return result; | 5356 return result; |
| 5333 } | 5357 } |
| 5334 | 5358 |
| 5335 | 5359 |
| 5336 #undef NEW | 5360 #undef NEW |
| 5337 | 5361 |
| 5338 | 5362 |
| 5339 } } // namespace v8::internal | 5363 } } // namespace v8::internal |
| OLD | NEW |