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

Side by Side Diff: src/jsregexp.cc

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

Powered by Google App Engine
This is Rietveld 408576698