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

Side by Side Diff: src/parser.cc

Issue 3308010: Avoid (some) symbol lookups at parse time if preparse data is available. (Closed)
Patch Set: Fixed indentation too. Created 10 years, 3 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
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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // Magical syntax support. 259 // Magical syntax support.
260 Expression* ParseV8Intrinsic(bool* ok); 260 Expression* ParseV8Intrinsic(bool* ok);
261 261
262 INLINE(Token::Value peek()) { return scanner_.peek(); } 262 INLINE(Token::Value peek()) { return scanner_.peek(); }
263 INLINE(Token::Value Next()) { return scanner_.Next(); } 263 INLINE(Token::Value Next()) { return scanner_.Next(); }
264 INLINE(void Consume(Token::Value token)); 264 INLINE(void Consume(Token::Value token));
265 void Expect(Token::Value token, bool* ok); 265 void Expect(Token::Value token, bool* ok);
266 bool Check(Token::Value token); 266 bool Check(Token::Value token);
267 void ExpectSemicolon(bool* ok); 267 void ExpectSemicolon(bool* ok);
268 268
269 Handle<String> GetSymbol(bool* ok);
270
269 // Get odd-ball literals. 271 // Get odd-ball literals.
270 Literal* GetLiteralUndefined(); 272 Literal* GetLiteralUndefined();
271 Literal* GetLiteralTheHole(); 273 Literal* GetLiteralTheHole();
272 Literal* GetLiteralNumber(double value); 274 Literal* GetLiteralNumber(double value);
273 275
274 Handle<String> ParseIdentifier(bool* ok); 276 Handle<String> ParseIdentifier(bool* ok);
275 Handle<String> ParseIdentifierName(bool* ok); 277 Handle<String> ParseIdentifierName(bool* ok);
276 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, 278 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
277 bool* is_set, 279 bool* is_set,
278 bool* ok); 280 bool* ok);
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 823
822 class ParserFactory BASE_EMBEDDED { 824 class ParserFactory BASE_EMBEDDED {
823 public: 825 public:
824 explicit ParserFactory(bool is_pre_parsing) : 826 explicit ParserFactory(bool is_pre_parsing) :
825 is_pre_parsing_(is_pre_parsing) { } 827 is_pre_parsing_(is_pre_parsing) { }
826 828
827 virtual ~ParserFactory() { } 829 virtual ~ParserFactory() { }
828 830
829 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); 831 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
830 832
831 virtual Handle<String> LookupSymbol(const char* string, int length) { 833 virtual Handle<String> LookupSymbol(int index, Vector<const char> string) {
832 return Handle<String>(); 834 return Handle<String>();
833 } 835 }
834 836
835 virtual Handle<String> EmptySymbol() { 837 virtual Handle<String> EmptySymbol() {
836 return Handle<String>(); 838 return Handle<String>();
837 } 839 }
838 840
839 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { 841 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) {
840 if (obj == VariableProxySentinel::this_proxy()) { 842 if (obj == VariableProxySentinel::this_proxy()) {
841 return Property::this_property(); 843 return Property::this_property();
(...skipping 20 matching lines...) Expand all
862 bool is_pre_parsing_; 864 bool is_pre_parsing_;
863 }; 865 };
864 866
865 867
866 class ParserLog BASE_EMBEDDED { 868 class ParserLog BASE_EMBEDDED {
867 public: 869 public:
868 virtual ~ParserLog() { } 870 virtual ~ParserLog() { }
869 871
870 // Records the occurrence of a function. 872 // Records the occurrence of a function.
871 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } 873 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); }
874 virtual void LogSymbol(int start, Vector<const char> symbol) {}
872 // Return the current position in the function entry log. 875 // Return the current position in the function entry log.
873 virtual int position() { return 0; } 876 virtual int function_position() { return 0; }
877 virtual int symbol_position() { return 0; }
878 virtual int symbol_ids() { return 0; }
874 virtual void LogError() { } 879 virtual void LogError() { }
875 }; 880 };
876 881
877 882
878 class AstBuildingParserFactory : public ParserFactory { 883 class AstBuildingParserFactory : public ParserFactory {
879 public: 884 public:
880 AstBuildingParserFactory() : ParserFactory(false) { } 885 explicit AstBuildingParserFactory(int expected_symbols)
886 : ParserFactory(false), symbol_cache_(expected_symbols) { }
881 887
882 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); 888 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
883 889
884 virtual Handle<String> LookupSymbol(const char* string, int length) { 890 virtual Handle<String> LookupSymbol(int symbol_id,
885 return Factory::LookupSymbol(Vector<const char>(string, length)); 891 Vector<const char> string) {
892 // If there is no preparse data, we have no simpler way to identify similar
893 // symbols.
894 if (symbol_id < 0) return Factory::LookupSymbol(string);
895 return LookupCachedSymbol(symbol_id, string);
896 }
897
898 Handle<String> LookupCachedSymbol(int symbol_id,
899 Vector<const char> string) {
900 // Make sure the cache is large enough to hold the symbol identifier.
901 if (symbol_cache_.length() <= symbol_id) {
902 // Increase length to index + 1.
903 symbol_cache_.AddBlock(Handle<String>::null(),
904 symbol_id + 1 - symbol_cache_.length());
905 }
906 Handle<String> result = symbol_cache_.at(symbol_id);
907 if (result.is_null()) {
908 result = Factory::LookupSymbol(string);
909 symbol_cache_.at(symbol_id) = result;
910 return result;
911 }
912 Counters::total_preparse_symbols_skipped.Increment();
913 return result;
886 } 914 }
887 915
888 virtual Handle<String> EmptySymbol() { 916 virtual Handle<String> EmptySymbol() {
889 return Factory::empty_symbol(); 917 return Factory::empty_symbol();
890 } 918 }
891 919
892 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { 920 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) {
893 return new Property(obj, key, pos); 921 return new Property(obj, key, pos);
894 } 922 }
895 923
896 virtual Expression* NewCall(Expression* expression, 924 virtual Expression* NewCall(Expression* expression,
897 ZoneList<Expression*>* arguments, 925 ZoneList<Expression*>* arguments,
898 int pos) { 926 int pos) {
899 return new Call(expression, arguments, pos); 927 return new Call(expression, arguments, pos);
900 } 928 }
901 929
902 virtual Statement* EmptyStatement(); 930 virtual Statement* EmptyStatement();
931 private:
932 List<Handle<String> > symbol_cache_;
903 }; 933 };
904 934
905 935
906 class ParserRecorder: public ParserLog { 936 class ParserRecorder: public ParserLog {
907 public: 937 public:
908 ParserRecorder(); 938 ParserRecorder();
909 virtual FunctionEntry LogFunction(int start); 939 virtual FunctionEntry LogFunction(int start);
940 virtual void LogSymbol(int start, Vector<const char> literal) {
941 int hash = vector_hash(literal);
942 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
943 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
944 if (id == 0) {
945 // Put (symbol_id_ + 1) into entry and increment it.
946 symbol_id_++;
947 entry->value = reinterpret_cast<void*>(symbol_id_);
948 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
949 entry->key = &symbol[0];
950 } else {
951 // Log a reuse of an earlier seen symbol.
952 symbol_store_.Add(start);
953 symbol_store_.Add(id - 1);
954 }
955 }
910 virtual void LogError() { } 956 virtual void LogError() { }
911 virtual void LogMessage(Scanner::Location loc, 957 virtual void LogMessage(Scanner::Location loc,
912 const char* message, 958 const char* message,
913 Vector<const char*> args); 959 Vector<const char*> args);
914 Vector<unsigned> ExtractData() { 960 Vector<unsigned> ExtractData() {
915 int total_size = ScriptDataImpl::kHeaderSize + store_.size(); 961 int function_size = function_store_.size();
962 int symbol_size = symbol_store_.size();
963 int total_size = ScriptDataImpl::kHeaderSize + function_size + symbol_size;
916 Vector<unsigned> data = Vector<unsigned>::New(total_size); 964 Vector<unsigned> data = Vector<unsigned>::New(total_size);
965 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
966 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_;
917 memcpy(data.start(), preamble_, sizeof(preamble_)); 967 memcpy(data.start(), preamble_, sizeof(preamble_));
918 if (ScriptDataImpl::kHeaderSize < total_size) { 968 int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
919 store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, total_size)); 969 if (function_size > 0) {
970 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
971 symbol_start));
972 }
973 if (symbol_size > 0) {
974 symbol_store_.WriteTo(data.SubVector(symbol_start, total_size));
920 } 975 }
921 return data; 976 return data;
922 } 977 }
923 virtual int position() { return store_.size(); } 978
979 virtual int function_position() { return function_store_.size(); }
980 virtual int symbol_position() { return symbol_store_.size(); }
981 virtual int symbol_ids() { return symbol_id_; }
924 private: 982 private:
925 Collector<unsigned> store_; 983 Collector<unsigned> function_store_;
984 Collector<unsigned> symbol_store_;
985 Collector<Vector<const char> > symbol_entries_;
986 HashMap symbol_table_;
987 int symbol_id_;
988
989 static int vector_hash(Vector<const char> string) {
990 int hash = 0;
991 for (int i = 0; i < string.length(); i++) {
992 int c = string[i];
993 hash += c;
994 hash += (hash << 10);
995 hash ^= (hash >> 6);
996 }
997 return hash;
998 }
999
1000 static bool vector_compare(void* a, void* b) {
1001 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a);
1002 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b);
1003 int length = string1->length();
1004 if (string2->length() != length) return false;
1005 return memcmp(string1->start(), string2->start(), length) == 0;
1006 }
1007
926 unsigned preamble_[ScriptDataImpl::kHeaderSize]; 1008 unsigned preamble_[ScriptDataImpl::kHeaderSize];
927 #ifdef DEBUG 1009 #ifdef DEBUG
928 int prev_start; 1010 int prev_start;
929 #endif 1011 #endif
930 1012
931 bool has_error() { 1013 bool has_error() {
932 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); 1014 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
933 } 1015 }
934 void WriteString(Vector<const char> str); 1016 void WriteString(Vector<const char> str);
935 }; 1017 };
936 1018
937 1019
938 void ScriptDataImpl::SkipFunctionEntry(int start) { 1020 void ScriptDataImpl::SkipFunctionEntry(int start) {
939 ASSERT(index_ + FunctionEntry::kSize <= store_.length()); 1021 ASSERT(function_index_ + FunctionEntry::kSize <= store_.length());
940 ASSERT(static_cast<int>(store_[index_]) == start); 1022 ASSERT(static_cast<int>(store_[function_index_]) == start);
941 index_ += FunctionEntry::kSize; 1023 function_index_ += FunctionEntry::kSize;
942 } 1024 }
943 1025
944 1026
945 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 1027 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
946 // The current pre-data entry must be a FunctionEntry with the given 1028 // The current pre-data entry must be a FunctionEntry with the given
947 // start position. 1029 // start position.
948 if ((index_ + FunctionEntry::kSize <= store_.length()) 1030 if ((function_index_ + FunctionEntry::kSize <= store_.length())
949 && (static_cast<int>(store_[index_]) == start)) { 1031 && (static_cast<int>(store_[function_index_]) == start)) {
950 int index = index_; 1032 int index = function_index_;
951 index_ += FunctionEntry::kSize; 1033 function_index_ += FunctionEntry::kSize;
952 return FunctionEntry(store_.SubVector(index, 1034 return FunctionEntry(store_.SubVector(index,
953 index + FunctionEntry::kSize)); 1035 index + FunctionEntry::kSize));
954 } 1036 }
955 return FunctionEntry(); 1037 return FunctionEntry();
956 } 1038 }
957 1039
958 1040
1041 int ScriptDataImpl::GetSymbolIdentifier(int start) {
1042 int next = symbol_index_ + 2;
1043 if (next <= store_.length()
1044 && static_cast<int>(store_[symbol_index_]) == start) {
1045 symbol_index_ = next;
1046 return store_[next - 1];
1047 }
1048 return symbol_id_++;
1049 }
1050
1051
1052
959 bool ScriptDataImpl::SanityCheck() { 1053 bool ScriptDataImpl::SanityCheck() {
960 if (store_.length() < static_cast<int>(ScriptDataImpl::kHeaderSize)) { 1054 // Check that the header data is valid and doesn't specify
961 return false; 1055 // point to positions outside the store.
962 } 1056 if (store_.length() < ScriptDataImpl::kHeaderSize) return false;
963 if (magic() != ScriptDataImpl::kMagicNumber) return false; 1057 if (magic() != ScriptDataImpl::kMagicNumber) return false;
964 if (version() != ScriptDataImpl::kCurrentVersion) return false; 1058 if (version() != ScriptDataImpl::kCurrentVersion) return false;
1059 if (has_error()) {
1060 // Extra sane sanity check for error message encoding.
1061 if (store_.length() <= kHeaderSize + kMessageTextPos) return false;
1062 if (Read(kMessageStartPos) > Read(kMessageEndPos)) return false;
1063 unsigned arg_count = Read(kMessageArgCountPos);
1064 int pos = kMessageTextPos;
1065 for (unsigned int i = 0; i <= arg_count; i++) {
1066 if (store_.length() <= kHeaderSize + pos) return false;
1067 int length = static_cast<int>(Read(pos));
1068 if (length < 0) return false;
1069 pos += 1 + length;
1070 }
1071 if (store_.length() < kHeaderSize + pos) return false;
1072 return true;
1073 }
1074 // Check that the space allocated for function entries is sane.
1075 int functions_size =
1076 static_cast<int>(store_[ScriptDataImpl::kFunctionsSizeOffset]);
1077 if (functions_size < 0) return false;
1078 if (functions_size % FunctionEntry::kSize != 0) return false;
1079 // Check that the count of symbols is non-negative.
1080 int symbol_count =
1081 static_cast<int>(store_[ScriptDataImpl::kSymbolCountOffset]);
1082 if (symbol_count < 0) return false;
1083 // Check that the total size has room both function entries.
1084 int minimum_size =
1085 ScriptDataImpl::kHeaderSize + functions_size;
1086 if (store_.length() < minimum_size) return false;
965 return true; 1087 return true;
966 } 1088 }
967 1089
968 1090
969 ParserRecorder::ParserRecorder() 1091 ParserRecorder::ParserRecorder()
970 : store_(0) { 1092 : function_store_(0),
1093 symbol_store_(0),
1094 symbol_entries_(0),
1095 symbol_table_(vector_compare),
1096 symbol_id_(0) {
971 #ifdef DEBUG 1097 #ifdef DEBUG
972 prev_start = -1; 1098 prev_start = -1;
973 #endif 1099 #endif
974 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; 1100 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
975 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; 1101 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
976 preamble_[ScriptDataImpl::kHasErrorOffset] = false; 1102 preamble_[ScriptDataImpl::kHasErrorOffset] = false;
1103 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0;
1104 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
977 preamble_[ScriptDataImpl::kSizeOffset] = 0; 1105 preamble_[ScriptDataImpl::kSizeOffset] = 0;
978 ASSERT_EQ(4, ScriptDataImpl::kHeaderSize); 1106 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize);
979 } 1107 }
980 1108
981 1109
982 void ParserRecorder::WriteString(Vector<const char> str) { 1110 void ParserRecorder::WriteString(Vector<const char> str) {
983 store_.Add(str.length()); 1111 function_store_.Add(str.length());
984 for (int i = 0; i < str.length(); i++) { 1112 for (int i = 0; i < str.length(); i++) {
985 store_.Add(str[i]); 1113 function_store_.Add(str[i]);
986 } 1114 }
987 } 1115 }
988 1116
989 1117
990 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { 1118 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
991 int length = start[0]; 1119 int length = start[0];
992 char* result = NewArray<char>(length + 1); 1120 char* result = NewArray<char>(length + 1);
993 for (int i = 0; i < length; i++) { 1121 for (int i = 0; i < length; i++) {
994 result[i] = start[i + 1]; 1122 result[i] = start[i + 1];
995 } 1123 }
996 result[length] = '\0'; 1124 result[length] = '\0';
997 if (chars != NULL) *chars = length; 1125 if (chars != NULL) *chars = length;
998 return result; 1126 return result;
999 } 1127 }
1000 1128
1001 1129
1002 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, 1130 void ParserRecorder::LogMessage(Scanner::Location loc, const char* message,
1003 Vector<const char*> args) { 1131 Vector<const char*> args) {
1004 if (has_error()) return; 1132 if (has_error()) return;
1005 preamble_[ScriptDataImpl::kHasErrorOffset] = true; 1133 preamble_[ScriptDataImpl::kHasErrorOffset] = true;
1006 store_.Reset(); 1134 function_store_.Reset();
1007 store_.Add(loc.beg_pos); 1135 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0);
1008 store_.Add(loc.end_pos); 1136 function_store_.Add(loc.beg_pos);
1009 store_.Add(args.length()); 1137 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1);
1138 function_store_.Add(loc.end_pos);
1139 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2);
1140 function_store_.Add(args.length());
1141 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3);
1010 WriteString(CStrVector(message)); 1142 WriteString(CStrVector(message));
1011 for (int i = 0; i < args.length(); i++) { 1143 for (int i = 0; i < args.length(); i++) {
1012 WriteString(CStrVector(args[i])); 1144 WriteString(CStrVector(args[i]));
1013 } 1145 }
1014 } 1146 }
1015 1147
1016 1148
1017 Scanner::Location ScriptDataImpl::MessageLocation() { 1149 Scanner::Location ScriptDataImpl::MessageLocation() {
1018 int beg_pos = Read(0); 1150 int beg_pos = Read(kMessageStartPos);
1019 int end_pos = Read(1); 1151 int end_pos = Read(kMessageEndPos);
1020 return Scanner::Location(beg_pos, end_pos); 1152 return Scanner::Location(beg_pos, end_pos);
1021 } 1153 }
1022 1154
1023 1155
1024 const char* ScriptDataImpl::BuildMessage() { 1156 const char* ScriptDataImpl::BuildMessage() {
1025 unsigned* start = ReadAddress(3); 1157 unsigned* start = ReadAddress(kMessageTextPos);
1026 return ReadString(start, NULL); 1158 return ReadString(start, NULL);
1027 } 1159 }
1028 1160
1029 1161
1030 Vector<const char*> ScriptDataImpl::BuildArgs() { 1162 Vector<const char*> ScriptDataImpl::BuildArgs() {
1031 int arg_count = Read(2); 1163 int arg_count = Read(kMessageArgCountPos);
1032 const char** array = NewArray<const char*>(arg_count); 1164 const char** array = NewArray<const char*>(arg_count);
1033 int pos = ScriptDataImpl::kHeaderSize + Read(3); 1165 // Position after the string starting at position 3.
1166 int pos = kMessageTextPos + 1 + Read(kMessageTextPos);
1034 for (int i = 0; i < arg_count; i++) { 1167 for (int i = 0; i < arg_count; i++) {
1035 int count = 0; 1168 int count = 0;
1036 array[i] = ReadString(ReadAddress(pos), &count); 1169 array[i] = ReadString(ReadAddress(pos), &count);
1037 pos += count + 1; 1170 pos += count + 1;
1038 } 1171 }
1039 return Vector<const char*>(array, arg_count); 1172 return Vector<const char*>(array, arg_count);
1040 } 1173 }
1041 1174
1042 1175
1043 unsigned ScriptDataImpl::Read(int position) { 1176 unsigned ScriptDataImpl::Read(int position) {
1044 return store_[ScriptDataImpl::kHeaderSize + position]; 1177 return store_[ScriptDataImpl::kHeaderSize + position];
1045 } 1178 }
1046 1179
1047 1180
1048 unsigned* ScriptDataImpl::ReadAddress(int position) { 1181 unsigned* ScriptDataImpl::ReadAddress(int position) {
1049 return &store_[ScriptDataImpl::kHeaderSize + position]; 1182 return &store_[ScriptDataImpl::kHeaderSize + position];
1050 } 1183 }
1051 1184
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
1060 1185
1061 FunctionEntry ParserRecorder::LogFunction(int start) { 1186 FunctionEntry ParserRecorder::LogFunction(int start) {
1062 #ifdef DEBUG 1187 #ifdef DEBUG
1063 ASSERT(start > prev_start); 1188 ASSERT(start > prev_start);
1064 prev_start = start; 1189 prev_start = start;
1065 #endif 1190 #endif
1066 if (has_error()) return FunctionEntry(); 1191 if (has_error()) return FunctionEntry();
1067 FunctionEntry result(store_.AddBlock(FunctionEntry::kSize, 0)); 1192 FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0));
1068 result.set_start_pos(start); 1193 result.set_start_pos(start);
1069 return result; 1194 return result;
1070 } 1195 }
1071 1196
1072 1197
1073 class AstBuildingParser : public Parser { 1198 class AstBuildingParser : public Parser {
1074 public: 1199 public:
1075 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, 1200 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax,
1076 v8::Extension* extension, ScriptDataImpl* pre_data) 1201 v8::Extension* extension, ScriptDataImpl* pre_data)
1077 : Parser(script, allow_natives_syntax, extension, PARSE, 1202 : Parser(script,
1078 factory(), log(), pre_data) { } 1203 allow_natives_syntax,
1204 extension,
1205 PARSE,
1206 factory(),
1207 log(),
1208 pre_data),
1209 factory_(pre_data ? pre_data->symbol_count() : 16) { }
1079 virtual void ReportMessageAt(Scanner::Location loc, const char* message, 1210 virtual void ReportMessageAt(Scanner::Location loc, const char* message,
1080 Vector<const char*> args); 1211 Vector<const char*> args);
1081 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, 1212 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
1082 FunctionLiteral* fun, bool resolve, bool* ok); 1213 FunctionLiteral* fun, bool resolve, bool* ok);
1083 AstBuildingParserFactory* factory() { return &factory_; } 1214 AstBuildingParserFactory* factory() { return &factory_; }
1084 ParserLog* log() { return &log_; } 1215 ParserLog* log() { return &log_; }
1085 1216
1086 private: 1217 private:
1087 ParserLog log_; 1218 ParserLog log_;
1088 AstBuildingParserFactory factory_; 1219 AstBuildingParserFactory factory_;
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 if (result == NULL) zone_scope.DeleteOnExit(); 1566 if (result == NULL) zone_scope.DeleteOnExit();
1436 return result; 1567 return result;
1437 } 1568 }
1438 1569
1439 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 1570 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
1440 Scanner::Location source_location = scanner_.location(); 1571 Scanner::Location source_location = scanner_.location();
1441 ReportMessageAt(source_location, type, args); 1572 ReportMessageAt(source_location, type, args);
1442 } 1573 }
1443 1574
1444 1575
1576 Handle<String> Parser::GetSymbol(bool* ok) {
1577 if (pre_data() != NULL) {
1578 int symbol_id =
1579 pre_data()->GetSymbolIdentifier(scanner_.location().beg_pos);
1580 if (symbol_id < 0) {
1581 ReportInvalidPreparseData(Factory::empty_symbol(), ok);
1582 return Handle<String>::null();
1583 }
1584 return factory()->LookupSymbol(symbol_id, scanner_.literal());
1585 }
1586 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
1587 return factory()->LookupSymbol(-1, scanner_.literal());
1588 }
1589
1590
1445 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, 1591 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location,
1446 const char* type, 1592 const char* type,
1447 Vector<const char*> args) { 1593 Vector<const char*> args) {
1448 MessageLocation location(script_, 1594 MessageLocation location(script_,
1449 source_location.beg_pos, source_location.end_pos); 1595 source_location.beg_pos, source_location.end_pos);
1450 Handle<JSArray> array = Factory::NewJSArray(args.length()); 1596 Handle<JSArray> array = Factory::NewJSArray(args.length());
1451 for (int i = 0; i < args.length(); i++) { 1597 for (int i = 0; i < args.length(); i++) {
1452 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); 1598 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i])));
1453 } 1599 }
1454 Handle<Object> result = Factory::NewSyntaxError(type, array); 1600 Handle<Object> result = Factory::NewSyntaxError(type, array);
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after
3412 case Token::NUMBER: { 3558 case Token::NUMBER: {
3413 Consume(Token::NUMBER); 3559 Consume(Token::NUMBER);
3414 double value = 3560 double value =
3415 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); 3561 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS);
3416 result = NewNumberLiteral(value); 3562 result = NewNumberLiteral(value);
3417 break; 3563 break;
3418 } 3564 }
3419 3565
3420 case Token::STRING: { 3566 case Token::STRING: {
3421 Consume(Token::STRING); 3567 Consume(Token::STRING);
3422 Handle<String> symbol = 3568 Handle<String> symbol = GetSymbol(CHECK_OK);
3423 factory()->LookupSymbol(scanner_.literal_string(),
3424 scanner_.literal_length());
3425 result = NEW(Literal(symbol)); 3569 result = NEW(Literal(symbol));
3426 if (fni_ != NULL) fni_->PushLiteralName(symbol); 3570 if (fni_ != NULL) fni_->PushLiteralName(symbol);
3427 break; 3571 break;
3428 } 3572 }
3429 3573
3430 case Token::ASSIGN_DIV: 3574 case Token::ASSIGN_DIV:
3431 result = ParseRegExpLiteral(true, CHECK_OK); 3575 result = ParseRegExpLiteral(true, CHECK_OK);
3432 break; 3576 break;
3433 3577
3434 case Token::DIV: 3578 case Token::DIV:
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
3682 3826
3683 3827
3684 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 3828 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
3685 bool* ok) { 3829 bool* ok) {
3686 // Special handling of getter and setter syntax: 3830 // Special handling of getter and setter syntax:
3687 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3831 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3688 // We have already read the "get" or "set" keyword. 3832 // We have already read the "get" or "set" keyword.
3689 Token::Value next = Next(); 3833 Token::Value next = Next();
3690 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). 3834 // TODO(820): Allow NUMBER and STRING as well (and handle array indices).
3691 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { 3835 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) {
3692 Handle<String> name = 3836 Handle<String> name = GetSymbol(CHECK_OK);
3693 factory()->LookupSymbol(scanner_.literal_string(),
3694 scanner_.literal_length());
3695 FunctionLiteral* value = 3837 FunctionLiteral* value =
3696 ParseFunctionLiteral(name, 3838 ParseFunctionLiteral(name,
3697 RelocInfo::kNoPosition, 3839 RelocInfo::kNoPosition,
3698 DECLARATION, 3840 DECLARATION,
3699 CHECK_OK); 3841 CHECK_OK);
3700 ObjectLiteral::Property* property = 3842 ObjectLiteral::Property* property =
3701 NEW(ObjectLiteral::Property(is_getter, value)); 3843 NEW(ObjectLiteral::Property(is_getter, value));
3702 return property; 3844 return property;
3703 } else { 3845 } else {
3704 ReportUnexpectedToken(next); 3846 ReportUnexpectedToken(next);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3748 } 3890 }
3749 continue; // restart the while 3891 continue; // restart the while
3750 } 3892 }
3751 // Failed to parse as get/set property, so it's just a property 3893 // Failed to parse as get/set property, so it's just a property
3752 // called "get" or "set". 3894 // called "get" or "set".
3753 key = NEW(Literal(id)); 3895 key = NEW(Literal(id));
3754 break; 3896 break;
3755 } 3897 }
3756 case Token::STRING: { 3898 case Token::STRING: {
3757 Consume(Token::STRING); 3899 Consume(Token::STRING);
3758 Handle<String> string = 3900 Handle<String> string = GetSymbol(CHECK_OK);
3759 factory()->LookupSymbol(scanner_.literal_string(),
3760 scanner_.literal_length());
3761 if (fni_ != NULL) fni_->PushLiteralName(string); 3901 if (fni_ != NULL) fni_->PushLiteralName(string);
3762 uint32_t index; 3902 uint32_t index;
3763 if (!string.is_null() && string->AsArrayIndex(&index)) { 3903 if (!string.is_null() && string->AsArrayIndex(&index)) {
3764 key = NewNumberLiteral(index); 3904 key = NewNumberLiteral(index);
3765 break; 3905 break;
3766 } 3906 }
3767 key = NEW(Literal(string)); 3907 key = NEW(Literal(string));
3768 break; 3908 break;
3769 } 3909 }
3770 case Token::NUMBER: { 3910 case Token::NUMBER: {
3771 Consume(Token::NUMBER); 3911 Consume(Token::NUMBER);
3772 double value = 3912 double value =
3773 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); 3913 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS);
3774 key = NewNumberLiteral(value); 3914 key = NewNumberLiteral(value);
3775 break; 3915 break;
3776 } 3916 }
3777 default: 3917 default:
3778 if (Token::IsKeyword(next)) { 3918 if (Token::IsKeyword(next)) {
3779 Consume(next); 3919 Consume(next);
3780 Handle<String> string = 3920 Handle<String> string = GetSymbol(CHECK_OK);
3781 factory()->LookupSymbol(scanner_.literal_string(),
3782 scanner_.literal_length());
3783 key = NEW(Literal(string)); 3921 key = NEW(Literal(string));
3784 } else { 3922 } else {
3785 // Unexpected token. 3923 // Unexpected token.
3786 Token::Value next = Next(); 3924 Token::Value next = Next();
3787 ReportUnexpectedToken(next); 3925 ReportUnexpectedToken(next);
3788 *ok = false; 3926 *ok = false;
3789 return NULL; 3927 return NULL;
3790 } 3928 }
3791 } 3929 }
3792 3930
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
3965 if (!entry.is_valid()) { 4103 if (!entry.is_valid()) {
3966 ReportInvalidPreparseData(name, CHECK_OK); 4104 ReportInvalidPreparseData(name, CHECK_OK);
3967 } 4105 }
3968 end_pos = entry.end_pos(); 4106 end_pos = entry.end_pos();
3969 if (end_pos <= function_block_pos) { 4107 if (end_pos <= function_block_pos) {
3970 // End position greater than end of stream is safe, and hard to check. 4108 // End position greater than end of stream is safe, and hard to check.
3971 ReportInvalidPreparseData(name, CHECK_OK); 4109 ReportInvalidPreparseData(name, CHECK_OK);
3972 } 4110 }
3973 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); 4111 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos);
3974 scanner_.SeekForward(end_pos); 4112 scanner_.SeekForward(end_pos);
3975 pre_data()->Skip(entry.predata_skip()); 4113 pre_data()->Skip(entry.predata_function_skip(),
4114 entry.predata_symbol_skip(),
4115 entry.symbol_id_skip());
3976 materialized_literal_count = entry.literal_count(); 4116 materialized_literal_count = entry.literal_count();
3977 expected_property_count = entry.property_count(); 4117 expected_property_count = entry.property_count();
3978 only_simple_this_property_assignments = false; 4118 only_simple_this_property_assignments = false;
3979 this_property_assignments = Factory::empty_fixed_array(); 4119 this_property_assignments = Factory::empty_fixed_array();
3980 Expect(Token::RBRACE, CHECK_OK); 4120 Expect(Token::RBRACE, CHECK_OK);
3981 } else { 4121 } else {
3982 if (pre_data() != NULL) { 4122 if (pre_data() != NULL) {
3983 // Skip pre-data entry for non-lazily compiled function. 4123 // Skip pre-data entry for non-lazily compiled function.
3984 pre_data()->SkipFunctionEntry(function_block_pos); 4124 pre_data()->SkipFunctionEntry(function_block_pos);
3985 } 4125 }
3986 FunctionEntry entry = log()->LogFunction(function_block_pos); 4126 FunctionEntry entry = log()->LogFunction(function_block_pos);
3987 int predata_position_before = log()->position(); 4127 int predata_function_position_before = log()->function_position();
4128 int predata_symbol_position_before = log()->symbol_position();
4129 int symbol_ids_before = log()->symbol_ids();
3988 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); 4130 ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
3989 materialized_literal_count = temp_scope.materialized_literal_count(); 4131 materialized_literal_count = temp_scope.materialized_literal_count();
3990 expected_property_count = temp_scope.expected_property_count(); 4132 expected_property_count = temp_scope.expected_property_count();
3991 only_simple_this_property_assignments = 4133 only_simple_this_property_assignments =
3992 temp_scope.only_simple_this_property_assignments(); 4134 temp_scope.only_simple_this_property_assignments();
3993 this_property_assignments = temp_scope.this_property_assignments(); 4135 this_property_assignments = temp_scope.this_property_assignments();
3994 4136
3995 Expect(Token::RBRACE, CHECK_OK); 4137 Expect(Token::RBRACE, CHECK_OK);
3996 end_pos = scanner_.location().end_pos; 4138 end_pos = scanner_.location().end_pos;
3997 if (entry.is_valid()) { 4139 if (entry.is_valid()) {
3998 entry.set_end_pos(end_pos); 4140 entry.set_end_pos(end_pos);
3999 entry.set_literal_count(materialized_literal_count); 4141 entry.set_literal_count(materialized_literal_count);
4000 entry.set_property_count(expected_property_count); 4142 entry.set_property_count(expected_property_count);
4001 entry.set_predata_skip(log()->position() - predata_position_before); 4143 entry.set_predata_function_skip(
4144 log()->function_position() - predata_function_position_before);
4145 entry.set_predata_symbol_skip(
4146 log()->symbol_position() - predata_symbol_position_before);
4147 entry.set_symbol_id_skip(
4148 log()->symbol_ids() - symbol_ids_before);
4002 } 4149 }
4003 } 4150 }
4004 4151
4005 FunctionLiteral* function_literal = 4152 FunctionLiteral* function_literal =
4006 NEW(FunctionLiteral(name, 4153 NEW(FunctionLiteral(name,
4007 top_scope_, 4154 top_scope_,
4008 body.elements(), 4155 body.elements(),
4009 materialized_literal_count, 4156 materialized_literal_count,
4010 expected_property_count, 4157 expected_property_count,
4011 only_simple_this_property_assignments, 4158 only_simple_this_property_assignments,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4141 4288
4142 4289
4143 Literal* Parser::GetLiteralNumber(double value) { 4290 Literal* Parser::GetLiteralNumber(double value) {
4144 return NewNumberLiteral(value); 4291 return NewNumberLiteral(value);
4145 } 4292 }
4146 4293
4147 4294
4148 Handle<String> Parser::ParseIdentifier(bool* ok) { 4295 Handle<String> Parser::ParseIdentifier(bool* ok) {
4149 Expect(Token::IDENTIFIER, ok); 4296 Expect(Token::IDENTIFIER, ok);
4150 if (!*ok) return Handle<String>(); 4297 if (!*ok) return Handle<String>();
4151 return factory()->LookupSymbol(scanner_.literal_string(), 4298 return GetSymbol(ok);
4152 scanner_.literal_length());
4153 } 4299 }
4154 4300
4155 4301
4156 Handle<String> Parser::ParseIdentifierName(bool* ok) { 4302 Handle<String> Parser::ParseIdentifierName(bool* ok) {
4157 Token::Value next = Next(); 4303 Token::Value next = Next();
4158 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { 4304 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) {
4159 ReportUnexpectedToken(next); 4305 ReportUnexpectedToken(next);
4160 *ok = false; 4306 *ok = false;
4161 return Handle<String>(); 4307 return Handle<String>();
4162 } 4308 }
4163 return factory()->LookupSymbol(scanner_.literal_string(), 4309 return GetSymbol(ok);
4164 scanner_.literal_length());
4165 } 4310 }
4166 4311
4167 4312
4168 // This function reads an identifier and determines whether or not it 4313 // This function reads an identifier and determines whether or not it
4169 // is 'get' or 'set'. The reason for not using ParseIdentifier and 4314 // is 'get' or 'set'. The reason for not using ParseIdentifier and
4170 // checking on the output is that this involves heap allocation which 4315 // checking on the output is that this involves heap allocation which
4171 // we can't do during preparsing. 4316 // we can't do during preparsing.
4172 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 4317 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
4173 bool* is_set, 4318 bool* is_set,
4174 bool* ok) { 4319 bool* ok) {
4175 Expect(Token::IDENTIFIER, ok); 4320 Expect(Token::IDENTIFIER, ok);
4176 if (!*ok) return Handle<String>(); 4321 if (!*ok) return Handle<String>();
4177 if (scanner_.literal_length() == 3) { 4322 if (scanner_.literal_length() == 3) {
4178 const char* token = scanner_.literal_string(); 4323 const char* token = scanner_.literal_string();
4179 *is_get = strcmp(token, "get") == 0; 4324 *is_get = strcmp(token, "get") == 0;
4180 *is_set = !*is_get && strcmp(token, "set") == 0; 4325 *is_set = !*is_get && strcmp(token, "set") == 0;
4181 } 4326 }
4182 return factory()->LookupSymbol(scanner_.literal_string(), 4327 return GetSymbol(ok);
4183 scanner_.literal_length());
4184 } 4328 }
4185 4329
4186 4330
4187 // ---------------------------------------------------------------------------- 4331 // ----------------------------------------------------------------------------
4188 // Parser support 4332 // Parser support
4189 4333
4190 4334
4191 bool Parser::TargetStackContainsLabel(Handle<String> label) { 4335 bool Parser::TargetStackContainsLabel(Handle<String> label) {
4192 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 4336 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4193 BreakableStatement* stat = t->node()->AsBreakableStatement(); 4337 BreakableStatement* stat = t->node()->AsBreakableStatement();
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
4355 4499
4356 // Parse a JSON object. Scanner must be right after '{' token. 4500 // Parse a JSON object. Scanner must be right after '{' token.
4357 Expression* Parser::ParseJsonObject(bool* ok) { 4501 Expression* Parser::ParseJsonObject(bool* ok) {
4358 Consume(Token::LBRACE); 4502 Consume(Token::LBRACE);
4359 ZoneListWrapper<ObjectLiteral::Property> properties = 4503 ZoneListWrapper<ObjectLiteral::Property> properties =
4360 factory()->NewList<ObjectLiteral::Property>(4); 4504 factory()->NewList<ObjectLiteral::Property>(4);
4361 int boilerplate_properties = 0; 4505 int boilerplate_properties = 0;
4362 if (peek() != Token::RBRACE) { 4506 if (peek() != Token::RBRACE) {
4363 do { 4507 do {
4364 Expect(Token::STRING, CHECK_OK); 4508 Expect(Token::STRING, CHECK_OK);
4365 Handle<String> key = factory()->LookupSymbol(scanner_.literal_string(), 4509 Handle<String> key = GetSymbol(CHECK_OK);
4366 scanner_.literal_length());
4367 Expect(Token::COLON, CHECK_OK); 4510 Expect(Token::COLON, CHECK_OK);
4368 Expression* value = ParseJsonValue(CHECK_OK); 4511 Expression* value = ParseJsonValue(CHECK_OK);
4369 Literal* key_literal; 4512 Literal* key_literal;
4370 uint32_t index; 4513 uint32_t index;
4371 if (key->AsArrayIndex(&index)) { 4514 if (key->AsArrayIndex(&index)) {
4372 key_literal = NewNumberLiteral(index); 4515 key_literal = NewNumberLiteral(index);
4373 } else { 4516 } else {
4374 key_literal = NEW(Literal(key)); 4517 key_literal = NEW(Literal(key));
4375 } 4518 }
4376 ObjectLiteral::Property* property = 4519 ObjectLiteral::Property* property =
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
5244 5387
5245 5388
5246 ParserMessage::~ParserMessage() { 5389 ParserMessage::~ParserMessage() {
5247 for (int i = 0; i < args().length(); i++) 5390 for (int i = 0; i < args().length(); i++)
5248 DeleteArray(args()[i]); 5391 DeleteArray(args()[i]);
5249 DeleteArray(args().start()); 5392 DeleteArray(args().start());
5250 } 5393 }
5251 5394
5252 5395
5253 ScriptDataImpl::~ScriptDataImpl() { 5396 ScriptDataImpl::~ScriptDataImpl() {
5254 store_.Dispose(); 5397 if (owns_store_) store_.Dispose();
5255 } 5398 }
5256 5399
5257 5400
5258 int ScriptDataImpl::Length() { 5401 int ScriptDataImpl::Length() {
5259 return store_.length() * sizeof(unsigned); 5402 return store_.length() * sizeof(unsigned);
5260 } 5403 }
5261 5404
5262 5405
5263 const char* ScriptDataImpl::Data() { 5406 const char* ScriptDataImpl::Data() {
5264 return reinterpret_cast<const char*>(store_.start()); 5407 return reinterpret_cast<const char*>(store_.start());
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
5358 parser.ParseLazy(script_source, name, 5501 parser.ParseLazy(script_source, name,
5359 start_position, end_position, is_expression); 5502 start_position, end_position, is_expression);
5360 return result; 5503 return result;
5361 } 5504 }
5362 5505
5363 5506
5364 #undef NEW 5507 #undef NEW
5365 5508
5366 5509
5367 } } // namespace v8::internal 5510 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/v8-counters.h » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698