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

Side by Side Diff: src/parser.cc

Issue 3185026: Reordered function entries in PreParse data to be ordered by start position. (Closed)
Patch Set: Added parentheses. Created 10 years, 4 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
« no previous file with comments | « src/parser.h ('k') | src/scanner.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 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698