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

Side by Side Diff: src/jsregexp.cc

Issue 10534006: Remove TLS access for current Zone. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review. Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/jsregexp.h ('k') | src/list-inl.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 // to that trace. The code generator therefore has the ability to generate 813 // to that trace. The code generator therefore has the ability to generate
814 // code for each node several times. In order to limit the size of the 814 // code for each node several times. In order to limit the size of the
815 // generated code there is an arbitrary limit on how many specialized sets of 815 // generated code there is an arbitrary limit on how many specialized sets of
816 // code may be generated for a given node. If the limit is reached, the 816 // code may be generated for a given node. If the limit is reached, the
817 // trace is flushed and a generic version of the code for a node is emitted. 817 // trace is flushed and a generic version of the code for a node is emitted.
818 // This is subsequently used for that node. The code emitted for non-generic 818 // This is subsequently used for that node. The code emitted for non-generic
819 // trace is not recorded in the node and so it cannot currently be reused in 819 // trace is not recorded in the node and so it cannot currently be reused in
820 // the event that code generation is requested for an identical trace. 820 // the event that code generation is requested for an identical trace.
821 821
822 822
823 void RegExpTree::AppendToText(RegExpText* text) { 823 void RegExpTree::AppendToText(RegExpText* text, Zone* zone) {
824 UNREACHABLE(); 824 UNREACHABLE();
825 } 825 }
826 826
827 827
828 void RegExpAtom::AppendToText(RegExpText* text) { 828 void RegExpAtom::AppendToText(RegExpText* text, Zone* zone) {
829 text->AddElement(TextElement::Atom(this)); 829 text->AddElement(TextElement::Atom(this), zone);
830 } 830 }
831 831
832 832
833 void RegExpCharacterClass::AppendToText(RegExpText* text) { 833 void RegExpCharacterClass::AppendToText(RegExpText* text, Zone* zone) {
834 text->AddElement(TextElement::CharClass(this)); 834 text->AddElement(TextElement::CharClass(this), zone);
835 } 835 }
836 836
837 837
838 void RegExpText::AppendToText(RegExpText* text) { 838 void RegExpText::AppendToText(RegExpText* text, Zone* zone) {
839 for (int i = 0; i < elements()->length(); i++) 839 for (int i = 0; i < elements()->length(); i++)
840 text->AddElement(elements()->at(i)); 840 text->AddElement(elements()->at(i), zone);
841 } 841 }
842 842
843 843
844 TextElement TextElement::Atom(RegExpAtom* atom) { 844 TextElement TextElement::Atom(RegExpAtom* atom) {
845 TextElement result = TextElement(ATOM); 845 TextElement result = TextElement(ATOM);
846 result.data.u_atom = atom; 846 result.data.u_atom = atom;
847 return result; 847 return result;
848 } 848 }
849 849
850 850
(...skipping 10 matching lines...) Expand all
861 return data.u_atom->length(); 861 return data.u_atom->length();
862 } else { 862 } else {
863 ASSERT(type == CHAR_CLASS); 863 ASSERT(type == CHAR_CLASS);
864 return 1; 864 return 1;
865 } 865 }
866 } 866 }
867 867
868 868
869 DispatchTable* ChoiceNode::GetTable(bool ignore_case) { 869 DispatchTable* ChoiceNode::GetTable(bool ignore_case) {
870 if (table_ == NULL) { 870 if (table_ == NULL) {
871 table_ = new DispatchTable(); 871 table_ = new(zone()) DispatchTable(zone());
872 DispatchTableConstructor cons(table_, ignore_case); 872 DispatchTableConstructor cons(table_, ignore_case, zone());
873 cons.BuildTable(this); 873 cons.BuildTable(this);
874 } 874 }
875 return table_; 875 return table_;
876 } 876 }
877 877
878 878
879 class FrequencyCollator { 879 class FrequencyCollator {
880 public: 880 public:
881 FrequencyCollator() : total_samples_(0) { 881 FrequencyCollator() : total_samples_(0) {
882 for (int i = 0; i < RegExpMacroAssembler::kTableSize; i++) { 882 for (int i = 0; i < RegExpMacroAssembler::kTableSize; i++) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 959
960 inline bool ignore_case() { return ignore_case_; } 960 inline bool ignore_case() { return ignore_case_; }
961 inline bool ascii() { return ascii_; } 961 inline bool ascii() { return ascii_; }
962 FrequencyCollator* frequency_collator() { return &frequency_collator_; } 962 FrequencyCollator* frequency_collator() { return &frequency_collator_; }
963 963
964 int current_expansion_factor() { return current_expansion_factor_; } 964 int current_expansion_factor() { return current_expansion_factor_; }
965 void set_current_expansion_factor(int value) { 965 void set_current_expansion_factor(int value) {
966 current_expansion_factor_ = value; 966 current_expansion_factor_ = value;
967 } 967 }
968 968
969 Zone* zone() { return zone_; } 969 Zone* zone() const { return zone_; }
970 970
971 static const int kNoRegister = -1; 971 static const int kNoRegister = -1;
972 972
973 private: 973 private:
974 EndNode* accept_; 974 EndNode* accept_;
975 int next_register_; 975 int next_register_;
976 List<RegExpNode*>* work_list_; 976 List<RegExpNode*>* work_list_;
977 int recursion_depth_; 977 int recursion_depth_;
978 RegExpMacroAssembler* macro_assembler_; 978 RegExpMacroAssembler* macro_assembler_;
979 bool ignore_case_; 979 bool ignore_case_;
(...skipping 27 matching lines...) Expand all
1007 Zone* zone) 1007 Zone* zone)
1008 : next_register_(2 * (capture_count + 1)), 1008 : next_register_(2 * (capture_count + 1)),
1009 work_list_(NULL), 1009 work_list_(NULL),
1010 recursion_depth_(0), 1010 recursion_depth_(0),
1011 ignore_case_(ignore_case), 1011 ignore_case_(ignore_case),
1012 ascii_(ascii), 1012 ascii_(ascii),
1013 reg_exp_too_big_(false), 1013 reg_exp_too_big_(false),
1014 current_expansion_factor_(1), 1014 current_expansion_factor_(1),
1015 frequency_collator_(), 1015 frequency_collator_(),
1016 zone_(zone) { 1016 zone_(zone) {
1017 accept_ = new EndNode(EndNode::ACCEPT, zone); 1017 accept_ = new(zone) EndNode(EndNode::ACCEPT, zone);
1018 ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister); 1018 ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
1019 } 1019 }
1020 1020
1021 1021
1022 RegExpEngine::CompilationResult RegExpCompiler::Assemble( 1022 RegExpEngine::CompilationResult RegExpCompiler::Assemble(
1023 RegExpMacroAssembler* macro_assembler, 1023 RegExpMacroAssembler* macro_assembler,
1024 RegExpNode* start, 1024 RegExpNode* start,
1025 int capture_count, 1025 int capture_count,
1026 Handle<String> pattern) { 1026 Handle<String> pattern) {
1027 Heap* heap = pattern->GetHeap(); 1027 Heap* heap = pattern->GetHeap();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 return true; 1103 return true;
1104 } else { 1104 } else {
1105 return false; 1105 return false;
1106 } 1106 }
1107 } 1107 }
1108 } 1108 }
1109 return false; 1109 return false;
1110 } 1110 }
1111 1111
1112 1112
1113 int Trace::FindAffectedRegisters(OutSet* affected_registers) { 1113 int Trace::FindAffectedRegisters(OutSet* affected_registers,
1114 Zone* zone) {
1114 int max_register = RegExpCompiler::kNoRegister; 1115 int max_register = RegExpCompiler::kNoRegister;
1115 for (DeferredAction* action = actions_; 1116 for (DeferredAction* action = actions_;
1116 action != NULL; 1117 action != NULL;
1117 action = action->next()) { 1118 action = action->next()) {
1118 if (action->type() == ActionNode::CLEAR_CAPTURES) { 1119 if (action->type() == ActionNode::CLEAR_CAPTURES) {
1119 Interval range = static_cast<DeferredClearCaptures*>(action)->range(); 1120 Interval range = static_cast<DeferredClearCaptures*>(action)->range();
1120 for (int i = range.from(); i <= range.to(); i++) 1121 for (int i = range.from(); i <= range.to(); i++)
1121 affected_registers->Set(i); 1122 affected_registers->Set(i, zone);
1122 if (range.to() > max_register) max_register = range.to(); 1123 if (range.to() > max_register) max_register = range.to();
1123 } else { 1124 } else {
1124 affected_registers->Set(action->reg()); 1125 affected_registers->Set(action->reg(), zone);
1125 if (action->reg() > max_register) max_register = action->reg(); 1126 if (action->reg() > max_register) max_register = action->reg();
1126 } 1127 }
1127 } 1128 }
1128 return max_register; 1129 return max_register;
1129 } 1130 }
1130 1131
1131 1132
1132 void Trace::RestoreAffectedRegisters(RegExpMacroAssembler* assembler, 1133 void Trace::RestoreAffectedRegisters(RegExpMacroAssembler* assembler,
1133 int max_register, 1134 int max_register,
1134 OutSet& registers_to_pop, 1135 OutSet& registers_to_pop,
1135 OutSet& registers_to_clear) { 1136 OutSet& registers_to_clear) {
1136 for (int reg = max_register; reg >= 0; reg--) { 1137 for (int reg = max_register; reg >= 0; reg--) {
1137 if (registers_to_pop.Get(reg)) assembler->PopRegister(reg); 1138 if (registers_to_pop.Get(reg)) assembler->PopRegister(reg);
1138 else if (registers_to_clear.Get(reg)) { 1139 else if (registers_to_clear.Get(reg)) {
1139 int clear_to = reg; 1140 int clear_to = reg;
1140 while (reg > 0 && registers_to_clear.Get(reg - 1)) { 1141 while (reg > 0 && registers_to_clear.Get(reg - 1)) {
1141 reg--; 1142 reg--;
1142 } 1143 }
1143 assembler->ClearRegisters(reg, clear_to); 1144 assembler->ClearRegisters(reg, clear_to);
1144 } 1145 }
1145 } 1146 }
1146 } 1147 }
1147 1148
1148 1149
1149 void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler, 1150 void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler,
1150 int max_register, 1151 int max_register,
1151 OutSet& affected_registers, 1152 OutSet& affected_registers,
1152 OutSet* registers_to_pop, 1153 OutSet* registers_to_pop,
1153 OutSet* registers_to_clear) { 1154 OutSet* registers_to_clear,
1155 Zone* zone) {
1154 // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1. 1156 // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1.
1155 const int push_limit = (assembler->stack_limit_slack() + 1) / 2; 1157 const int push_limit = (assembler->stack_limit_slack() + 1) / 2;
1156 1158
1157 // Count pushes performed to force a stack limit check occasionally. 1159 // Count pushes performed to force a stack limit check occasionally.
1158 int pushes = 0; 1160 int pushes = 0;
1159 1161
1160 for (int reg = 0; reg <= max_register; reg++) { 1162 for (int reg = 0; reg <= max_register; reg++) {
1161 if (!affected_registers.Get(reg)) { 1163 if (!affected_registers.Get(reg)) {
1162 continue; 1164 continue;
1163 } 1165 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 if (undo_action == RESTORE) { 1251 if (undo_action == RESTORE) {
1250 pushes++; 1252 pushes++;
1251 RegExpMacroAssembler::StackCheckFlag stack_check = 1253 RegExpMacroAssembler::StackCheckFlag stack_check =
1252 RegExpMacroAssembler::kNoStackLimitCheck; 1254 RegExpMacroAssembler::kNoStackLimitCheck;
1253 if (pushes == push_limit) { 1255 if (pushes == push_limit) {
1254 stack_check = RegExpMacroAssembler::kCheckStackLimit; 1256 stack_check = RegExpMacroAssembler::kCheckStackLimit;
1255 pushes = 0; 1257 pushes = 0;
1256 } 1258 }
1257 1259
1258 assembler->PushRegister(reg, stack_check); 1260 assembler->PushRegister(reg, stack_check);
1259 registers_to_pop->Set(reg); 1261 registers_to_pop->Set(reg, zone);
1260 } else if (undo_action == CLEAR) { 1262 } else if (undo_action == CLEAR) {
1261 registers_to_clear->Set(reg); 1263 registers_to_clear->Set(reg, zone);
1262 } 1264 }
1263 // Perform the chronologically last action (or accumulated increment) 1265 // Perform the chronologically last action (or accumulated increment)
1264 // for the register. 1266 // for the register.
1265 if (store_position != -1) { 1267 if (store_position != -1) {
1266 assembler->WriteCurrentPositionToRegister(reg, store_position); 1268 assembler->WriteCurrentPositionToRegister(reg, store_position);
1267 } else if (clear) { 1269 } else if (clear) {
1268 assembler->ClearRegisters(reg, reg); 1270 assembler->ClearRegisters(reg, reg);
1269 } else if (absolute) { 1271 } else if (absolute) {
1270 assembler->SetRegister(reg, value); 1272 assembler->SetRegister(reg, value);
1271 } else if (value != 0) { 1273 } else if (value != 0) {
(...skipping 25 matching lines...) Expand all
1297 // Generate deferred actions here along with code to undo them again. 1299 // Generate deferred actions here along with code to undo them again.
1298 OutSet affected_registers; 1300 OutSet affected_registers;
1299 1301
1300 if (backtrack() != NULL) { 1302 if (backtrack() != NULL) {
1301 // Here we have a concrete backtrack location. These are set up by choice 1303 // Here we have a concrete backtrack location. These are set up by choice
1302 // nodes and so they indicate that we have a deferred save of the current 1304 // nodes and so they indicate that we have a deferred save of the current
1303 // position which we may need to emit here. 1305 // position which we may need to emit here.
1304 assembler->PushCurrentPosition(); 1306 assembler->PushCurrentPosition();
1305 } 1307 }
1306 1308
1307 int max_register = FindAffectedRegisters(&affected_registers); 1309 int max_register = FindAffectedRegisters(&affected_registers,
1310 compiler->zone());
1308 OutSet registers_to_pop; 1311 OutSet registers_to_pop;
1309 OutSet registers_to_clear; 1312 OutSet registers_to_clear;
1310 PerformDeferredActions(assembler, 1313 PerformDeferredActions(assembler,
1311 max_register, 1314 max_register,
1312 affected_registers, 1315 affected_registers,
1313 &registers_to_pop, 1316 &registers_to_pop,
1314 &registers_to_clear); 1317 &registers_to_clear,
1318 compiler->zone());
1315 if (cp_offset_ != 0) { 1319 if (cp_offset_ != 0) {
1316 assembler->AdvanceCurrentPosition(cp_offset_); 1320 assembler->AdvanceCurrentPosition(cp_offset_);
1317 } 1321 }
1318 1322
1319 // Create a new trivial state and generate the node with that. 1323 // Create a new trivial state and generate the node with that.
1320 Label undo; 1324 Label undo;
1321 assembler->PushBacktrack(&undo); 1325 assembler->PushBacktrack(&undo);
1322 Trace new_state; 1326 Trace new_state;
1323 successor->Emit(compiler, &new_state); 1327 successor->Emit(compiler, &new_state);
1324 1328
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 assembler->GoTo(trace->backtrack()); 1385 assembler->GoTo(trace->backtrack());
1382 return; 1386 return;
1383 case NEGATIVE_SUBMATCH_SUCCESS: 1387 case NEGATIVE_SUBMATCH_SUCCESS:
1384 // This case is handled in a different virtual method. 1388 // This case is handled in a different virtual method.
1385 UNREACHABLE(); 1389 UNREACHABLE();
1386 } 1390 }
1387 UNIMPLEMENTED(); 1391 UNIMPLEMENTED();
1388 } 1392 }
1389 1393
1390 1394
1391 void GuardedAlternative::AddGuard(Guard* guard) { 1395 void GuardedAlternative::AddGuard(Guard* guard, Zone* zone) {
1392 if (guards_ == NULL) 1396 if (guards_ == NULL)
1393 guards_ = new ZoneList<Guard*>(1); 1397 guards_ = new(zone) ZoneList<Guard*>(1, zone);
1394 guards_->Add(guard); 1398 guards_->Add(guard, zone);
1395 } 1399 }
1396 1400
1397 1401
1398 ActionNode* ActionNode::SetRegister(int reg, 1402 ActionNode* ActionNode::SetRegister(int reg,
1399 int val, 1403 int val,
1400 RegExpNode* on_success) { 1404 RegExpNode* on_success) {
1401 ActionNode* result = new ActionNode(SET_REGISTER, on_success); 1405 ActionNode* result =
1406 new(on_success->zone()) ActionNode(SET_REGISTER, on_success);
1402 result->data_.u_store_register.reg = reg; 1407 result->data_.u_store_register.reg = reg;
1403 result->data_.u_store_register.value = val; 1408 result->data_.u_store_register.value = val;
1404 return result; 1409 return result;
1405 } 1410 }
1406 1411
1407 1412
1408 ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) { 1413 ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) {
1409 ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success); 1414 ActionNode* result =
1415 new(on_success->zone()) ActionNode(INCREMENT_REGISTER, on_success);
1410 result->data_.u_increment_register.reg = reg; 1416 result->data_.u_increment_register.reg = reg;
1411 return result; 1417 return result;
1412 } 1418 }
1413 1419
1414 1420
1415 ActionNode* ActionNode::StorePosition(int reg, 1421 ActionNode* ActionNode::StorePosition(int reg,
1416 bool is_capture, 1422 bool is_capture,
1417 RegExpNode* on_success) { 1423 RegExpNode* on_success) {
1418 ActionNode* result = new ActionNode(STORE_POSITION, on_success); 1424 ActionNode* result =
1425 new(on_success->zone()) ActionNode(STORE_POSITION, on_success);
1419 result->data_.u_position_register.reg = reg; 1426 result->data_.u_position_register.reg = reg;
1420 result->data_.u_position_register.is_capture = is_capture; 1427 result->data_.u_position_register.is_capture = is_capture;
1421 return result; 1428 return result;
1422 } 1429 }
1423 1430
1424 1431
1425 ActionNode* ActionNode::ClearCaptures(Interval range, 1432 ActionNode* ActionNode::ClearCaptures(Interval range,
1426 RegExpNode* on_success) { 1433 RegExpNode* on_success) {
1427 ActionNode* result = new ActionNode(CLEAR_CAPTURES, on_success); 1434 ActionNode* result =
1435 new(on_success->zone()) ActionNode(CLEAR_CAPTURES, on_success);
1428 result->data_.u_clear_captures.range_from = range.from(); 1436 result->data_.u_clear_captures.range_from = range.from();
1429 result->data_.u_clear_captures.range_to = range.to(); 1437 result->data_.u_clear_captures.range_to = range.to();
1430 return result; 1438 return result;
1431 } 1439 }
1432 1440
1433 1441
1434 ActionNode* ActionNode::BeginSubmatch(int stack_reg, 1442 ActionNode* ActionNode::BeginSubmatch(int stack_reg,
1435 int position_reg, 1443 int position_reg,
1436 RegExpNode* on_success) { 1444 RegExpNode* on_success) {
1437 ActionNode* result = new ActionNode(BEGIN_SUBMATCH, on_success); 1445 ActionNode* result =
1446 new(on_success->zone()) ActionNode(BEGIN_SUBMATCH, on_success);
1438 result->data_.u_submatch.stack_pointer_register = stack_reg; 1447 result->data_.u_submatch.stack_pointer_register = stack_reg;
1439 result->data_.u_submatch.current_position_register = position_reg; 1448 result->data_.u_submatch.current_position_register = position_reg;
1440 return result; 1449 return result;
1441 } 1450 }
1442 1451
1443 1452
1444 ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg, 1453 ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg,
1445 int position_reg, 1454 int position_reg,
1446 int clear_register_count, 1455 int clear_register_count,
1447 int clear_register_from, 1456 int clear_register_from,
1448 RegExpNode* on_success) { 1457 RegExpNode* on_success) {
1449 ActionNode* result = new ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success); 1458 ActionNode* result =
1459 new(on_success->zone()) ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success);
1450 result->data_.u_submatch.stack_pointer_register = stack_reg; 1460 result->data_.u_submatch.stack_pointer_register = stack_reg;
1451 result->data_.u_submatch.current_position_register = position_reg; 1461 result->data_.u_submatch.current_position_register = position_reg;
1452 result->data_.u_submatch.clear_register_count = clear_register_count; 1462 result->data_.u_submatch.clear_register_count = clear_register_count;
1453 result->data_.u_submatch.clear_register_from = clear_register_from; 1463 result->data_.u_submatch.clear_register_from = clear_register_from;
1454 return result; 1464 return result;
1455 } 1465 }
1456 1466
1457 1467
1458 ActionNode* ActionNode::EmptyMatchCheck(int start_register, 1468 ActionNode* ActionNode::EmptyMatchCheck(int start_register,
1459 int repetition_register, 1469 int repetition_register,
1460 int repetition_limit, 1470 int repetition_limit,
1461 RegExpNode* on_success) { 1471 RegExpNode* on_success) {
1462 ActionNode* result = new ActionNode(EMPTY_MATCH_CHECK, on_success); 1472 ActionNode* result =
1473 new(on_success->zone()) ActionNode(EMPTY_MATCH_CHECK, on_success);
1463 result->data_.u_empty_match_check.start_register = start_register; 1474 result->data_.u_empty_match_check.start_register = start_register;
1464 result->data_.u_empty_match_check.repetition_register = repetition_register; 1475 result->data_.u_empty_match_check.repetition_register = repetition_register;
1465 result->data_.u_empty_match_check.repetition_limit = repetition_limit; 1476 result->data_.u_empty_match_check.repetition_limit = repetition_limit;
1466 return result; 1477 return result;
1467 } 1478 }
1468 1479
1469 1480
1470 #define DEFINE_ACCEPT(Type) \ 1481 #define DEFINE_ACCEPT(Type) \
1471 void Type##Node::Accept(NodeVisitor* visitor) { \ 1482 void Type##Node::Accept(NodeVisitor* visitor) { \
1472 visitor->Visit##Type(this); \ 1483 visitor->Visit##Type(this); \
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 } 2043 }
2033 } 2044 }
2034 2045
2035 2046
2036 static void EmitCharClass(RegExpMacroAssembler* macro_assembler, 2047 static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
2037 RegExpCharacterClass* cc, 2048 RegExpCharacterClass* cc,
2038 bool ascii, 2049 bool ascii,
2039 Label* on_failure, 2050 Label* on_failure,
2040 int cp_offset, 2051 int cp_offset,
2041 bool check_offset, 2052 bool check_offset,
2042 bool preloaded) { 2053 bool preloaded,
2043 ZoneList<CharacterRange>* ranges = cc->ranges(); 2054 Zone* zone) {
2055 ZoneList<CharacterRange>* ranges = cc->ranges(zone);
2044 if (!CharacterRange::IsCanonical(ranges)) { 2056 if (!CharacterRange::IsCanonical(ranges)) {
2045 CharacterRange::Canonicalize(ranges); 2057 CharacterRange::Canonicalize(ranges);
2046 } 2058 }
2047 2059
2048 int max_char; 2060 int max_char;
2049 if (ascii) { 2061 if (ascii) {
2050 max_char = String::kMaxAsciiCharCode; 2062 max_char = String::kMaxAsciiCharCode;
2051 } else { 2063 } else {
2052 max_char = String::kMaxUtf16CodeUnit; 2064 max_char = String::kMaxUtf16CodeUnit;
2053 } 2065 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 if (check_offset) { 2104 if (check_offset) {
2093 macro_assembler->CheckPosition(cp_offset, on_failure); 2105 macro_assembler->CheckPosition(cp_offset, on_failure);
2094 } 2106 }
2095 return; 2107 return;
2096 } 2108 }
2097 2109
2098 if (!preloaded) { 2110 if (!preloaded) {
2099 macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check_offset); 2111 macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check_offset);
2100 } 2112 }
2101 2113
2102 if (cc->is_standard() && 2114 if (cc->is_standard(zone) &&
2103 macro_assembler->CheckSpecialCharacterClass(cc->standard_type(), 2115 macro_assembler->CheckSpecialCharacterClass(cc->standard_type(),
2104 on_failure)) { 2116 on_failure)) {
2105 return; 2117 return;
2106 } 2118 }
2107 2119
2108 2120
2109 // A new list with ascending entries. Each entry is a code unit 2121 // A new list with ascending entries. Each entry is a code unit
2110 // where there is a boundary between code units that are part of 2122 // where there is a boundary between code units that are part of
2111 // the class and code units that are not. Normally we insert an 2123 // the class and code units that are not. Normally we insert an
2112 // entry at zero which goes to the failure label, but if there 2124 // entry at zero which goes to the failure label, but if there
2113 // was already one there we fall through for success on that entry. 2125 // was already one there we fall through for success on that entry.
2114 // Subsequent entries have alternating meaning (success/failure). 2126 // Subsequent entries have alternating meaning (success/failure).
2115 ZoneList<int>* range_boundaries = new ZoneList<int>(last_valid_range); 2127 ZoneList<int>* range_boundaries =
2128 new(zone) ZoneList<int>(last_valid_range, zone);
2116 2129
2117 bool zeroth_entry_is_failure = !cc->is_negated(); 2130 bool zeroth_entry_is_failure = !cc->is_negated();
2118 2131
2119 for (int i = 0; i <= last_valid_range; i++) { 2132 for (int i = 0; i <= last_valid_range; i++) {
2120 CharacterRange& range = ranges->at(i); 2133 CharacterRange& range = ranges->at(i);
2121 if (range.from() == 0) { 2134 if (range.from() == 0) {
2122 ASSERT_EQ(i, 0); 2135 ASSERT_EQ(i, 0);
2123 zeroth_entry_is_failure = !zeroth_entry_is_failure; 2136 zeroth_entry_is_failure = !zeroth_entry_is_failure;
2124 } else { 2137 } else {
2125 range_boundaries->Add(range.from()); 2138 range_boundaries->Add(range.from(), zone);
2126 } 2139 }
2127 range_boundaries->Add(range.to() + 1); 2140 range_boundaries->Add(range.to() + 1, zone);
2128 } 2141 }
2129 int end_index = range_boundaries->length() - 1; 2142 int end_index = range_boundaries->length() - 1;
2130 if (range_boundaries->at(end_index) > max_char) { 2143 if (range_boundaries->at(end_index) > max_char) {
2131 end_index--; 2144 end_index--;
2132 } 2145 }
2133 2146
2134 Label fall_through; 2147 Label fall_through;
2135 GenerateBranches(macro_assembler, 2148 GenerateBranches(macro_assembler,
2136 range_boundaries, 2149 range_boundaries,
2137 0, // start_index. 2150 0, // start_index.
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 characters_filled_in++; 2528 characters_filled_in++;
2516 ASSERT(characters_filled_in <= details->characters()); 2529 ASSERT(characters_filled_in <= details->characters());
2517 if (characters_filled_in == details->characters()) { 2530 if (characters_filled_in == details->characters()) {
2518 return; 2531 return;
2519 } 2532 }
2520 } 2533 }
2521 } else { 2534 } else {
2522 QuickCheckDetails::Position* pos = 2535 QuickCheckDetails::Position* pos =
2523 details->positions(characters_filled_in); 2536 details->positions(characters_filled_in);
2524 RegExpCharacterClass* tree = elm.data.u_char_class; 2537 RegExpCharacterClass* tree = elm.data.u_char_class;
2525 ZoneList<CharacterRange>* ranges = tree->ranges(); 2538 ZoneList<CharacterRange>* ranges = tree->ranges(zone());
2526 if (tree->is_negated()) { 2539 if (tree->is_negated()) {
2527 // A quick check uses multi-character mask and compare. There is no 2540 // A quick check uses multi-character mask and compare. There is no
2528 // useful way to incorporate a negative char class into this scheme 2541 // useful way to incorporate a negative char class into this scheme
2529 // so we just conservatively create a mask and value that will always 2542 // so we just conservatively create a mask and value that will always
2530 // succeed. 2543 // succeed.
2531 pos->mask = 0; 2544 pos->mask = 0;
2532 pos->value = 0; 2545 pos->value = 0;
2533 } else { 2546 } else {
2534 int first_range = 0; 2547 int first_range = 0;
2535 while (ranges->at(first_range).from() > char_mask) { 2548 while (ranges->at(first_range).from() > char_mask) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2700 // We don't need special handling for case independence 2713 // We don't need special handling for case independence
2701 // because of the rule that case independence cannot make 2714 // because of the rule that case independence cannot make
2702 // a non-ASCII character match an ASCII character. 2715 // a non-ASCII character match an ASCII character.
2703 if (quarks[j] > String::kMaxAsciiCharCode) { 2716 if (quarks[j] > String::kMaxAsciiCharCode) {
2704 return set_replacement(NULL); 2717 return set_replacement(NULL);
2705 } 2718 }
2706 } 2719 }
2707 } else { 2720 } else {
2708 ASSERT(elm.type == TextElement::CHAR_CLASS); 2721 ASSERT(elm.type == TextElement::CHAR_CLASS);
2709 RegExpCharacterClass* cc = elm.data.u_char_class; 2722 RegExpCharacterClass* cc = elm.data.u_char_class;
2710 ZoneList<CharacterRange>* ranges = cc->ranges(); 2723 ZoneList<CharacterRange>* ranges = cc->ranges(zone());
2711 if (!CharacterRange::IsCanonical(ranges)) { 2724 if (!CharacterRange::IsCanonical(ranges)) {
2712 CharacterRange::Canonicalize(ranges); 2725 CharacterRange::Canonicalize(ranges);
2713 } 2726 }
2714 // Now they are in order so we only need to look at the first. 2727 // Now they are in order so we only need to look at the first.
2715 int range_count = ranges->length(); 2728 int range_count = ranges->length();
2716 if (cc->is_negated()) { 2729 if (cc->is_negated()) {
2717 if (range_count != 0 && 2730 if (range_count != 0 &&
2718 ranges->at(0).from() == 0 && 2731 ranges->at(0).from() == 0 &&
2719 ranges->at(0).to() >= String::kMaxAsciiCharCode) { 2732 ranges->at(0).to() >= String::kMaxAsciiCharCode) {
2720 return set_replacement(NULL); 2733 return set_replacement(NULL);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2768 } 2781 }
2769 if (surviving < 2) return set_replacement(survivor); 2782 if (surviving < 2) return set_replacement(survivor);
2770 2783
2771 set_replacement(this); 2784 set_replacement(this);
2772 if (surviving == choice_count) { 2785 if (surviving == choice_count) {
2773 return this; 2786 return this;
2774 } 2787 }
2775 // Only some of the nodes survived the filtering. We need to rebuild the 2788 // Only some of the nodes survived the filtering. We need to rebuild the
2776 // alternatives list. 2789 // alternatives list.
2777 ZoneList<GuardedAlternative>* new_alternatives = 2790 ZoneList<GuardedAlternative>* new_alternatives =
2778 new ZoneList<GuardedAlternative>(surviving); 2791 new(zone()) ZoneList<GuardedAlternative>(surviving, zone());
2779 for (int i = 0; i < choice_count; i++) { 2792 for (int i = 0; i < choice_count; i++) {
2780 RegExpNode* replacement = 2793 RegExpNode* replacement =
2781 alternatives_->at(i).node()->FilterASCII(depth - 1); 2794 alternatives_->at(i).node()->FilterASCII(depth - 1);
2782 if (replacement != NULL) { 2795 if (replacement != NULL) {
2783 alternatives_->at(i).set_node(replacement); 2796 alternatives_->at(i).set_node(replacement);
2784 new_alternatives->Add(alternatives_->at(i)); 2797 new_alternatives->Add(alternatives_->at(i), zone());
2785 } 2798 }
2786 } 2799 }
2787 alternatives_ = new_alternatives; 2800 alternatives_ = new_alternatives;
2788 return this; 2801 return this;
2789 } 2802 }
2790 2803
2791 2804
2792 RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth) { 2805 RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth) {
2793 if (info()->replacement_calculated) return replacement(); 2806 if (info()->replacement_calculated) return replacement();
2794 if (depth < 0) return this; 2807 if (depth < 0) return this;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 RegExpMacroAssembler* assembler = compiler->macro_assembler(); 2944 RegExpMacroAssembler* assembler = compiler->macro_assembler();
2932 Trace::TriBool next_is_word_character = Trace::UNKNOWN; 2945 Trace::TriBool next_is_word_character = Trace::UNKNOWN;
2933 bool not_at_start = (trace->at_start() == Trace::FALSE); 2946 bool not_at_start = (trace->at_start() == Trace::FALSE);
2934 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 2947 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
2935 if (lookahead == NULL) { 2948 if (lookahead == NULL) {
2936 int eats_at_least = 2949 int eats_at_least =
2937 Min(kMaxLookaheadForBoyerMoore, 2950 Min(kMaxLookaheadForBoyerMoore,
2938 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 2951 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
2939 if (eats_at_least >= 1) { 2952 if (eats_at_least >= 1) {
2940 BoyerMooreLookahead* bm = 2953 BoyerMooreLookahead* bm =
2941 new BoyerMooreLookahead(eats_at_least, compiler, zone()); 2954 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone());
2942 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 2955 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
2943 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 2956 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
2944 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; 2957 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
2945 } 2958 }
2946 } else { 2959 } else {
2947 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 2960 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
2948 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; 2961 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE;
2949 } 2962 }
2950 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); 2963 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY);
2951 if (next_is_word_character == Trace::UNKNOWN) { 2964 if (next_is_word_character == Trace::UNKNOWN) {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
3158 if (pass == CHARACTER_CLASS_MATCH) { 3171 if (pass == CHARACTER_CLASS_MATCH) {
3159 if (first_element_checked && i == 0) continue; 3172 if (first_element_checked && i == 0) continue;
3160 if (DeterminedAlready(quick_check, elm.cp_offset)) continue; 3173 if (DeterminedAlready(quick_check, elm.cp_offset)) continue;
3161 RegExpCharacterClass* cc = elm.data.u_char_class; 3174 RegExpCharacterClass* cc = elm.data.u_char_class;
3162 EmitCharClass(assembler, 3175 EmitCharClass(assembler,
3163 cc, 3176 cc,
3164 ascii, 3177 ascii,
3165 backtrack, 3178 backtrack,
3166 cp_offset, 3179 cp_offset,
3167 *checked_up_to < cp_offset, 3180 *checked_up_to < cp_offset,
3168 preloaded); 3181 preloaded,
3182 zone());
3169 UpdateBoundsCheck(cp_offset, checked_up_to); 3183 UpdateBoundsCheck(cp_offset, checked_up_to);
3170 } 3184 }
3171 } 3185 }
3172 } 3186 }
3173 } 3187 }
3174 3188
3175 3189
3176 int TextNode::Length() { 3190 int TextNode::Length() {
3177 TextElement elm = elms_->last(); 3191 TextElement elm = elms_->last();
3178 ASSERT(elm.cp_offset >= 0); 3192 ASSERT(elm.cp_offset >= 0);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3279 3293
3280 3294
3281 void TextNode::MakeCaseIndependent(bool is_ascii) { 3295 void TextNode::MakeCaseIndependent(bool is_ascii) {
3282 int element_count = elms_->length(); 3296 int element_count = elms_->length();
3283 for (int i = 0; i < element_count; i++) { 3297 for (int i = 0; i < element_count; i++) {
3284 TextElement elm = elms_->at(i); 3298 TextElement elm = elms_->at(i);
3285 if (elm.type == TextElement::CHAR_CLASS) { 3299 if (elm.type == TextElement::CHAR_CLASS) {
3286 RegExpCharacterClass* cc = elm.data.u_char_class; 3300 RegExpCharacterClass* cc = elm.data.u_char_class;
3287 // None of the standard character classes is different in the case 3301 // None of the standard character classes is different in the case
3288 // independent case and it slows us down if we don't know that. 3302 // independent case and it slows us down if we don't know that.
3289 if (cc->is_standard()) continue; 3303 if (cc->is_standard(zone())) continue;
3290 ZoneList<CharacterRange>* ranges = cc->ranges(); 3304 ZoneList<CharacterRange>* ranges = cc->ranges(zone());
3291 int range_count = ranges->length(); 3305 int range_count = ranges->length();
3292 for (int j = 0; j < range_count; j++) { 3306 for (int j = 0; j < range_count; j++) {
3293 ranges->at(j).AddCaseEquivalents(ranges, is_ascii); 3307 ranges->at(j).AddCaseEquivalents(ranges, is_ascii, zone());
3294 } 3308 }
3295 } 3309 }
3296 } 3310 }
3297 } 3311 }
3298 3312
3299 3313
3300 int TextNode::GreedyLoopTextLength() { 3314 int TextNode::GreedyLoopTextLength() {
3301 TextElement elm = elms_->at(elms_->length() - 1); 3315 TextElement elm = elms_->at(elms_->length() - 1);
3302 if (elm.type == TextElement::CHAR_CLASS) { 3316 if (elm.type == TextElement::CHAR_CLASS) {
3303 return elm.cp_offset + 1; 3317 return elm.cp_offset + 1;
3304 } else { 3318 } else {
3305 return elm.cp_offset + elm.data.u_atom->data().length(); 3319 return elm.cp_offset + elm.data.u_atom->data().length();
3306 } 3320 }
3307 } 3321 }
3308 3322
3309 3323
3310 RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( 3324 RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode(
3311 RegExpCompiler* compiler) { 3325 RegExpCompiler* compiler) {
3312 if (elms_->length() != 1) return NULL; 3326 if (elms_->length() != 1) return NULL;
3313 TextElement elm = elms_->at(0); 3327 TextElement elm = elms_->at(0);
3314 if (elm.type != TextElement::CHAR_CLASS) return NULL; 3328 if (elm.type != TextElement::CHAR_CLASS) return NULL;
3315 RegExpCharacterClass* node = elm.data.u_char_class; 3329 RegExpCharacterClass* node = elm.data.u_char_class;
3316 ZoneList<CharacterRange>* ranges = node->ranges(); 3330 ZoneList<CharacterRange>* ranges = node->ranges(zone());
3317 if (!CharacterRange::IsCanonical(ranges)) { 3331 if (!CharacterRange::IsCanonical(ranges)) {
3318 CharacterRange::Canonicalize(ranges); 3332 CharacterRange::Canonicalize(ranges);
3319 } 3333 }
3320 if (node->is_negated()) { 3334 if (node->is_negated()) {
3321 return ranges->length() == 0 ? on_success() : NULL; 3335 return ranges->length() == 0 ? on_success() : NULL;
3322 } 3336 }
3323 if (ranges->length() != 1) return NULL; 3337 if (ranges->length() != 1) return NULL;
3324 uint32_t max_char; 3338 uint32_t max_char;
3325 if (compiler->ascii()) { 3339 if (compiler->ascii()) {
3326 max_char = String::kMaxAsciiCharCode; 3340 max_char = String::kMaxAsciiCharCode;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3428 bool expects_preload; 3442 bool expects_preload;
3429 Label after; 3443 Label after;
3430 QuickCheckDetails quick_check_details; 3444 QuickCheckDetails quick_check_details;
3431 }; 3445 };
3432 3446
3433 3447
3434 // Creates a list of AlternativeGenerations. If the list has a reasonable 3448 // Creates a list of AlternativeGenerations. If the list has a reasonable
3435 // size then it is on the stack, otherwise the excess is on the heap. 3449 // size then it is on the stack, otherwise the excess is on the heap.
3436 class AlternativeGenerationList { 3450 class AlternativeGenerationList {
3437 public: 3451 public:
3438 explicit AlternativeGenerationList(int count) 3452 AlternativeGenerationList(int count, Zone* zone)
3439 : alt_gens_(count) { 3453 : alt_gens_(count, zone) {
3440 for (int i = 0; i < count && i < kAFew; i++) { 3454 for (int i = 0; i < count && i < kAFew; i++) {
3441 alt_gens_.Add(a_few_alt_gens_ + i); 3455 alt_gens_.Add(a_few_alt_gens_ + i, zone);
3442 } 3456 }
3443 for (int i = kAFew; i < count; i++) { 3457 for (int i = kAFew; i < count; i++) {
3444 alt_gens_.Add(new AlternativeGeneration()); 3458 alt_gens_.Add(new AlternativeGeneration(), zone);
3445 } 3459 }
3446 } 3460 }
3447 ~AlternativeGenerationList() { 3461 ~AlternativeGenerationList() {
3448 for (int i = kAFew; i < alt_gens_.length(); i++) { 3462 for (int i = kAFew; i < alt_gens_.length(); i++) {
3449 delete alt_gens_[i]; 3463 delete alt_gens_[i];
3450 alt_gens_[i] = NULL; 3464 alt_gens_[i] = NULL;
3451 } 3465 }
3452 } 3466 }
3453 3467
3454 AlternativeGeneration* at(int i) { 3468 AlternativeGeneration* at(int i) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3520 3534
3521 BoyerMooreLookahead::BoyerMooreLookahead( 3535 BoyerMooreLookahead::BoyerMooreLookahead(
3522 int length, RegExpCompiler* compiler, Zone* zone) 3536 int length, RegExpCompiler* compiler, Zone* zone)
3523 : length_(length), 3537 : length_(length),
3524 compiler_(compiler) { 3538 compiler_(compiler) {
3525 if (compiler->ascii()) { 3539 if (compiler->ascii()) {
3526 max_char_ = String::kMaxAsciiCharCode; 3540 max_char_ = String::kMaxAsciiCharCode;
3527 } else { 3541 } else {
3528 max_char_ = String::kMaxUtf16CodeUnit; 3542 max_char_ = String::kMaxUtf16CodeUnit;
3529 } 3543 }
3530 bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length); 3544 bitmaps_ = new(zone) ZoneList<BoyerMoorePositionInfo*>(length, zone);
3531 for (int i = 0; i < length; i++) { 3545 for (int i = 0; i < length; i++) {
3532 bitmaps_->Add(new BoyerMoorePositionInfo(zone)); 3546 bitmaps_->Add(new(zone) BoyerMoorePositionInfo(zone), zone);
3533 } 3547 }
3534 } 3548 }
3535 3549
3536 3550
3537 // Find the longest range of lookahead that has the fewest number of different 3551 // Find the longest range of lookahead that has the fewest number of different
3538 // characters that can occur at a given position. Since we are optimizing two 3552 // characters that can occur at a given position. Since we are optimizing two
3539 // different parameters at once this is a tradeoff. 3553 // different parameters at once this is a tradeoff.
3540 bool BoyerMooreLookahead::FindWorthwhileInterval(int* from, int* to) { 3554 bool BoyerMooreLookahead::FindWorthwhileInterval(int* from, int* to) {
3541 int biggest_points = 0; 3555 int biggest_points = 0;
3542 // If more than 32 characters out of 128 can occur it is unlikely that we can 3556 // If more than 32 characters out of 128 can occur it is unlikely that we can
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
3868 // not be atoms, they can be any reasonably limited character class or 3882 // not be atoms, they can be any reasonably limited character class or
3869 // small alternation. 3883 // small alternation.
3870 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. 3884 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes.
3871 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 3885 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
3872 if (lookahead == NULL) { 3886 if (lookahead == NULL) {
3873 eats_at_least = 3887 eats_at_least =
3874 Min(kMaxLookaheadForBoyerMoore, 3888 Min(kMaxLookaheadForBoyerMoore,
3875 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 3889 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
3876 if (eats_at_least >= 1) { 3890 if (eats_at_least >= 1) {
3877 BoyerMooreLookahead* bm = 3891 BoyerMooreLookahead* bm =
3878 new BoyerMooreLookahead(eats_at_least, compiler, zone()); 3892 new(zone()) BoyerMooreLookahead(eats_at_least,
3893 compiler,
3894 zone());
3879 GuardedAlternative alt0 = alternatives_->at(0); 3895 GuardedAlternative alt0 = alternatives_->at(0);
3880 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 3896 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
3881 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); 3897 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
3882 } 3898 }
3883 } else { 3899 } else {
3884 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); 3900 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler);
3885 } 3901 }
3886 } 3902 }
3887 } 3903 }
3888 } 3904 }
3889 3905
3890 if (eats_at_least == kEatsAtLeastNotYetInitialized) { 3906 if (eats_at_least == kEatsAtLeastNotYetInitialized) {
3891 // Save some time by looking at most one machine word ahead. 3907 // Save some time by looking at most one machine word ahead.
3892 eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start); 3908 eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start);
3893 } 3909 }
3894 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least); 3910 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least);
3895 3911
3896 bool preload_is_current = !skip_was_emitted && 3912 bool preload_is_current = !skip_was_emitted &&
3897 (current_trace->characters_preloaded() == preload_characters); 3913 (current_trace->characters_preloaded() == preload_characters);
3898 bool preload_has_checked_bounds = preload_is_current; 3914 bool preload_has_checked_bounds = preload_is_current;
3899 3915
3900 AlternativeGenerationList alt_gens(choice_count); 3916 AlternativeGenerationList alt_gens(choice_count, zone());
3901 3917
3902 // For now we just call all choices one after the other. The idea ultimately 3918 // For now we just call all choices one after the other. The idea ultimately
3903 // is to use the Dispatch table to try only the relevant ones. 3919 // is to use the Dispatch table to try only the relevant ones.
3904 for (int i = first_normal_choice; i < choice_count; i++) { 3920 for (int i = first_normal_choice; i < choice_count; i++) {
3905 GuardedAlternative alternative = alternatives_->at(i); 3921 GuardedAlternative alternative = alternatives_->at(i);
3906 AlternativeGeneration* alt_gen = alt_gens.at(i); 3922 AlternativeGeneration* alt_gen = alt_gens.at(i);
3907 alt_gen->quick_check_details.set_characters(preload_characters); 3923 alt_gen->quick_check_details.set_characters(preload_characters);
3908 ZoneList<Guard*>* guards = alternative.guards(); 3924 ZoneList<Guard*>* guards = alternative.guards();
3909 int guard_count = (guards == NULL) ? 0 : guards->length(); 3925 int guard_count = (guards == NULL) ? 0 : guards->length();
3910 Trace new_trace(*current_trace); 3926 Trace new_trace(*current_trace);
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
4370 } 4386 }
4371 } 4387 }
4372 for (int i = 0; i < that->alternatives()->length(); i++) { 4388 for (int i = 0; i < that->alternatives()->length(); i++) {
4373 GuardedAlternative alt = that->alternatives()->at(i); 4389 GuardedAlternative alt = that->alternatives()->at(i);
4374 alt.node()->Accept(this); 4390 alt.node()->Accept(this);
4375 } 4391 }
4376 } 4392 }
4377 4393
4378 4394
4379 void DotPrinter::VisitText(TextNode* that) { 4395 void DotPrinter::VisitText(TextNode* that) {
4396 Zone* zone = that->zone();
4380 stream()->Add(" n%p [label=\"", that); 4397 stream()->Add(" n%p [label=\"", that);
4381 for (int i = 0; i < that->elements()->length(); i++) { 4398 for (int i = 0; i < that->elements()->length(); i++) {
4382 if (i > 0) stream()->Add(" "); 4399 if (i > 0) stream()->Add(" ");
4383 TextElement elm = that->elements()->at(i); 4400 TextElement elm = that->elements()->at(i);
4384 switch (elm.type) { 4401 switch (elm.type) {
4385 case TextElement::ATOM: { 4402 case TextElement::ATOM: {
4386 stream()->Add("'%w'", elm.data.u_atom->data()); 4403 stream()->Add("'%w'", elm.data.u_atom->data());
4387 break; 4404 break;
4388 } 4405 }
4389 case TextElement::CHAR_CLASS: { 4406 case TextElement::CHAR_CLASS: {
4390 RegExpCharacterClass* node = elm.data.u_char_class; 4407 RegExpCharacterClass* node = elm.data.u_char_class;
4391 stream()->Add("["); 4408 stream()->Add("[");
4392 if (node->is_negated()) 4409 if (node->is_negated())
4393 stream()->Add("^"); 4410 stream()->Add("^");
4394 for (int j = 0; j < node->ranges()->length(); j++) { 4411 for (int j = 0; j < node->ranges(zone)->length(); j++) {
4395 CharacterRange range = node->ranges()->at(j); 4412 CharacterRange range = node->ranges(zone)->at(j);
4396 stream()->Add("%k-%k", range.from(), range.to()); 4413 stream()->Add("%k-%k", range.from(), range.to());
4397 } 4414 }
4398 stream()->Add("]"); 4415 stream()->Add("]");
4399 break; 4416 break;
4400 } 4417 }
4401 default: 4418 default:
4402 UNREACHABLE(); 4419 UNREACHABLE();
4403 } 4420 }
4404 } 4421 }
4405 stream()->Add("\", shape=box, peripheries=2];\n"); 4422 stream()->Add("\", shape=box, peripheries=2];\n");
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4543 4560
4544 4561
4545 #endif // DEBUG 4562 #endif // DEBUG
4546 4563
4547 4564
4548 // ------------------------------------------------------------------- 4565 // -------------------------------------------------------------------
4549 // Tree to graph conversion 4566 // Tree to graph conversion
4550 4567
4551 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler, 4568 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
4552 RegExpNode* on_success) { 4569 RegExpNode* on_success) {
4553 ZoneList<TextElement>* elms = new ZoneList<TextElement>(1); 4570 ZoneList<TextElement>* elms =
4554 elms->Add(TextElement::Atom(this)); 4571 new(compiler->zone()) ZoneList<TextElement>(1, compiler->zone());
4555 return new TextNode(elms, on_success); 4572 elms->Add(TextElement::Atom(this), compiler->zone());
4573 return new(compiler->zone()) TextNode(elms, on_success);
4556 } 4574 }
4557 4575
4558 4576
4559 RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler, 4577 RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler,
4560 RegExpNode* on_success) { 4578 RegExpNode* on_success) {
4561 return new TextNode(elements(), on_success); 4579 return new(compiler->zone()) TextNode(elements(), on_success);
4562 } 4580 }
4563 4581
4564 4582
4565 static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges, 4583 static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges,
4566 const int* special_class, 4584 const int* special_class,
4567 int length) { 4585 int length) {
4568 length--; // Remove final 0x10000. 4586 length--; // Remove final 0x10000.
4569 ASSERT(special_class[length] == 0x10000); 4587 ASSERT(special_class[length] == 0x10000);
4570 ASSERT(ranges->length() != 0); 4588 ASSERT(ranges->length() != 0);
4571 ASSERT(length != 0); 4589 ASSERT(length != 0);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 CharacterRange range = ranges->at(i >> 1); 4623 CharacterRange range = ranges->at(i >> 1);
4606 if (range.from() != special_class[i] || 4624 if (range.from() != special_class[i] ||
4607 range.to() != special_class[i + 1] - 1) { 4625 range.to() != special_class[i + 1] - 1) {
4608 return false; 4626 return false;
4609 } 4627 }
4610 } 4628 }
4611 return true; 4629 return true;
4612 } 4630 }
4613 4631
4614 4632
4615 bool RegExpCharacterClass::is_standard() { 4633 bool RegExpCharacterClass::is_standard(Zone* zone) {
4616 // TODO(lrn): Remove need for this function, by not throwing away information 4634 // TODO(lrn): Remove need for this function, by not throwing away information
4617 // along the way. 4635 // along the way.
4618 if (is_negated_) { 4636 if (is_negated_) {
4619 return false; 4637 return false;
4620 } 4638 }
4621 if (set_.is_standard()) { 4639 if (set_.is_standard()) {
4622 return true; 4640 return true;
4623 } 4641 }
4624 if (CompareRanges(set_.ranges(), kSpaceRanges, kSpaceRangeCount)) { 4642 if (CompareRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
4625 set_.set_standard_set_type('s'); 4643 set_.set_standard_set_type('s');
4626 return true; 4644 return true;
4627 } 4645 }
4628 if (CompareInverseRanges(set_.ranges(), kSpaceRanges, kSpaceRangeCount)) { 4646 if (CompareInverseRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
4629 set_.set_standard_set_type('S'); 4647 set_.set_standard_set_type('S');
4630 return true; 4648 return true;
4631 } 4649 }
4632 if (CompareInverseRanges(set_.ranges(), 4650 if (CompareInverseRanges(set_.ranges(zone),
4633 kLineTerminatorRanges, 4651 kLineTerminatorRanges,
4634 kLineTerminatorRangeCount)) { 4652 kLineTerminatorRangeCount)) {
4635 set_.set_standard_set_type('.'); 4653 set_.set_standard_set_type('.');
4636 return true; 4654 return true;
4637 } 4655 }
4638 if (CompareRanges(set_.ranges(), 4656 if (CompareRanges(set_.ranges(zone),
4639 kLineTerminatorRanges, 4657 kLineTerminatorRanges,
4640 kLineTerminatorRangeCount)) { 4658 kLineTerminatorRangeCount)) {
4641 set_.set_standard_set_type('n'); 4659 set_.set_standard_set_type('n');
4642 return true; 4660 return true;
4643 } 4661 }
4644 if (CompareRanges(set_.ranges(), kWordRanges, kWordRangeCount)) { 4662 if (CompareRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
4645 set_.set_standard_set_type('w'); 4663 set_.set_standard_set_type('w');
4646 return true; 4664 return true;
4647 } 4665 }
4648 if (CompareInverseRanges(set_.ranges(), kWordRanges, kWordRangeCount)) { 4666 if (CompareInverseRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
4649 set_.set_standard_set_type('W'); 4667 set_.set_standard_set_type('W');
4650 return true; 4668 return true;
4651 } 4669 }
4652 return false; 4670 return false;
4653 } 4671 }
4654 4672
4655 4673
4656 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, 4674 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
4657 RegExpNode* on_success) { 4675 RegExpNode* on_success) {
4658 return new TextNode(this, on_success); 4676 return new(compiler->zone()) TextNode(this, on_success);
4659 } 4677 }
4660 4678
4661 4679
4662 RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, 4680 RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler,
4663 RegExpNode* on_success) { 4681 RegExpNode* on_success) {
4664 ZoneList<RegExpTree*>* alternatives = this->alternatives(); 4682 ZoneList<RegExpTree*>* alternatives = this->alternatives();
4665 int length = alternatives->length(); 4683 int length = alternatives->length();
4666 ChoiceNode* result = new ChoiceNode(length, compiler->zone()); 4684 ChoiceNode* result =
4685 new(compiler->zone()) ChoiceNode(length, compiler->zone());
4667 for (int i = 0; i < length; i++) { 4686 for (int i = 0; i < length; i++) {
4668 GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler, 4687 GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler,
4669 on_success)); 4688 on_success));
4670 result->AddAlternative(alternative); 4689 result->AddAlternative(alternative);
4671 } 4690 }
4672 return result; 4691 return result;
4673 } 4692 }
4674 4693
4675 4694
4676 RegExpNode* RegExpQuantifier::ToNode(RegExpCompiler* compiler, 4695 RegExpNode* RegExpQuantifier::ToNode(RegExpCompiler* compiler,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4749 // simpler since we don't need to make the special zero length match check 4768 // simpler since we don't need to make the special zero length match check
4750 // from step 2.1. If the min and max are small we can unroll a little in 4769 // from step 2.1. If the min and max are small we can unroll a little in
4751 // this case. 4770 // this case.
4752 static const int kMaxUnrolledMinMatches = 3; // Unroll (foo)+ and (foo){3,} 4771 static const int kMaxUnrolledMinMatches = 3; // Unroll (foo)+ and (foo){3,}
4753 static const int kMaxUnrolledMaxMatches = 3; // Unroll (foo)? and (foo){x,3} 4772 static const int kMaxUnrolledMaxMatches = 3; // Unroll (foo)? and (foo){x,3}
4754 if (max == 0) return on_success; // This can happen due to recursion. 4773 if (max == 0) return on_success; // This can happen due to recursion.
4755 bool body_can_be_empty = (body->min_match() == 0); 4774 bool body_can_be_empty = (body->min_match() == 0);
4756 int body_start_reg = RegExpCompiler::kNoRegister; 4775 int body_start_reg = RegExpCompiler::kNoRegister;
4757 Interval capture_registers = body->CaptureRegisters(); 4776 Interval capture_registers = body->CaptureRegisters();
4758 bool needs_capture_clearing = !capture_registers.is_empty(); 4777 bool needs_capture_clearing = !capture_registers.is_empty();
4778 Zone* zone = compiler->zone();
4779
4759 if (body_can_be_empty) { 4780 if (body_can_be_empty) {
4760 body_start_reg = compiler->AllocateRegister(); 4781 body_start_reg = compiler->AllocateRegister();
4761 } else if (FLAG_regexp_optimization && !needs_capture_clearing) { 4782 } else if (FLAG_regexp_optimization && !needs_capture_clearing) {
4762 // Only unroll if there are no captures and the body can't be 4783 // Only unroll if there are no captures and the body can't be
4763 // empty. 4784 // empty.
4764 { 4785 {
4765 RegExpExpansionLimiter limiter( 4786 RegExpExpansionLimiter limiter(
4766 compiler, min + ((max != min) ? 1 : 0)); 4787 compiler, min + ((max != min) ? 1 : 0));
4767 if (min > 0 && min <= kMaxUnrolledMinMatches && limiter.ok_to_expand()) { 4788 if (min > 0 && min <= kMaxUnrolledMinMatches && limiter.ok_to_expand()) {
4768 int new_max = (max == kInfinity) ? max : max - min; 4789 int new_max = (max == kInfinity) ? max : max - min;
(...skipping 10 matching lines...) Expand all
4779 return answer; 4800 return answer;
4780 } 4801 }
4781 } 4802 }
4782 if (max <= kMaxUnrolledMaxMatches && min == 0) { 4803 if (max <= kMaxUnrolledMaxMatches && min == 0) {
4783 ASSERT(max > 0); // Due to the 'if' above. 4804 ASSERT(max > 0); // Due to the 'if' above.
4784 RegExpExpansionLimiter limiter(compiler, max); 4805 RegExpExpansionLimiter limiter(compiler, max);
4785 if (limiter.ok_to_expand()) { 4806 if (limiter.ok_to_expand()) {
4786 // Unroll the optional matches up to max. 4807 // Unroll the optional matches up to max.
4787 RegExpNode* answer = on_success; 4808 RegExpNode* answer = on_success;
4788 for (int i = 0; i < max; i++) { 4809 for (int i = 0; i < max; i++) {
4789 ChoiceNode* alternation = new ChoiceNode(2, compiler->zone()); 4810 ChoiceNode* alternation = new(zone) ChoiceNode(2, zone);
4790 if (is_greedy) { 4811 if (is_greedy) {
4791 alternation->AddAlternative( 4812 alternation->AddAlternative(
4792 GuardedAlternative(body->ToNode(compiler, answer))); 4813 GuardedAlternative(body->ToNode(compiler, answer)));
4793 alternation->AddAlternative(GuardedAlternative(on_success)); 4814 alternation->AddAlternative(GuardedAlternative(on_success));
4794 } else { 4815 } else {
4795 alternation->AddAlternative(GuardedAlternative(on_success)); 4816 alternation->AddAlternative(GuardedAlternative(on_success));
4796 alternation->AddAlternative( 4817 alternation->AddAlternative(
4797 GuardedAlternative(body->ToNode(compiler, answer))); 4818 GuardedAlternative(body->ToNode(compiler, answer)));
4798 } 4819 }
4799 answer = alternation; 4820 answer = alternation;
4800 if (not_at_start) alternation->set_not_at_start(); 4821 if (not_at_start) alternation->set_not_at_start();
4801 } 4822 }
4802 return answer; 4823 return answer;
4803 } 4824 }
4804 } 4825 }
4805 } 4826 }
4806 bool has_min = min > 0; 4827 bool has_min = min > 0;
4807 bool has_max = max < RegExpTree::kInfinity; 4828 bool has_max = max < RegExpTree::kInfinity;
4808 bool needs_counter = has_min || has_max; 4829 bool needs_counter = has_min || has_max;
4809 int reg_ctr = needs_counter 4830 int reg_ctr = needs_counter
4810 ? compiler->AllocateRegister() 4831 ? compiler->AllocateRegister()
4811 : RegExpCompiler::kNoRegister; 4832 : RegExpCompiler::kNoRegister;
4812 LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0, 4833 LoopChoiceNode* center = new(zone) LoopChoiceNode(body->min_match() == 0,
4813 compiler->zone()); 4834 zone);
4814 if (not_at_start) center->set_not_at_start(); 4835 if (not_at_start) center->set_not_at_start();
4815 RegExpNode* loop_return = needs_counter 4836 RegExpNode* loop_return = needs_counter
4816 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center)) 4837 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
4817 : static_cast<RegExpNode*>(center); 4838 : static_cast<RegExpNode*>(center);
4818 if (body_can_be_empty) { 4839 if (body_can_be_empty) {
4819 // If the body can be empty we need to check if it was and then 4840 // If the body can be empty we need to check if it was and then
4820 // backtrack. 4841 // backtrack.
4821 loop_return = ActionNode::EmptyMatchCheck(body_start_reg, 4842 loop_return = ActionNode::EmptyMatchCheck(body_start_reg,
4822 reg_ctr, 4843 reg_ctr,
4823 min, 4844 min,
4824 loop_return); 4845 loop_return);
4825 } 4846 }
4826 RegExpNode* body_node = body->ToNode(compiler, loop_return); 4847 RegExpNode* body_node = body->ToNode(compiler, loop_return);
4827 if (body_can_be_empty) { 4848 if (body_can_be_empty) {
4828 // If the body can be empty we need to store the start position 4849 // If the body can be empty we need to store the start position
4829 // so we can bail out if it was empty. 4850 // so we can bail out if it was empty.
4830 body_node = ActionNode::StorePosition(body_start_reg, false, body_node); 4851 body_node = ActionNode::StorePosition(body_start_reg, false, body_node);
4831 } 4852 }
4832 if (needs_capture_clearing) { 4853 if (needs_capture_clearing) {
4833 // Before entering the body of this loop we need to clear captures. 4854 // Before entering the body of this loop we need to clear captures.
4834 body_node = ActionNode::ClearCaptures(capture_registers, body_node); 4855 body_node = ActionNode::ClearCaptures(capture_registers, body_node);
4835 } 4856 }
4836 GuardedAlternative body_alt(body_node); 4857 GuardedAlternative body_alt(body_node);
4837 if (has_max) { 4858 if (has_max) {
4838 Guard* body_guard = new Guard(reg_ctr, Guard::LT, max); 4859 Guard* body_guard =
4839 body_alt.AddGuard(body_guard); 4860 new(zone) Guard(reg_ctr, Guard::LT, max);
4861 body_alt.AddGuard(body_guard, zone);
4840 } 4862 }
4841 GuardedAlternative rest_alt(on_success); 4863 GuardedAlternative rest_alt(on_success);
4842 if (has_min) { 4864 if (has_min) {
4843 Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min); 4865 Guard* rest_guard = new(compiler->zone()) Guard(reg_ctr, Guard::GEQ, min);
4844 rest_alt.AddGuard(rest_guard); 4866 rest_alt.AddGuard(rest_guard, zone);
4845 } 4867 }
4846 if (is_greedy) { 4868 if (is_greedy) {
4847 center->AddLoopAlternative(body_alt); 4869 center->AddLoopAlternative(body_alt);
4848 center->AddContinueAlternative(rest_alt); 4870 center->AddContinueAlternative(rest_alt);
4849 } else { 4871 } else {
4850 center->AddContinueAlternative(rest_alt); 4872 center->AddContinueAlternative(rest_alt);
4851 center->AddLoopAlternative(body_alt); 4873 center->AddLoopAlternative(body_alt);
4852 } 4874 }
4853 if (needs_counter) { 4875 if (needs_counter) {
4854 return ActionNode::SetRegister(reg_ctr, 0, center); 4876 return ActionNode::SetRegister(reg_ctr, 0, center);
4855 } else { 4877 } else {
4856 return center; 4878 return center;
4857 } 4879 }
4858 } 4880 }
4859 4881
4860 4882
4861 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, 4883 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
4862 RegExpNode* on_success) { 4884 RegExpNode* on_success) {
4863 NodeInfo info; 4885 NodeInfo info;
4886 Zone* zone = compiler->zone();
4887
4864 switch (type()) { 4888 switch (type()) {
4865 case START_OF_LINE: 4889 case START_OF_LINE:
4866 return AssertionNode::AfterNewline(on_success); 4890 return AssertionNode::AfterNewline(on_success);
4867 case START_OF_INPUT: 4891 case START_OF_INPUT:
4868 return AssertionNode::AtStart(on_success); 4892 return AssertionNode::AtStart(on_success);
4869 case BOUNDARY: 4893 case BOUNDARY:
4870 return AssertionNode::AtBoundary(on_success); 4894 return AssertionNode::AtBoundary(on_success);
4871 case NON_BOUNDARY: 4895 case NON_BOUNDARY:
4872 return AssertionNode::AtNonBoundary(on_success); 4896 return AssertionNode::AtNonBoundary(on_success);
4873 case END_OF_INPUT: 4897 case END_OF_INPUT:
4874 return AssertionNode::AtEnd(on_success); 4898 return AssertionNode::AtEnd(on_success);
4875 case END_OF_LINE: { 4899 case END_OF_LINE: {
4876 // Compile $ in multiline regexps as an alternation with a positive 4900 // Compile $ in multiline regexps as an alternation with a positive
4877 // lookahead in one side and an end-of-input on the other side. 4901 // lookahead in one side and an end-of-input on the other side.
4878 // We need two registers for the lookahead. 4902 // We need two registers for the lookahead.
4879 int stack_pointer_register = compiler->AllocateRegister(); 4903 int stack_pointer_register = compiler->AllocateRegister();
4880 int position_register = compiler->AllocateRegister(); 4904 int position_register = compiler->AllocateRegister();
4881 // The ChoiceNode to distinguish between a newline and end-of-input. 4905 // The ChoiceNode to distinguish between a newline and end-of-input.
4882 ChoiceNode* result = new ChoiceNode(2, compiler->zone()); 4906 ChoiceNode* result = new(zone) ChoiceNode(2, zone);
4883 // Create a newline atom. 4907 // Create a newline atom.
4884 ZoneList<CharacterRange>* newline_ranges = 4908 ZoneList<CharacterRange>* newline_ranges =
4885 new ZoneList<CharacterRange>(3); 4909 new(zone) ZoneList<CharacterRange>(3, zone);
4886 CharacterRange::AddClassEscape('n', newline_ranges); 4910 CharacterRange::AddClassEscape('n', newline_ranges, zone);
4887 RegExpCharacterClass* newline_atom = new RegExpCharacterClass('n'); 4911 RegExpCharacterClass* newline_atom = new(zone) RegExpCharacterClass('n');
4888 TextNode* newline_matcher = new TextNode( 4912 TextNode* newline_matcher = new(zone) TextNode(
4889 newline_atom, 4913 newline_atom,
4890 ActionNode::PositiveSubmatchSuccess(stack_pointer_register, 4914 ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
4891 position_register, 4915 position_register,
4892 0, // No captures inside. 4916 0, // No captures inside.
4893 -1, // Ignored if no captures. 4917 -1, // Ignored if no captures.
4894 on_success)); 4918 on_success));
4895 // Create an end-of-input matcher. 4919 // Create an end-of-input matcher.
4896 RegExpNode* end_of_line = ActionNode::BeginSubmatch( 4920 RegExpNode* end_of_line = ActionNode::BeginSubmatch(
4897 stack_pointer_register, 4921 stack_pointer_register,
4898 position_register, 4922 position_register,
4899 newline_matcher); 4923 newline_matcher);
4900 // Add the two alternatives to the ChoiceNode. 4924 // Add the two alternatives to the ChoiceNode.
4901 GuardedAlternative eol_alternative(end_of_line); 4925 GuardedAlternative eol_alternative(end_of_line);
4902 result->AddAlternative(eol_alternative); 4926 result->AddAlternative(eol_alternative);
4903 GuardedAlternative end_alternative(AssertionNode::AtEnd(on_success)); 4927 GuardedAlternative end_alternative(AssertionNode::AtEnd(on_success));
4904 result->AddAlternative(end_alternative); 4928 result->AddAlternative(end_alternative);
4905 return result; 4929 return result;
4906 } 4930 }
4907 default: 4931 default:
4908 UNREACHABLE(); 4932 UNREACHABLE();
4909 } 4933 }
4910 return on_success; 4934 return on_success;
4911 } 4935 }
4912 4936
4913 4937
4914 RegExpNode* RegExpBackReference::ToNode(RegExpCompiler* compiler, 4938 RegExpNode* RegExpBackReference::ToNode(RegExpCompiler* compiler,
4915 RegExpNode* on_success) { 4939 RegExpNode* on_success) {
4916 return new BackReferenceNode(RegExpCapture::StartRegister(index()), 4940 return new(compiler->zone())
4917 RegExpCapture::EndRegister(index()), 4941 BackReferenceNode(RegExpCapture::StartRegister(index()),
4918 on_success); 4942 RegExpCapture::EndRegister(index()),
4943 on_success);
4919 } 4944 }
4920 4945
4921 4946
4922 RegExpNode* RegExpEmpty::ToNode(RegExpCompiler* compiler, 4947 RegExpNode* RegExpEmpty::ToNode(RegExpCompiler* compiler,
4923 RegExpNode* on_success) { 4948 RegExpNode* on_success) {
4924 return on_success; 4949 return on_success;
4925 } 4950 }
4926 4951
4927 4952
4928 RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler, 4953 RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler,
(...skipping 24 matching lines...) Expand all
4953 // We use a ChoiceNode for a negative lookahead because it has most of 4978 // We use a ChoiceNode for a negative lookahead because it has most of
4954 // the characteristics we need. It has the body of the lookahead as its 4979 // the characteristics we need. It has the body of the lookahead as its
4955 // first alternative and the expression after the lookahead of the second 4980 // first alternative and the expression after the lookahead of the second
4956 // alternative. If the first alternative succeeds then the 4981 // alternative. If the first alternative succeeds then the
4957 // NegativeSubmatchSuccess will unwind the stack including everything the 4982 // NegativeSubmatchSuccess will unwind the stack including everything the
4958 // choice node set up and backtrack. If the first alternative fails then 4983 // choice node set up and backtrack. If the first alternative fails then
4959 // the second alternative is tried, which is exactly the desired result 4984 // the second alternative is tried, which is exactly the desired result
4960 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special 4985 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
4961 // ChoiceNode that knows to ignore the first exit when calculating quick 4986 // ChoiceNode that knows to ignore the first exit when calculating quick
4962 // checks. 4987 // checks.
4988 Zone* zone = compiler->zone();
4989
4963 GuardedAlternative body_alt( 4990 GuardedAlternative body_alt(
4964 body()->ToNode( 4991 body()->ToNode(
4965 compiler, 4992 compiler,
4966 success = new NegativeSubmatchSuccess(stack_pointer_register, 4993 success = new(zone) NegativeSubmatchSuccess(stack_pointer_register,
4967 position_register, 4994 position_register,
4968 register_count, 4995 register_count,
4969 register_start, 4996 register_start,
4970 compiler->zone()))); 4997 zone)));
4971 ChoiceNode* choice_node = 4998 ChoiceNode* choice_node =
4972 new NegativeLookaheadChoiceNode(body_alt, 4999 new(zone) NegativeLookaheadChoiceNode(body_alt,
4973 GuardedAlternative(on_success), 5000 GuardedAlternative(on_success),
4974 compiler->zone()); 5001 zone);
4975 return ActionNode::BeginSubmatch(stack_pointer_register, 5002 return ActionNode::BeginSubmatch(stack_pointer_register,
4976 position_register, 5003 position_register,
4977 choice_node); 5004 choice_node);
4978 } 5005 }
4979 } 5006 }
4980 5007
4981 5008
4982 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler, 5009 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler,
4983 RegExpNode* on_success) { 5010 RegExpNode* on_success) {
4984 return ToNode(body(), index(), compiler, on_success); 5011 return ToNode(body(), index(), compiler, on_success);
(...skipping 18 matching lines...) Expand all
5003 RegExpNode* current = on_success; 5030 RegExpNode* current = on_success;
5004 for (int i = children->length() - 1; i >= 0; i--) { 5031 for (int i = children->length() - 1; i >= 0; i--) {
5005 current = children->at(i)->ToNode(compiler, current); 5032 current = children->at(i)->ToNode(compiler, current);
5006 } 5033 }
5007 return current; 5034 return current;
5008 } 5035 }
5009 5036
5010 5037
5011 static void AddClass(const int* elmv, 5038 static void AddClass(const int* elmv,
5012 int elmc, 5039 int elmc,
5013 ZoneList<CharacterRange>* ranges) { 5040 ZoneList<CharacterRange>* ranges,
5041 Zone* zone) {
5014 elmc--; 5042 elmc--;
5015 ASSERT(elmv[elmc] == 0x10000); 5043 ASSERT(elmv[elmc] == 0x10000);
5016 for (int i = 0; i < elmc; i += 2) { 5044 for (int i = 0; i < elmc; i += 2) {
5017 ASSERT(elmv[i] < elmv[i + 1]); 5045 ASSERT(elmv[i] < elmv[i + 1]);
5018 ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1)); 5046 ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1), zone);
5019 } 5047 }
5020 } 5048 }
5021 5049
5022 5050
5023 static void AddClassNegated(const int *elmv, 5051 static void AddClassNegated(const int *elmv,
5024 int elmc, 5052 int elmc,
5025 ZoneList<CharacterRange>* ranges) { 5053 ZoneList<CharacterRange>* ranges,
5054 Zone* zone) {
5026 elmc--; 5055 elmc--;
5027 ASSERT(elmv[elmc] == 0x10000); 5056 ASSERT(elmv[elmc] == 0x10000);
5028 ASSERT(elmv[0] != 0x0000); 5057 ASSERT(elmv[0] != 0x0000);
5029 ASSERT(elmv[elmc-1] != String::kMaxUtf16CodeUnit); 5058 ASSERT(elmv[elmc-1] != String::kMaxUtf16CodeUnit);
5030 uc16 last = 0x0000; 5059 uc16 last = 0x0000;
5031 for (int i = 0; i < elmc; i += 2) { 5060 for (int i = 0; i < elmc; i += 2) {
5032 ASSERT(last <= elmv[i] - 1); 5061 ASSERT(last <= elmv[i] - 1);
5033 ASSERT(elmv[i] < elmv[i + 1]); 5062 ASSERT(elmv[i] < elmv[i + 1]);
5034 ranges->Add(CharacterRange(last, elmv[i] - 1)); 5063 ranges->Add(CharacterRange(last, elmv[i] - 1), zone);
5035 last = elmv[i + 1]; 5064 last = elmv[i + 1];
5036 } 5065 }
5037 ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit)); 5066 ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit), zone);
5038 } 5067 }
5039 5068
5040 5069
5041 void CharacterRange::AddClassEscape(uc16 type, 5070 void CharacterRange::AddClassEscape(uc16 type,
5042 ZoneList<CharacterRange>* ranges) { 5071 ZoneList<CharacterRange>* ranges,
5072 Zone* zone) {
5043 switch (type) { 5073 switch (type) {
5044 case 's': 5074 case 's':
5045 AddClass(kSpaceRanges, kSpaceRangeCount, ranges); 5075 AddClass(kSpaceRanges, kSpaceRangeCount, ranges, zone);
5046 break; 5076 break;
5047 case 'S': 5077 case 'S':
5048 AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges); 5078 AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges, zone);
5049 break; 5079 break;
5050 case 'w': 5080 case 'w':
5051 AddClass(kWordRanges, kWordRangeCount, ranges); 5081 AddClass(kWordRanges, kWordRangeCount, ranges, zone);
5052 break; 5082 break;
5053 case 'W': 5083 case 'W':
5054 AddClassNegated(kWordRanges, kWordRangeCount, ranges); 5084 AddClassNegated(kWordRanges, kWordRangeCount, ranges, zone);
5055 break; 5085 break;
5056 case 'd': 5086 case 'd':
5057 AddClass(kDigitRanges, kDigitRangeCount, ranges); 5087 AddClass(kDigitRanges, kDigitRangeCount, ranges, zone);
5058 break; 5088 break;
5059 case 'D': 5089 case 'D':
5060 AddClassNegated(kDigitRanges, kDigitRangeCount, ranges); 5090 AddClassNegated(kDigitRanges, kDigitRangeCount, ranges, zone);
5061 break; 5091 break;
5062 case '.': 5092 case '.':
5063 AddClassNegated(kLineTerminatorRanges, 5093 AddClassNegated(kLineTerminatorRanges,
5064 kLineTerminatorRangeCount, 5094 kLineTerminatorRangeCount,
5065 ranges); 5095 ranges,
5096 zone);
5066 break; 5097 break;
5067 // This is not a character range as defined by the spec but a 5098 // This is not a character range as defined by the spec but a
5068 // convenient shorthand for a character class that matches any 5099 // convenient shorthand for a character class that matches any
5069 // character. 5100 // character.
5070 case '*': 5101 case '*':
5071 ranges->Add(CharacterRange::Everything()); 5102 ranges->Add(CharacterRange::Everything(), zone);
5072 break; 5103 break;
5073 // This is the set of characters matched by the $ and ^ symbols 5104 // This is the set of characters matched by the $ and ^ symbols
5074 // in multiline mode. 5105 // in multiline mode.
5075 case 'n': 5106 case 'n':
5076 AddClass(kLineTerminatorRanges, 5107 AddClass(kLineTerminatorRanges,
5077 kLineTerminatorRangeCount, 5108 kLineTerminatorRangeCount,
5078 ranges); 5109 ranges,
5110 zone);
5079 break; 5111 break;
5080 default: 5112 default:
5081 UNREACHABLE(); 5113 UNREACHABLE();
5082 } 5114 }
5083 } 5115 }
5084 5116
5085 5117
5086 Vector<const int> CharacterRange::GetWordBounds() { 5118 Vector<const int> CharacterRange::GetWordBounds() {
5087 return Vector<const int>(kWordRanges, kWordRangeCount - 1); 5119 return Vector<const int>(kWordRanges, kWordRangeCount - 1);
5088 } 5120 }
5089 5121
5090 5122
5091 class CharacterRangeSplitter { 5123 class CharacterRangeSplitter {
5092 public: 5124 public:
5093 CharacterRangeSplitter(ZoneList<CharacterRange>** included, 5125 CharacterRangeSplitter(ZoneList<CharacterRange>** included,
5094 ZoneList<CharacterRange>** excluded) 5126 ZoneList<CharacterRange>** excluded,
5127 Zone* zone)
5095 : included_(included), 5128 : included_(included),
5096 excluded_(excluded) { } 5129 excluded_(excluded),
5130 zone_(zone) { }
5097 void Call(uc16 from, DispatchTable::Entry entry); 5131 void Call(uc16 from, DispatchTable::Entry entry);
5098 5132
5099 static const int kInBase = 0; 5133 static const int kInBase = 0;
5100 static const int kInOverlay = 1; 5134 static const int kInOverlay = 1;
5101 5135
5102 private: 5136 private:
5103 ZoneList<CharacterRange>** included_; 5137 ZoneList<CharacterRange>** included_;
5104 ZoneList<CharacterRange>** excluded_; 5138 ZoneList<CharacterRange>** excluded_;
5139 Zone* zone_;
5105 }; 5140 };
5106 5141
5107 5142
5108 void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) { 5143 void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) {
5109 if (!entry.out_set()->Get(kInBase)) return; 5144 if (!entry.out_set()->Get(kInBase)) return;
5110 ZoneList<CharacterRange>** target = entry.out_set()->Get(kInOverlay) 5145 ZoneList<CharacterRange>** target = entry.out_set()->Get(kInOverlay)
5111 ? included_ 5146 ? included_
5112 : excluded_; 5147 : excluded_;
5113 if (*target == NULL) *target = new ZoneList<CharacterRange>(2); 5148 if (*target == NULL) *target = new(zone_) ZoneList<CharacterRange>(2, zone_);
5114 (*target)->Add(CharacterRange(entry.from(), entry.to())); 5149 (*target)->Add(CharacterRange(entry.from(), entry.to()), zone_);
5115 } 5150 }
5116 5151
5117 5152
5118 void CharacterRange::Split(ZoneList<CharacterRange>* base, 5153 void CharacterRange::Split(ZoneList<CharacterRange>* base,
5119 Vector<const int> overlay, 5154 Vector<const int> overlay,
5120 ZoneList<CharacterRange>** included, 5155 ZoneList<CharacterRange>** included,
5121 ZoneList<CharacterRange>** excluded) { 5156 ZoneList<CharacterRange>** excluded,
5157 Zone* zone) {
5122 ASSERT_EQ(NULL, *included); 5158 ASSERT_EQ(NULL, *included);
5123 ASSERT_EQ(NULL, *excluded); 5159 ASSERT_EQ(NULL, *excluded);
5124 DispatchTable table; 5160 DispatchTable table(zone);
5125 for (int i = 0; i < base->length(); i++) 5161 for (int i = 0; i < base->length(); i++)
5126 table.AddRange(base->at(i), CharacterRangeSplitter::kInBase); 5162 table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone);
5127 for (int i = 0; i < overlay.length(); i += 2) { 5163 for (int i = 0; i < overlay.length(); i += 2) {
5128 table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1), 5164 table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1),
5129 CharacterRangeSplitter::kInOverlay); 5165 CharacterRangeSplitter::kInOverlay, zone);
5130 } 5166 }
5131 CharacterRangeSplitter callback(included, excluded); 5167 CharacterRangeSplitter callback(included, excluded, zone);
5132 table.ForEach(&callback); 5168 table.ForEach(&callback);
5133 } 5169 }
5134 5170
5135 5171
5136 void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges, 5172 void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
5137 bool is_ascii) { 5173 bool is_ascii,
5174 Zone* zone) {
5138 Isolate* isolate = Isolate::Current(); 5175 Isolate* isolate = Isolate::Current();
5139 uc16 bottom = from(); 5176 uc16 bottom = from();
5140 uc16 top = to(); 5177 uc16 top = to();
5141 if (is_ascii) { 5178 if (is_ascii) {
5142 if (bottom > String::kMaxAsciiCharCode) return; 5179 if (bottom > String::kMaxAsciiCharCode) return;
5143 if (top > String::kMaxAsciiCharCode) top = String::kMaxAsciiCharCode; 5180 if (top > String::kMaxAsciiCharCode) top = String::kMaxAsciiCharCode;
5144 } 5181 }
5145 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 5182 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
5146 if (top == bottom) { 5183 if (top == bottom) {
5147 // If this is a singleton we just expand the one character. 5184 // If this is a singleton we just expand the one character.
5148 int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars); 5185 int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars);
5149 for (int i = 0; i < length; i++) { 5186 for (int i = 0; i < length; i++) {
5150 uc32 chr = chars[i]; 5187 uc32 chr = chars[i];
5151 if (chr != bottom) { 5188 if (chr != bottom) {
5152 ranges->Add(CharacterRange::Singleton(chars[i])); 5189 ranges->Add(CharacterRange::Singleton(chars[i]), zone);
5153 } 5190 }
5154 } 5191 }
5155 } else { 5192 } else {
5156 // If this is a range we expand the characters block by block, 5193 // If this is a range we expand the characters block by block,
5157 // expanding contiguous subranges (blocks) one at a time. 5194 // expanding contiguous subranges (blocks) one at a time.
5158 // The approach is as follows. For a given start character we 5195 // The approach is as follows. For a given start character we
5159 // look up the remainder of the block that contains it (represented 5196 // look up the remainder of the block that contains it (represented
5160 // by the end point), for instance we find 'z' if the character 5197 // by the end point), for instance we find 'z' if the character
5161 // is 'c'. A block is characterized by the property 5198 // is 'c'. A block is characterized by the property
5162 // that all characters uncanonicalize in the same way, except that 5199 // that all characters uncanonicalize in the same way, except that
(...skipping 19 matching lines...) Expand all
5182 ASSERT_EQ(1, length); 5219 ASSERT_EQ(1, length);
5183 block_end = range[0]; 5220 block_end = range[0];
5184 } 5221 }
5185 int end = (block_end > top) ? top : block_end; 5222 int end = (block_end > top) ? top : block_end;
5186 length = isolate->jsregexp_uncanonicalize()->get(block_end, '\0', range); 5223 length = isolate->jsregexp_uncanonicalize()->get(block_end, '\0', range);
5187 for (int i = 0; i < length; i++) { 5224 for (int i = 0; i < length; i++) {
5188 uc32 c = range[i]; 5225 uc32 c = range[i];
5189 uc16 range_from = c - (block_end - pos); 5226 uc16 range_from = c - (block_end - pos);
5190 uc16 range_to = c - (block_end - end); 5227 uc16 range_to = c - (block_end - end);
5191 if (!(bottom <= range_from && range_to <= top)) { 5228 if (!(bottom <= range_from && range_to <= top)) {
5192 ranges->Add(CharacterRange(range_from, range_to)); 5229 ranges->Add(CharacterRange(range_from, range_to), zone);
5193 } 5230 }
5194 } 5231 }
5195 pos = end + 1; 5232 pos = end + 1;
5196 } 5233 }
5197 } 5234 }
5198 } 5235 }
5199 5236
5200 5237
5201 bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { 5238 bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) {
5202 ASSERT_NOT_NULL(ranges); 5239 ASSERT_NOT_NULL(ranges);
5203 int n = ranges->length(); 5240 int n = ranges->length();
5204 if (n <= 1) return true; 5241 if (n <= 1) return true;
5205 int max = ranges->at(0).to(); 5242 int max = ranges->at(0).to();
5206 for (int i = 1; i < n; i++) { 5243 for (int i = 1; i < n; i++) {
5207 CharacterRange next_range = ranges->at(i); 5244 CharacterRange next_range = ranges->at(i);
5208 if (next_range.from() <= max + 1) return false; 5245 if (next_range.from() <= max + 1) return false;
5209 max = next_range.to(); 5246 max = next_range.to();
5210 } 5247 }
5211 return true; 5248 return true;
5212 } 5249 }
5213 5250
5214 5251
5215 ZoneList<CharacterRange>* CharacterSet::ranges() { 5252 ZoneList<CharacterRange>* CharacterSet::ranges(Zone* zone) {
5216 if (ranges_ == NULL) { 5253 if (ranges_ == NULL) {
5217 ranges_ = new ZoneList<CharacterRange>(2); 5254 ranges_ = new(zone) ZoneList<CharacterRange>(2, zone);
5218 CharacterRange::AddClassEscape(standard_set_type_, ranges_); 5255 CharacterRange::AddClassEscape(standard_set_type_, ranges_, zone);
5219 } 5256 }
5220 return ranges_; 5257 return ranges_;
5221 } 5258 }
5222 5259
5223 5260
5224 // Move a number of elements in a zonelist to another position 5261 // Move a number of elements in a zonelist to another position
5225 // in the same list. Handles overlapping source and target areas. 5262 // in the same list. Handles overlapping source and target areas.
5226 static void MoveRanges(ZoneList<CharacterRange>* list, 5263 static void MoveRanges(ZoneList<CharacterRange>* list,
5227 int from, 5264 int from,
5228 int to, 5265 int to,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
5337 character_ranges->at(read)); 5374 character_ranges->at(read));
5338 read++; 5375 read++;
5339 } while (read < n); 5376 } while (read < n);
5340 character_ranges->Rewind(num_canonical); 5377 character_ranges->Rewind(num_canonical);
5341 5378
5342 ASSERT(CharacterRange::IsCanonical(character_ranges)); 5379 ASSERT(CharacterRange::IsCanonical(character_ranges));
5343 } 5380 }
5344 5381
5345 5382
5346 void CharacterRange::Negate(ZoneList<CharacterRange>* ranges, 5383 void CharacterRange::Negate(ZoneList<CharacterRange>* ranges,
5347 ZoneList<CharacterRange>* negated_ranges) { 5384 ZoneList<CharacterRange>* negated_ranges,
5385 Zone* zone) {
5348 ASSERT(CharacterRange::IsCanonical(ranges)); 5386 ASSERT(CharacterRange::IsCanonical(ranges));
5349 ASSERT_EQ(0, negated_ranges->length()); 5387 ASSERT_EQ(0, negated_ranges->length());
5350 int range_count = ranges->length(); 5388 int range_count = ranges->length();
5351 uc16 from = 0; 5389 uc16 from = 0;
5352 int i = 0; 5390 int i = 0;
5353 if (range_count > 0 && ranges->at(0).from() == 0) { 5391 if (range_count > 0 && ranges->at(0).from() == 0) {
5354 from = ranges->at(0).to(); 5392 from = ranges->at(0).to();
5355 i = 1; 5393 i = 1;
5356 } 5394 }
5357 while (i < range_count) { 5395 while (i < range_count) {
5358 CharacterRange range = ranges->at(i); 5396 CharacterRange range = ranges->at(i);
5359 negated_ranges->Add(CharacterRange(from + 1, range.from() - 1)); 5397 negated_ranges->Add(CharacterRange(from + 1, range.from() - 1), zone);
5360 from = range.to(); 5398 from = range.to();
5361 i++; 5399 i++;
5362 } 5400 }
5363 if (from < String::kMaxUtf16CodeUnit) { 5401 if (from < String::kMaxUtf16CodeUnit) {
5364 negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit)); 5402 negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit),
5403 zone);
5365 } 5404 }
5366 } 5405 }
5367 5406
5368 5407
5369 // ------------------------------------------------------------------- 5408 // -------------------------------------------------------------------
5370 // Splay tree 5409 // Splay tree
5371 5410
5372 5411
5373 OutSet* OutSet::Extend(unsigned value) { 5412 OutSet* OutSet::Extend(unsigned value, Zone* zone) {
5374 if (Get(value)) 5413 if (Get(value))
5375 return this; 5414 return this;
5376 if (successors() != NULL) { 5415 if (successors(zone) != NULL) {
5377 for (int i = 0; i < successors()->length(); i++) { 5416 for (int i = 0; i < successors(zone)->length(); i++) {
5378 OutSet* successor = successors()->at(i); 5417 OutSet* successor = successors(zone)->at(i);
5379 if (successor->Get(value)) 5418 if (successor->Get(value))
5380 return successor; 5419 return successor;
5381 } 5420 }
5382 } else { 5421 } else {
5383 successors_ = new ZoneList<OutSet*>(2); 5422 successors_ = new(zone) ZoneList<OutSet*>(2, zone);
5384 } 5423 }
5385 OutSet* result = new OutSet(first_, remaining_); 5424 OutSet* result = new(zone) OutSet(first_, remaining_);
5386 result->Set(value); 5425 result->Set(value, zone);
5387 successors()->Add(result); 5426 successors(zone)->Add(result, zone);
5388 return result; 5427 return result;
5389 } 5428 }
5390 5429
5391 5430
5392 void OutSet::Set(unsigned value) { 5431 void OutSet::Set(unsigned value, Zone *zone) {
5393 if (value < kFirstLimit) { 5432 if (value < kFirstLimit) {
5394 first_ |= (1 << value); 5433 first_ |= (1 << value);
5395 } else { 5434 } else {
5396 if (remaining_ == NULL) 5435 if (remaining_ == NULL)
5397 remaining_ = new ZoneList<unsigned>(1); 5436 remaining_ = new(zone) ZoneList<unsigned>(1, zone);
5398 if (remaining_->is_empty() || !remaining_->Contains(value)) 5437 if (remaining_->is_empty() || !remaining_->Contains(value))
5399 remaining_->Add(value); 5438 remaining_->Add(value, zone);
5400 } 5439 }
5401 } 5440 }
5402 5441
5403 5442
5404 bool OutSet::Get(unsigned value) { 5443 bool OutSet::Get(unsigned value) {
5405 if (value < kFirstLimit) { 5444 if (value < kFirstLimit) {
5406 return (first_ & (1 << value)) != 0; 5445 return (first_ & (1 << value)) != 0;
5407 } else if (remaining_ == NULL) { 5446 } else if (remaining_ == NULL) {
5408 return false; 5447 return false;
5409 } else { 5448 } else {
5410 return remaining_->Contains(value); 5449 return remaining_->Contains(value);
5411 } 5450 }
5412 } 5451 }
5413 5452
5414 5453
5415 const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar; 5454 const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar;
5416 5455
5417 5456
5418 void DispatchTable::AddRange(CharacterRange full_range, int value) { 5457 void DispatchTable::AddRange(CharacterRange full_range, int value,
5458 Zone* zone) {
5419 CharacterRange current = full_range; 5459 CharacterRange current = full_range;
5420 if (tree()->is_empty()) { 5460 if (tree()->is_empty()) {
5421 // If this is the first range we just insert into the table. 5461 // If this is the first range we just insert into the table.
5422 ZoneSplayTree<Config>::Locator loc; 5462 ZoneSplayTree<Config>::Locator loc;
5423 ASSERT_RESULT(tree()->Insert(current.from(), &loc)); 5463 ASSERT_RESULT(tree()->Insert(current.from(), &loc));
5424 loc.set_value(Entry(current.from(), current.to(), empty()->Extend(value))); 5464 loc.set_value(Entry(current.from(), current.to(),
5465 empty()->Extend(value, zone)));
5425 return; 5466 return;
5426 } 5467 }
5427 // First see if there is a range to the left of this one that 5468 // First see if there is a range to the left of this one that
5428 // overlaps. 5469 // overlaps.
5429 ZoneSplayTree<Config>::Locator loc; 5470 ZoneSplayTree<Config>::Locator loc;
5430 if (tree()->FindGreatestLessThan(current.from(), &loc)) { 5471 if (tree()->FindGreatestLessThan(current.from(), &loc)) {
5431 Entry* entry = &loc.value(); 5472 Entry* entry = &loc.value();
5432 // If we've found a range that overlaps with this one, and it 5473 // If we've found a range that overlaps with this one, and it
5433 // starts strictly to the left of this one, we have to fix it 5474 // starts strictly to the left of this one, we have to fix it
5434 // because the following code only handles ranges that start on 5475 // because the following code only handles ranges that start on
(...skipping 22 matching lines...) Expand all
5457 (loc.value().to() >= current.from())) { 5498 (loc.value().to() >= current.from())) {
5458 Entry* entry = &loc.value(); 5499 Entry* entry = &loc.value();
5459 // We have overlap. If there is space between the start point of 5500 // We have overlap. If there is space between the start point of
5460 // the range we're adding and where the overlapping range starts 5501 // the range we're adding and where the overlapping range starts
5461 // then we have to add a range covering just that space. 5502 // then we have to add a range covering just that space.
5462 if (current.from() < entry->from()) { 5503 if (current.from() < entry->from()) {
5463 ZoneSplayTree<Config>::Locator ins; 5504 ZoneSplayTree<Config>::Locator ins;
5464 ASSERT_RESULT(tree()->Insert(current.from(), &ins)); 5505 ASSERT_RESULT(tree()->Insert(current.from(), &ins));
5465 ins.set_value(Entry(current.from(), 5506 ins.set_value(Entry(current.from(),
5466 entry->from() - 1, 5507 entry->from() - 1,
5467 empty()->Extend(value))); 5508 empty()->Extend(value, zone)));
5468 current.set_from(entry->from()); 5509 current.set_from(entry->from());
5469 } 5510 }
5470 ASSERT_EQ(current.from(), entry->from()); 5511 ASSERT_EQ(current.from(), entry->from());
5471 // If the overlapping range extends beyond the one we want to add 5512 // If the overlapping range extends beyond the one we want to add
5472 // we have to snap the right part off and add it separately. 5513 // we have to snap the right part off and add it separately.
5473 if (entry->to() > current.to()) { 5514 if (entry->to() > current.to()) {
5474 ZoneSplayTree<Config>::Locator ins; 5515 ZoneSplayTree<Config>::Locator ins;
5475 ASSERT_RESULT(tree()->Insert(current.to() + 1, &ins)); 5516 ASSERT_RESULT(tree()->Insert(current.to() + 1, &ins));
5476 ins.set_value(Entry(current.to() + 1, 5517 ins.set_value(Entry(current.to() + 1,
5477 entry->to(), 5518 entry->to(),
5478 entry->out_set())); 5519 entry->out_set()));
5479 entry->set_to(current.to()); 5520 entry->set_to(current.to());
5480 } 5521 }
5481 ASSERT(entry->to() <= current.to()); 5522 ASSERT(entry->to() <= current.to());
5482 // The overlapping range is now completely contained by the range 5523 // The overlapping range is now completely contained by the range
5483 // we're adding so we can just update it and move the start point 5524 // we're adding so we can just update it and move the start point
5484 // of the range we're adding just past it. 5525 // of the range we're adding just past it.
5485 entry->AddValue(value); 5526 entry->AddValue(value, zone);
5486 // Bail out if the last interval ended at 0xFFFF since otherwise 5527 // Bail out if the last interval ended at 0xFFFF since otherwise
5487 // adding 1 will wrap around to 0. 5528 // adding 1 will wrap around to 0.
5488 if (entry->to() == String::kMaxUtf16CodeUnit) 5529 if (entry->to() == String::kMaxUtf16CodeUnit)
5489 break; 5530 break;
5490 ASSERT(entry->to() + 1 > current.from()); 5531 ASSERT(entry->to() + 1 > current.from());
5491 current.set_from(entry->to() + 1); 5532 current.set_from(entry->to() + 1);
5492 } else { 5533 } else {
5493 // There is no overlap so we can just add the range 5534 // There is no overlap so we can just add the range
5494 ZoneSplayTree<Config>::Locator ins; 5535 ZoneSplayTree<Config>::Locator ins;
5495 ASSERT_RESULT(tree()->Insert(current.from(), &ins)); 5536 ASSERT_RESULT(tree()->Insert(current.from(), &ins));
5496 ins.set_value(Entry(current.from(), 5537 ins.set_value(Entry(current.from(),
5497 current.to(), 5538 current.to(),
5498 empty()->Extend(value))); 5539 empty()->Extend(value, zone)));
5499 break; 5540 break;
5500 } 5541 }
5501 } 5542 }
5502 } 5543 }
5503 5544
5504 5545
5505 OutSet* DispatchTable::Get(uc16 value) { 5546 OutSet* DispatchTable::Get(uc16 value) {
5506 ZoneSplayTree<Config>::Locator loc; 5547 ZoneSplayTree<Config>::Locator loc;
5507 if (!tree()->FindGreatestLessThan(value, &loc)) 5548 if (!tree()->FindGreatestLessThan(value, &loc))
5508 return empty(); 5549 return empty();
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
5688 for (int j = 0; j < length; j++) { 5729 for (int j = 0; j < length; j++) {
5689 bm->Set(offset, chars[j]); 5730 bm->Set(offset, chars[j]);
5690 } 5731 }
5691 } else { 5732 } else {
5692 if (character <= max_char) bm->Set(offset, character); 5733 if (character <= max_char) bm->Set(offset, character);
5693 } 5734 }
5694 } 5735 }
5695 } else { 5736 } else {
5696 ASSERT(text.type == TextElement::CHAR_CLASS); 5737 ASSERT(text.type == TextElement::CHAR_CLASS);
5697 RegExpCharacterClass* char_class = text.data.u_char_class; 5738 RegExpCharacterClass* char_class = text.data.u_char_class;
5698 ZoneList<CharacterRange>* ranges = char_class->ranges(); 5739 ZoneList<CharacterRange>* ranges = char_class->ranges(zone());
5699 if (char_class->is_negated()) { 5740 if (char_class->is_negated()) {
5700 bm->SetAll(offset); 5741 bm->SetAll(offset);
5701 } else { 5742 } else {
5702 for (int k = 0; k < ranges->length(); k++) { 5743 for (int k = 0; k < ranges->length(); k++) {
5703 CharacterRange& range = ranges->at(k); 5744 CharacterRange& range = ranges->at(k);
5704 if (range.from() > max_char) continue; 5745 if (range.from() > max_char) continue;
5705 int to = Min(max_char, static_cast<int>(range.to())); 5746 int to = Min(max_char, static_cast<int>(range.to()));
5706 bm->SetInterval(offset, Interval(range.from(), to)); 5747 bm->SetInterval(offset, Interval(range.from(), to));
5707 } 5748 }
5708 } 5749 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
5808 void DispatchTableConstructor::VisitText(TextNode* that) { 5849 void DispatchTableConstructor::VisitText(TextNode* that) {
5809 TextElement elm = that->elements()->at(0); 5850 TextElement elm = that->elements()->at(0);
5810 switch (elm.type) { 5851 switch (elm.type) {
5811 case TextElement::ATOM: { 5852 case TextElement::ATOM: {
5812 uc16 c = elm.data.u_atom->data()[0]; 5853 uc16 c = elm.data.u_atom->data()[0];
5813 AddRange(CharacterRange(c, c)); 5854 AddRange(CharacterRange(c, c));
5814 break; 5855 break;
5815 } 5856 }
5816 case TextElement::CHAR_CLASS: { 5857 case TextElement::CHAR_CLASS: {
5817 RegExpCharacterClass* tree = elm.data.u_char_class; 5858 RegExpCharacterClass* tree = elm.data.u_char_class;
5818 ZoneList<CharacterRange>* ranges = tree->ranges(); 5859 ZoneList<CharacterRange>* ranges = tree->ranges(that->zone());
5819 if (tree->is_negated()) { 5860 if (tree->is_negated()) {
5820 AddInverse(ranges); 5861 AddInverse(ranges);
5821 } else { 5862 } else {
5822 for (int i = 0; i < ranges->length(); i++) 5863 for (int i = 0; i < ranges->length(); i++)
5823 AddRange(ranges->at(i)); 5864 AddRange(ranges->at(i));
5824 } 5865 }
5825 break; 5866 break;
5826 } 5867 }
5827 default: { 5868 default: {
5828 UNIMPLEMENTED(); 5869 UNIMPLEMENTED();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
5872 bool is_end_anchored = data->tree->IsAnchoredAtEnd(); 5913 bool is_end_anchored = data->tree->IsAnchoredAtEnd();
5873 bool is_start_anchored = data->tree->IsAnchoredAtStart(); 5914 bool is_start_anchored = data->tree->IsAnchoredAtStart();
5874 int max_length = data->tree->max_match(); 5915 int max_length = data->tree->max_match();
5875 if (!is_start_anchored) { 5916 if (!is_start_anchored) {
5876 // Add a .*? at the beginning, outside the body capture, unless 5917 // Add a .*? at the beginning, outside the body capture, unless
5877 // this expression is anchored at the beginning. 5918 // this expression is anchored at the beginning.
5878 RegExpNode* loop_node = 5919 RegExpNode* loop_node =
5879 RegExpQuantifier::ToNode(0, 5920 RegExpQuantifier::ToNode(0,
5880 RegExpTree::kInfinity, 5921 RegExpTree::kInfinity,
5881 false, 5922 false,
5882 new RegExpCharacterClass('*'), 5923 new(zone) RegExpCharacterClass('*'),
5883 &compiler, 5924 &compiler,
5884 captured_body, 5925 captured_body,
5885 data->contains_anchor); 5926 data->contains_anchor);
5886 5927
5887 if (data->contains_anchor) { 5928 if (data->contains_anchor) {
5888 // Unroll loop once, to take care of the case that might start 5929 // Unroll loop once, to take care of the case that might start
5889 // at the start of input. 5930 // at the start of input.
5890 ChoiceNode* first_step_node = new ChoiceNode(2, zone); 5931 ChoiceNode* first_step_node = new(zone) ChoiceNode(2, zone);
5891 first_step_node->AddAlternative(GuardedAlternative(captured_body)); 5932 first_step_node->AddAlternative(GuardedAlternative(captured_body));
5892 first_step_node->AddAlternative(GuardedAlternative( 5933 first_step_node->AddAlternative(GuardedAlternative(
5893 new TextNode(new RegExpCharacterClass('*'), loop_node))); 5934 new(zone) TextNode(new(zone) RegExpCharacterClass('*'), loop_node)));
5894 node = first_step_node; 5935 node = first_step_node;
5895 } else { 5936 } else {
5896 node = loop_node; 5937 node = loop_node;
5897 } 5938 }
5898 } 5939 }
5899 if (is_ascii) { 5940 if (is_ascii) {
5900 node = node->FilterASCII(RegExpCompiler::kMaxRecursion); 5941 node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5901 // Do it again to propagate the new nodes to places where they were not 5942 // Do it again to propagate the new nodes to places where they were not
5902 // put because they had not been calculated yet. 5943 // put because they had not been calculated yet.
5903 if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion); 5944 if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5904 } 5945 }
5905 5946
5906 if (node == NULL) node = new EndNode(EndNode::BACKTRACK, zone); 5947 if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone);
5907 data->node = node; 5948 data->node = node;
5908 Analysis analysis(ignore_case, is_ascii); 5949 Analysis analysis(ignore_case, is_ascii);
5909 analysis.EnsureAnalyzed(node); 5950 analysis.EnsureAnalyzed(node);
5910 if (analysis.has_failed()) { 5951 if (analysis.has_failed()) {
5911 const char* error_message = analysis.error_message(); 5952 const char* error_message = analysis.error_message();
5912 return CompilationResult(error_message); 5953 return CompilationResult(error_message);
5913 } 5954 }
5914 5955
5915 // Create the correct assembler for the architecture. 5956 // Create the correct assembler for the architecture.
5916 #ifndef V8_INTERPRETED_REGEXP 5957 #ifndef V8_INTERPRETED_REGEXP
5917 // Native regexp implementation. 5958 // Native regexp implementation.
5918 5959
5919 NativeRegExpMacroAssembler::Mode mode = 5960 NativeRegExpMacroAssembler::Mode mode =
5920 is_ascii ? NativeRegExpMacroAssembler::ASCII 5961 is_ascii ? NativeRegExpMacroAssembler::ASCII
5921 : NativeRegExpMacroAssembler::UC16; 5962 : NativeRegExpMacroAssembler::UC16;
5922 5963
5923 #if V8_TARGET_ARCH_IA32 5964 #if V8_TARGET_ARCH_IA32
5924 RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2); 5965 RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2,
5966 zone);
5925 #elif V8_TARGET_ARCH_X64 5967 #elif V8_TARGET_ARCH_X64
5926 RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2); 5968 RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2,
5969 zone);
5927 #elif V8_TARGET_ARCH_ARM 5970 #elif V8_TARGET_ARCH_ARM
5928 RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2); 5971 RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2,
5972 zone);
5929 #elif V8_TARGET_ARCH_MIPS 5973 #elif V8_TARGET_ARCH_MIPS
5930 RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2); 5974 RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2);
5931 #endif 5975 #endif
5932 5976
5933 #else // V8_INTERPRETED_REGEXP 5977 #else // V8_INTERPRETED_REGEXP
5934 // Interpreted regexp implementation. 5978 // Interpreted regexp implementation.
5935 EmbeddedVector<byte, 1024> codes; 5979 EmbeddedVector<byte, 1024> codes;
5936 RegExpMacroAssemblerIrregexp macro_assembler(codes); 5980 RegExpMacroAssemblerIrregexp macro_assembler(codes);
5937 #endif // V8_INTERPRETED_REGEXP 5981 #endif // V8_INTERPRETED_REGEXP
5938 5982
(...skipping 14 matching lines...) Expand all
5953 } 5997 }
5954 5998
5955 return compiler.Assemble(&macro_assembler, 5999 return compiler.Assemble(&macro_assembler,
5956 node, 6000 node,
5957 data->capture_count, 6001 data->capture_count,
5958 pattern); 6002 pattern);
5959 } 6003 }
5960 6004
5961 6005
5962 }} // namespace v8::internal 6006 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/list-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698