OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 ®isters_to_pop, | 1316 ®isters_to_pop, |
1314 ®isters_to_clear); | 1317 ®isters_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
5953 } | 5997 } |
5954 | 5998 |
5955 return compiler.Assemble(¯o_assembler, | 5999 return compiler.Assemble(¯o_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 |
OLD | NEW |