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

Side by Side Diff: src/jsregexp.cc

Issue 868883002: Remove the dependency of Zone on Isolate (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compilation issues Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/jsregexp.h ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/base/platform/platform.h" 8 #include "src/base/platform/platform.h"
9 #include "src/compilation-cache.h" 9 #include "src/compilation-cache.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 131 }
132 132
133 133
134 // Generic RegExp methods. Dispatches to implementation specific methods. 134 // Generic RegExp methods. Dispatches to implementation specific methods.
135 135
136 136
137 MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, 137 MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
138 Handle<String> pattern, 138 Handle<String> pattern,
139 JSRegExp::Flags flags) { 139 JSRegExp::Flags flags) {
140 Isolate* isolate = re->GetIsolate(); 140 Isolate* isolate = re->GetIsolate();
141 Zone zone(isolate); 141 Zone zone;
142 CompilationCache* compilation_cache = isolate->compilation_cache(); 142 CompilationCache* compilation_cache = isolate->compilation_cache();
143 MaybeHandle<FixedArray> maybe_cached = 143 MaybeHandle<FixedArray> maybe_cached =
144 compilation_cache->LookupRegExp(pattern, flags); 144 compilation_cache->LookupRegExp(pattern, flags);
145 Handle<FixedArray> cached; 145 Handle<FixedArray> cached;
146 bool in_cache = maybe_cached.ToHandle(&cached); 146 bool in_cache = maybe_cached.ToHandle(&cached);
147 LOG(isolate, RegExpCompileEvent(re, in_cache)); 147 LOG(isolate, RegExpCompileEvent(re, in_cache));
148 148
149 Handle<Object> result; 149 Handle<Object> result;
150 if (in_cache) { 150 if (in_cache) {
151 re->set_data(*cached); 151 re->set_data(*cached);
152 return re; 152 return re;
153 } 153 }
154 pattern = String::Flatten(pattern); 154 pattern = String::Flatten(pattern);
155 PostponeInterruptsScope postpone(isolate); 155 PostponeInterruptsScope postpone(isolate);
156 RegExpCompileData parse_result; 156 RegExpCompileData parse_result;
157 FlatStringReader reader(isolate, pattern); 157 FlatStringReader reader(isolate, pattern);
158 if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(), 158 if (!RegExpParser::ParseRegExp(re->GetIsolate(), &zone, &reader,
159 flags.is_unicode(), &parse_result, &zone)) { 159 flags.is_multiline(), flags.is_unicode(),
160 &parse_result)) {
160 // Throw an exception if we fail to parse the pattern. 161 // Throw an exception if we fail to parse the pattern.
161 return ThrowRegExpException(re, 162 return ThrowRegExpException(re,
162 pattern, 163 pattern,
163 parse_result.error, 164 parse_result.error,
164 "malformed_regexp"); 165 "malformed_regexp");
165 } 166 }
166 167
167 bool has_been_compiled = false; 168 bool has_been_compiled = false;
168 169
169 if (parse_result.simple && 170 if (parse_result.simple &&
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 factory->NewSyntaxError("malformed_regexp", array); 365 factory->NewSyntaxError("malformed_regexp", array);
365 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); 366 if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
366 } 367 }
367 368
368 369
369 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, 370 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
370 Handle<String> sample_subject, 371 Handle<String> sample_subject,
371 bool is_one_byte) { 372 bool is_one_byte) {
372 // Compile the RegExp. 373 // Compile the RegExp.
373 Isolate* isolate = re->GetIsolate(); 374 Isolate* isolate = re->GetIsolate();
374 Zone zone(isolate); 375 Zone zone;
375 PostponeInterruptsScope postpone(isolate); 376 PostponeInterruptsScope postpone(isolate);
376 // If we had a compilation error the last time this is saved at the 377 // If we had a compilation error the last time this is saved at the
377 // saved code index. 378 // saved code index.
378 Object* entry = re->DataAt(JSRegExp::code_index(is_one_byte)); 379 Object* entry = re->DataAt(JSRegExp::code_index(is_one_byte));
379 // When arriving here entry can only be a smi, either representing an 380 // When arriving here entry can only be a smi, either representing an
380 // uncompiled regexp, a previous compilation error, or code that has 381 // uncompiled regexp, a previous compilation error, or code that has
381 // been flushed. 382 // been flushed.
382 DCHECK(entry->IsSmi()); 383 DCHECK(entry->IsSmi());
383 int entry_value = Smi::cast(entry)->value(); 384 int entry_value = Smi::cast(entry)->value();
384 DCHECK(entry_value == JSRegExp::kUninitializedValue || 385 DCHECK(entry_value == JSRegExp::kUninitializedValue ||
(...skipping 10 matching lines...) Expand all
395 CreateRegExpErrorObjectAndThrow(re, error_message, isolate); 396 CreateRegExpErrorObjectAndThrow(re, error_message, isolate);
396 return false; 397 return false;
397 } 398 }
398 399
399 JSRegExp::Flags flags = re->GetFlags(); 400 JSRegExp::Flags flags = re->GetFlags();
400 401
401 Handle<String> pattern(re->Pattern()); 402 Handle<String> pattern(re->Pattern());
402 pattern = String::Flatten(pattern); 403 pattern = String::Flatten(pattern);
403 RegExpCompileData compile_data; 404 RegExpCompileData compile_data;
404 FlatStringReader reader(isolate, pattern); 405 FlatStringReader reader(isolate, pattern);
405 if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(), 406 if (!RegExpParser::ParseRegExp(isolate, &zone, &reader, flags.is_multiline(),
406 flags.is_unicode(), &compile_data, &zone)) { 407 flags.is_unicode(), &compile_data)) {
407 // Throw an exception if we fail to parse the pattern. 408 // Throw an exception if we fail to parse the pattern.
408 // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once. 409 // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
409 USE(ThrowRegExpException(re, 410 USE(ThrowRegExpException(re,
410 pattern, 411 pattern,
411 compile_data.error, 412 compile_data.error,
412 "malformed_regexp")); 413 "malformed_regexp"));
413 return false; 414 return false;
414 } 415 }
415 RegExpEngine::CompilationResult result = RegExpEngine::Compile( 416 RegExpEngine::CompilationResult result = RegExpEngine::Compile(
416 &compile_data, flags.is_ignore_case(), flags.is_global(), 417 isolate, &zone, &compile_data, flags.is_ignore_case(), flags.is_global(),
417 flags.is_multiline(), flags.is_sticky(), pattern, sample_subject, 418 flags.is_multiline(), flags.is_sticky(), pattern, sample_subject,
418 is_one_byte, &zone); 419 is_one_byte);
419 if (result.error_message != NULL) { 420 if (result.error_message != NULL) {
420 // Unable to compile regexp. 421 // Unable to compile regexp.
421 Handle<String> error_message = isolate->factory()->NewStringFromUtf8( 422 Handle<String> error_message = isolate->factory()->NewStringFromUtf8(
422 CStrVector(result.error_message)).ToHandleChecked(); 423 CStrVector(result.error_message)).ToHandleChecked();
423 CreateRegExpErrorObjectAndThrow(re, error_message, isolate); 424 CreateRegExpErrorObjectAndThrow(re, error_message, isolate);
424 return false; 425 return false;
425 } 426 }
426 427
427 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data())); 428 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data()));
428 data->set(JSRegExp::code_index(is_one_byte), result.code); 429 data->set(JSRegExp::code_index(is_one_byte), result.code);
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 965
965 966
966 private: 967 private:
967 CharacterFrequency frequencies_[RegExpMacroAssembler::kTableSize]; 968 CharacterFrequency frequencies_[RegExpMacroAssembler::kTableSize];
968 int total_samples_; 969 int total_samples_;
969 }; 970 };
970 971
971 972
972 class RegExpCompiler { 973 class RegExpCompiler {
973 public: 974 public:
974 RegExpCompiler(int capture_count, bool ignore_case, bool is_one_byte, 975 RegExpCompiler(Isolate* isolate, Zone* zone, int capture_count,
975 Zone* zone); 976 bool ignore_case, bool is_one_byte);
976 977
977 int AllocateRegister() { 978 int AllocateRegister() {
978 if (next_register_ >= RegExpMacroAssembler::kMaxRegister) { 979 if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
979 reg_exp_too_big_ = true; 980 reg_exp_too_big_ = true;
980 return next_register_; 981 return next_register_;
981 } 982 }
982 return next_register_++; 983 return next_register_++;
983 } 984 }
984 985
985 RegExpEngine::CompilationResult Assemble(RegExpMacroAssembler* assembler, 986 RegExpEngine::CompilationResult Assemble(RegExpMacroAssembler* assembler,
(...skipping 21 matching lines...) Expand all
1007 inline bool one_byte() { return one_byte_; } 1008 inline bool one_byte() { return one_byte_; }
1008 inline bool optimize() { return optimize_; } 1009 inline bool optimize() { return optimize_; }
1009 inline void set_optimize(bool value) { optimize_ = value; } 1010 inline void set_optimize(bool value) { optimize_ = value; }
1010 FrequencyCollator* frequency_collator() { return &frequency_collator_; } 1011 FrequencyCollator* frequency_collator() { return &frequency_collator_; }
1011 1012
1012 int current_expansion_factor() { return current_expansion_factor_; } 1013 int current_expansion_factor() { return current_expansion_factor_; }
1013 void set_current_expansion_factor(int value) { 1014 void set_current_expansion_factor(int value) {
1014 current_expansion_factor_ = value; 1015 current_expansion_factor_ = value;
1015 } 1016 }
1016 1017
1018 Isolate* isolate() const { return isolate_; }
1017 Zone* zone() const { return zone_; } 1019 Zone* zone() const { return zone_; }
1018 1020
1019 static const int kNoRegister = -1; 1021 static const int kNoRegister = -1;
1020 1022
1021 private: 1023 private:
1022 EndNode* accept_; 1024 EndNode* accept_;
1023 int next_register_; 1025 int next_register_;
1024 List<RegExpNode*>* work_list_; 1026 List<RegExpNode*>* work_list_;
1025 int recursion_depth_; 1027 int recursion_depth_;
1026 RegExpMacroAssembler* macro_assembler_; 1028 RegExpMacroAssembler* macro_assembler_;
1027 bool ignore_case_; 1029 bool ignore_case_;
1028 bool one_byte_; 1030 bool one_byte_;
1029 bool reg_exp_too_big_; 1031 bool reg_exp_too_big_;
1030 bool optimize_; 1032 bool optimize_;
1031 int current_expansion_factor_; 1033 int current_expansion_factor_;
1032 FrequencyCollator frequency_collator_; 1034 FrequencyCollator frequency_collator_;
1035 Isolate* isolate_;
1033 Zone* zone_; 1036 Zone* zone_;
1034 }; 1037 };
1035 1038
1036 1039
1037 class RecursionCheck { 1040 class RecursionCheck {
1038 public: 1041 public:
1039 explicit RecursionCheck(RegExpCompiler* compiler) : compiler_(compiler) { 1042 explicit RecursionCheck(RegExpCompiler* compiler) : compiler_(compiler) {
1040 compiler->IncrementRecursionDepth(); 1043 compiler->IncrementRecursionDepth();
1041 } 1044 }
1042 ~RecursionCheck() { compiler_->DecrementRecursionDepth(); } 1045 ~RecursionCheck() { compiler_->DecrementRecursionDepth(); }
1043 private: 1046 private:
1044 RegExpCompiler* compiler_; 1047 RegExpCompiler* compiler_;
1045 }; 1048 };
1046 1049
1047 1050
1048 static RegExpEngine::CompilationResult IrregexpRegExpTooBig(Isolate* isolate) { 1051 static RegExpEngine::CompilationResult IrregexpRegExpTooBig(Isolate* isolate) {
1049 return RegExpEngine::CompilationResult(isolate, "RegExp too big"); 1052 return RegExpEngine::CompilationResult(isolate, "RegExp too big");
1050 } 1053 }
1051 1054
1052 1055
1053 // Attempts to compile the regexp using an Irregexp code generator. Returns 1056 // Attempts to compile the regexp using an Irregexp code generator. Returns
1054 // a fixed array or a null handle depending on whether it succeeded. 1057 // a fixed array or a null handle depending on whether it succeeded.
1055 RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, 1058 RegExpCompiler::RegExpCompiler(Isolate* isolate, Zone* zone, int capture_count,
1056 bool one_byte, Zone* zone) 1059 bool ignore_case, bool one_byte)
1057 : next_register_(2 * (capture_count + 1)), 1060 : next_register_(2 * (capture_count + 1)),
1058 work_list_(NULL), 1061 work_list_(NULL),
1059 recursion_depth_(0), 1062 recursion_depth_(0),
1060 ignore_case_(ignore_case), 1063 ignore_case_(ignore_case),
1061 one_byte_(one_byte), 1064 one_byte_(one_byte),
1062 reg_exp_too_big_(false), 1065 reg_exp_too_big_(false),
1063 optimize_(FLAG_regexp_optimization), 1066 optimize_(FLAG_regexp_optimization),
1064 current_expansion_factor_(1), 1067 current_expansion_factor_(1),
1065 frequency_collator_(), 1068 frequency_collator_(),
1069 isolate_(isolate),
1066 zone_(zone) { 1070 zone_(zone) {
1067 accept_ = new(zone) EndNode(EndNode::ACCEPT, zone); 1071 accept_ = new(zone) EndNode(EndNode::ACCEPT, zone);
1068 DCHECK(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister); 1072 DCHECK(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
1069 } 1073 }
1070 1074
1071 1075
1072 RegExpEngine::CompilationResult RegExpCompiler::Assemble( 1076 RegExpEngine::CompilationResult RegExpCompiler::Assemble(
1073 RegExpMacroAssembler* macro_assembler, 1077 RegExpMacroAssembler* macro_assembler,
1074 RegExpNode* start, 1078 RegExpNode* start,
1075 int capture_count, 1079 int capture_count,
1076 Handle<String> pattern) { 1080 Handle<String> pattern) {
1077 Heap* heap = pattern->GetHeap(); 1081 Heap* heap = pattern->GetHeap();
1078 1082
1079 #ifdef DEBUG 1083 #ifdef DEBUG
1080 if (FLAG_trace_regexp_assembler) 1084 if (FLAG_trace_regexp_assembler)
1081 macro_assembler_ = new RegExpMacroAssemblerTracer(macro_assembler); 1085 macro_assembler_ =
1086 new RegExpMacroAssemblerTracer(isolate(), macro_assembler);
1082 else 1087 else
1083 #endif 1088 #endif
1084 macro_assembler_ = macro_assembler; 1089 macro_assembler_ = macro_assembler;
1085 1090
1086 List <RegExpNode*> work_list(0); 1091 List <RegExpNode*> work_list(0);
1087 work_list_ = &work_list; 1092 work_list_ = &work_list;
1088 Label fail; 1093 Label fail;
1089 macro_assembler_->PushBacktrack(&fail); 1094 macro_assembler_->PushBacktrack(&fail);
1090 Trace new_trace; 1095 Trace new_trace;
1091 start->Emit(this, &new_trace); 1096 start->Emit(this, &new_trace);
1092 macro_assembler_->Bind(&fail); 1097 macro_assembler_->Bind(&fail);
1093 macro_assembler_->Fail(); 1098 macro_assembler_->Fail();
1094 while (!work_list.is_empty()) { 1099 while (!work_list.is_empty()) {
1095 work_list.RemoveLast()->Emit(this, &new_trace); 1100 work_list.RemoveLast()->Emit(this, &new_trace);
1096 } 1101 }
1097 if (reg_exp_too_big_) return IrregexpRegExpTooBig(zone_->isolate()); 1102 if (reg_exp_too_big_) return IrregexpRegExpTooBig(isolate_);
1098 1103
1099 Handle<HeapObject> code = macro_assembler_->GetCode(pattern); 1104 Handle<HeapObject> code = macro_assembler_->GetCode(pattern);
1100 heap->IncreaseTotalRegexpCodeGenerated(code->Size()); 1105 heap->IncreaseTotalRegexpCodeGenerated(code->Size());
1101 work_list_ = NULL; 1106 work_list_ = NULL;
1102 #ifdef ENABLE_DISASSEMBLER 1107 #ifdef ENABLE_DISASSEMBLER
1103 if (FLAG_print_code) { 1108 if (FLAG_print_code) {
1104 CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer()); 1109 CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer());
1105 OFStream os(trace_scope.file()); 1110 OFStream os(trace_scope.file());
1106 Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), os); 1111 Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), os);
1107 } 1112 }
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 bit ^= 1; 1821 bit ^= 1;
1817 for (int i = start_index; i < end_index; i++) { 1822 for (int i = start_index; i < end_index; i++) {
1818 for (j = (ranges->at(i) & kMask); j < (ranges->at(i + 1) & kMask); j++) { 1823 for (j = (ranges->at(i) & kMask); j < (ranges->at(i + 1) & kMask); j++) {
1819 templ[j] = bit; 1824 templ[j] = bit;
1820 } 1825 }
1821 bit ^= 1; 1826 bit ^= 1;
1822 } 1827 }
1823 for (int i = j; i < kSize; i++) { 1828 for (int i = j; i < kSize; i++) {
1824 templ[i] = bit; 1829 templ[i] = bit;
1825 } 1830 }
1826 Factory* factory = masm->zone()->isolate()->factory(); 1831 Factory* factory = masm->isolate()->factory();
1827 // TODO(erikcorry): Cache these. 1832 // TODO(erikcorry): Cache these.
1828 Handle<ByteArray> ba = factory->NewByteArray(kSize, TENURED); 1833 Handle<ByteArray> ba = factory->NewByteArray(kSize, TENURED);
1829 for (int i = 0; i < kSize; i++) { 1834 for (int i = 0; i < kSize; i++) {
1830 ba->set(i, templ[i]); 1835 ba->set(i, templ[i]);
1831 } 1836 }
1832 masm->CheckBitInTable(ba, on_bit_set); 1837 masm->CheckBitInTable(ba, on_bit_set);
1833 if (on_bit_clear != fall_through) masm->GoTo(on_bit_clear); 1838 if (on_bit_clear != fall_through) masm->GoTo(on_bit_clear);
1834 } 1839 }
1835 1840
1836 1841
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 // 2500 //
2496 // We iterate along the text object, building up for each character a 2501 // We iterate along the text object, building up for each character a
2497 // mask and value that can be used to test for a quick failure to match. 2502 // mask and value that can be used to test for a quick failure to match.
2498 // The masks and values for the positions will be combined into a single 2503 // The masks and values for the positions will be combined into a single
2499 // machine word for the current character width in order to be used in 2504 // machine word for the current character width in order to be used in
2500 // generating a quick check. 2505 // generating a quick check.
2501 void TextNode::GetQuickCheckDetails(QuickCheckDetails* details, 2506 void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
2502 RegExpCompiler* compiler, 2507 RegExpCompiler* compiler,
2503 int characters_filled_in, 2508 int characters_filled_in,
2504 bool not_at_start) { 2509 bool not_at_start) {
2505 Isolate* isolate = compiler->macro_assembler()->zone()->isolate(); 2510 Isolate* isolate = compiler->macro_assembler()->isolate();
2506 DCHECK(characters_filled_in < details->characters()); 2511 DCHECK(characters_filled_in < details->characters());
2507 int characters = details->characters(); 2512 int characters = details->characters();
2508 int char_mask; 2513 int char_mask;
2509 if (compiler->one_byte()) { 2514 if (compiler->one_byte()) {
2510 char_mask = String::kMaxOneByteCharCode; 2515 char_mask = String::kMaxOneByteCharCode;
2511 } else { 2516 } else {
2512 char_mask = String::kMaxUtf16CodeUnit; 2517 char_mask = String::kMaxUtf16CodeUnit;
2513 } 2518 }
2514 for (int k = 0; k < elms_->length(); k++) { 2519 for (int k = 0; k < elms_->length(); k++) {
2515 TextElement elm = elms_->at(k); 2520 TextElement elm = elms_->at(k);
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
3196 // up to the limit the quick check already checked. In addition the quick 3201 // up to the limit the quick check already checked. In addition the quick
3197 // check can have involved a mask and compare operation which may simplify 3202 // check can have involved a mask and compare operation which may simplify
3198 // or obviate the need for further checks at some character positions. 3203 // or obviate the need for further checks at some character positions.
3199 void TextNode::TextEmitPass(RegExpCompiler* compiler, 3204 void TextNode::TextEmitPass(RegExpCompiler* compiler,
3200 TextEmitPassType pass, 3205 TextEmitPassType pass,
3201 bool preloaded, 3206 bool preloaded,
3202 Trace* trace, 3207 Trace* trace,
3203 bool first_element_checked, 3208 bool first_element_checked,
3204 int* checked_up_to) { 3209 int* checked_up_to) {
3205 RegExpMacroAssembler* assembler = compiler->macro_assembler(); 3210 RegExpMacroAssembler* assembler = compiler->macro_assembler();
3206 Isolate* isolate = assembler->zone()->isolate(); 3211 Isolate* isolate = assembler->isolate();
3207 bool one_byte = compiler->one_byte(); 3212 bool one_byte = compiler->one_byte();
3208 Label* backtrack = trace->backtrack(); 3213 Label* backtrack = trace->backtrack();
3209 QuickCheckDetails* quick_check = trace->quick_check_performed(); 3214 QuickCheckDetails* quick_check = trace->quick_check_performed();
3210 int element_count = elms_->length(); 3215 int element_count = elms_->length();
3211 for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) { 3216 for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) {
3212 TextElement elm = elms_->at(i); 3217 TextElement elm = elms_->at(i);
3213 int cp_offset = trace->cp_offset() + elm.cp_offset(); 3218 int cp_offset = trace->cp_offset() + elm.cp_offset();
3214 if (elm.text_type() == TextElement::ATOM) { 3219 if (elm.text_type() == TextElement::ATOM) {
3215 Vector<const uc16> quarks = elm.atom()->data(); 3220 Vector<const uc16> quarks = elm.atom()->data();
3216 for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) { 3221 for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3357 quick_check_performed_.Advance(by, compiler->one_byte()); 3362 quick_check_performed_.Advance(by, compiler->one_byte());
3358 cp_offset_ += by; 3363 cp_offset_ += by;
3359 if (cp_offset_ > RegExpMacroAssembler::kMaxCPOffset) { 3364 if (cp_offset_ > RegExpMacroAssembler::kMaxCPOffset) {
3360 compiler->SetRegExpTooBig(); 3365 compiler->SetRegExpTooBig();
3361 cp_offset_ = 0; 3366 cp_offset_ = 0;
3362 } 3367 }
3363 bound_checked_up_to_ = Max(0, bound_checked_up_to_ - by); 3368 bound_checked_up_to_ = Max(0, bound_checked_up_to_ - by);
3364 } 3369 }
3365 3370
3366 3371
3367 void TextNode::MakeCaseIndependent(bool is_one_byte) { 3372 void TextNode::MakeCaseIndependent(Isolate* isolate, bool is_one_byte) {
3368 int element_count = elms_->length(); 3373 int element_count = elms_->length();
3369 for (int i = 0; i < element_count; i++) { 3374 for (int i = 0; i < element_count; i++) {
3370 TextElement elm = elms_->at(i); 3375 TextElement elm = elms_->at(i);
3371 if (elm.text_type() == TextElement::CHAR_CLASS) { 3376 if (elm.text_type() == TextElement::CHAR_CLASS) {
3372 RegExpCharacterClass* cc = elm.char_class(); 3377 RegExpCharacterClass* cc = elm.char_class();
3373 // None of the standard character classes is different in the case 3378 // None of the standard character classes is different in the case
3374 // independent case and it slows us down if we don't know that. 3379 // independent case and it slows us down if we don't know that.
3375 if (cc->is_standard(zone())) continue; 3380 if (cc->is_standard(zone())) continue;
3376 ZoneList<CharacterRange>* ranges = cc->ranges(zone()); 3381 ZoneList<CharacterRange>* ranges = cc->ranges(zone());
3377 int range_count = ranges->length(); 3382 int range_count = ranges->length();
3378 for (int j = 0; j < range_count; j++) { 3383 for (int j = 0; j < range_count; j++) {
3379 ranges->at(j).AddCaseEquivalents(ranges, is_one_byte, zone()); 3384 ranges->at(j).AddCaseEquivalents(isolate, zone(), ranges, is_one_byte);
3380 } 3385 }
3381 } 3386 }
3382 } 3387 }
3383 } 3388 }
3384 3389
3385 3390
3386 int TextNode::GreedyLoopTextLength() { 3391 int TextNode::GreedyLoopTextLength() {
3387 TextElement elm = elms_->at(elms_->length() - 1); 3392 TextElement elm = elms_->at(elms_->length() - 1);
3388 return elm.cp_offset() + elm.length(); 3393 return elm.cp_offset() + elm.length();
3389 } 3394 }
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
3768 &cont); 3773 &cont);
3769 } else { 3774 } else {
3770 masm->CheckCharacter(single_character, &cont); 3775 masm->CheckCharacter(single_character, &cont);
3771 } 3776 }
3772 masm->AdvanceCurrentPosition(lookahead_width); 3777 masm->AdvanceCurrentPosition(lookahead_width);
3773 masm->GoTo(&again); 3778 masm->GoTo(&again);
3774 masm->Bind(&cont); 3779 masm->Bind(&cont);
3775 return; 3780 return;
3776 } 3781 }
3777 3782
3778 Factory* factory = masm->zone()->isolate()->factory(); 3783 Factory* factory = masm->isolate()->factory();
3779 Handle<ByteArray> boolean_skip_table = factory->NewByteArray(kSize, TENURED); 3784 Handle<ByteArray> boolean_skip_table = factory->NewByteArray(kSize, TENURED);
3780 int skip_distance = GetSkipTable( 3785 int skip_distance = GetSkipTable(
3781 min_lookahead, max_lookahead, boolean_skip_table); 3786 min_lookahead, max_lookahead, boolean_skip_table);
3782 DCHECK(skip_distance != 0); 3787 DCHECK(skip_distance != 0);
3783 3788
3784 Label cont, again; 3789 Label cont, again;
3785 masm->Bind(&again); 3790 masm->Bind(&again);
3786 masm->LoadCurrentCharacter(max_lookahead, &cont, true); 3791 masm->LoadCurrentCharacter(max_lookahead, &cont, true);
3787 masm->CheckBitInTable(boolean_skip_table, &cont); 3792 masm->CheckBitInTable(boolean_skip_table, &cont);
3788 masm->AdvanceCurrentPosition(skip_distance); 3793 masm->AdvanceCurrentPosition(skip_distance);
(...skipping 1507 matching lines...) Expand 10 before | Expand all | Expand 10 after
5296 table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone); 5301 table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone);
5297 for (int i = 0; i < overlay.length(); i += 2) { 5302 for (int i = 0; i < overlay.length(); i += 2) {
5298 table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1), 5303 table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1),
5299 CharacterRangeSplitter::kInOverlay, zone); 5304 CharacterRangeSplitter::kInOverlay, zone);
5300 } 5305 }
5301 CharacterRangeSplitter callback(included, excluded, zone); 5306 CharacterRangeSplitter callback(included, excluded, zone);
5302 table.ForEach(&callback); 5307 table.ForEach(&callback);
5303 } 5308 }
5304 5309
5305 5310
5306 void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges, 5311 void CharacterRange::AddCaseEquivalents(Isolate* isolate, Zone* zone,
5307 bool is_one_byte, Zone* zone) { 5312 ZoneList<CharacterRange>* ranges,
5308 Isolate* isolate = zone->isolate(); 5313 bool is_one_byte) {
5309 uc16 bottom = from(); 5314 uc16 bottom = from();
5310 uc16 top = to(); 5315 uc16 top = to();
5311 if (is_one_byte && !RangeContainsLatin1Equivalents(*this)) { 5316 if (is_one_byte && !RangeContainsLatin1Equivalents(*this)) {
5312 if (bottom > String::kMaxOneByteCharCode) return; 5317 if (bottom > String::kMaxOneByteCharCode) return;
5313 if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode; 5318 if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode;
5314 } 5319 }
5315 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 5320 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
5316 if (top == bottom) { 5321 if (top == bottom) {
5317 // If this is a singleton we just expand the one character. 5322 // If this is a singleton we just expand the one character.
5318 int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars); 5323 int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
5686 else 5691 else
5687 return empty(); 5692 return empty();
5688 } 5693 }
5689 5694
5690 5695
5691 // ------------------------------------------------------------------- 5696 // -------------------------------------------------------------------
5692 // Analysis 5697 // Analysis
5693 5698
5694 5699
5695 void Analysis::EnsureAnalyzed(RegExpNode* that) { 5700 void Analysis::EnsureAnalyzed(RegExpNode* that) {
5696 StackLimitCheck check(that->zone()->isolate()); 5701 StackLimitCheck check(isolate());
5697 if (check.HasOverflowed()) { 5702 if (check.HasOverflowed()) {
5698 fail("Stack overflow"); 5703 fail("Stack overflow");
5699 return; 5704 return;
5700 } 5705 }
5701 if (that->info()->been_analyzed || that->info()->being_analyzed) 5706 if (that->info()->been_analyzed || that->info()->being_analyzed)
5702 return; 5707 return;
5703 that->info()->being_analyzed = true; 5708 that->info()->being_analyzed = true;
5704 that->Accept(this); 5709 that->Accept(this);
5705 that->info()->being_analyzed = false; 5710 that->info()->being_analyzed = false;
5706 that->info()->been_analyzed = true; 5711 that->info()->been_analyzed = true;
(...skipping 13 matching lines...) Expand all
5720 for (int i = 0; i < element_count; i++) { 5725 for (int i = 0; i < element_count; i++) {
5721 TextElement& elm = elements()->at(i); 5726 TextElement& elm = elements()->at(i);
5722 elm.set_cp_offset(cp_offset); 5727 elm.set_cp_offset(cp_offset);
5723 cp_offset += elm.length(); 5728 cp_offset += elm.length();
5724 } 5729 }
5725 } 5730 }
5726 5731
5727 5732
5728 void Analysis::VisitText(TextNode* that) { 5733 void Analysis::VisitText(TextNode* that) {
5729 if (ignore_case_) { 5734 if (ignore_case_) {
5730 that->MakeCaseIndependent(is_one_byte_); 5735 that->MakeCaseIndependent(isolate(), is_one_byte_);
5731 } 5736 }
5732 EnsureAnalyzed(that->on_success()); 5737 EnsureAnalyzed(that->on_success());
5733 if (!has_failed()) { 5738 if (!has_failed()) {
5734 that->CalculateOffsets(); 5739 that->CalculateOffsets();
5735 } 5740 }
5736 } 5741 }
5737 5742
5738 5743
5739 void Analysis::VisitAction(ActionNode* that) { 5744 void Analysis::VisitAction(ActionNode* that) {
5740 RegExpNode* target = that->on_success(); 5745 RegExpNode* target = that->on_success();
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
5996 } 6001 }
5997 6002
5998 6003
5999 void DispatchTableConstructor::VisitAction(ActionNode* that) { 6004 void DispatchTableConstructor::VisitAction(ActionNode* that) {
6000 RegExpNode* target = that->on_success(); 6005 RegExpNode* target = that->on_success();
6001 target->Accept(this); 6006 target->Accept(this);
6002 } 6007 }
6003 6008
6004 6009
6005 RegExpEngine::CompilationResult RegExpEngine::Compile( 6010 RegExpEngine::CompilationResult RegExpEngine::Compile(
6006 RegExpCompileData* data, bool ignore_case, bool is_global, 6011 Isolate* isolate, Zone* zone, RegExpCompileData* data, bool ignore_case,
6007 bool is_multiline, bool is_sticky, Handle<String> pattern, 6012 bool is_global, bool is_multiline, bool is_sticky, Handle<String> pattern,
6008 Handle<String> sample_subject, bool is_one_byte, Zone* zone) { 6013 Handle<String> sample_subject, bool is_one_byte) {
6009 if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) { 6014 if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
6010 return IrregexpRegExpTooBig(zone->isolate()); 6015 return IrregexpRegExpTooBig(isolate);
6011 } 6016 }
6012 RegExpCompiler compiler(data->capture_count, ignore_case, is_one_byte, zone); 6017 RegExpCompiler compiler(isolate, zone, data->capture_count, ignore_case,
6018 is_one_byte);
6013 6019
6014 compiler.set_optimize(!TooMuchRegExpCode(pattern)); 6020 compiler.set_optimize(!TooMuchRegExpCode(pattern));
6015 6021
6016 // Sample some characters from the middle of the string. 6022 // Sample some characters from the middle of the string.
6017 static const int kSampleSize = 128; 6023 static const int kSampleSize = 128;
6018 6024
6019 sample_subject = String::Flatten(sample_subject); 6025 sample_subject = String::Flatten(sample_subject);
6020 int chars_sampled = 0; 6026 int chars_sampled = 0;
6021 int half_way = (sample_subject->length() - kSampleSize) / 2; 6027 int half_way = (sample_subject->length() - kSampleSize) / 2;
6022 for (int i = Max(0, half_way); 6028 for (int i = Max(0, half_way);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6062 node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case); 6068 node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case);
6063 // Do it again to propagate the new nodes to places where they were not 6069 // Do it again to propagate the new nodes to places where they were not
6064 // put because they had not been calculated yet. 6070 // put because they had not been calculated yet.
6065 if (node != NULL) { 6071 if (node != NULL) {
6066 node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case); 6072 node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case);
6067 } 6073 }
6068 } 6074 }
6069 6075
6070 if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone); 6076 if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone);
6071 data->node = node; 6077 data->node = node;
6072 Analysis analysis(ignore_case, is_one_byte); 6078 Analysis analysis(isolate, ignore_case, is_one_byte);
6073 analysis.EnsureAnalyzed(node); 6079 analysis.EnsureAnalyzed(node);
6074 if (analysis.has_failed()) { 6080 if (analysis.has_failed()) {
6075 const char* error_message = analysis.error_message(); 6081 const char* error_message = analysis.error_message();
6076 return CompilationResult(zone->isolate(), error_message); 6082 return CompilationResult(isolate, error_message);
6077 } 6083 }
6078 6084
6079 // Create the correct assembler for the architecture. 6085 // Create the correct assembler for the architecture.
6080 #ifndef V8_INTERPRETED_REGEXP 6086 #ifndef V8_INTERPRETED_REGEXP
6081 // Native regexp implementation. 6087 // Native regexp implementation.
6082 6088
6083 NativeRegExpMacroAssembler::Mode mode = 6089 NativeRegExpMacroAssembler::Mode mode =
6084 is_one_byte ? NativeRegExpMacroAssembler::LATIN1 6090 is_one_byte ? NativeRegExpMacroAssembler::LATIN1
6085 : NativeRegExpMacroAssembler::UC16; 6091 : NativeRegExpMacroAssembler::UC16;
6086 6092
6087 #if V8_TARGET_ARCH_IA32 6093 #if V8_TARGET_ARCH_IA32
6088 RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2, 6094 RegExpMacroAssemblerIA32 macro_assembler(isolate, zone, mode,
6089 zone); 6095 (data->capture_count + 1) * 2);
6090 #elif V8_TARGET_ARCH_X64 6096 #elif V8_TARGET_ARCH_X64
6091 RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2, 6097 RegExpMacroAssemblerX64 macro_assembler(isolate, zone, mode,
6092 zone); 6098 (data->capture_count + 1) * 2);
6093 #elif V8_TARGET_ARCH_ARM 6099 #elif V8_TARGET_ARCH_ARM
6094 RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2, 6100 RegExpMacroAssemblerARM macro_assembler(isolate, zone, mode,
6095 zone); 6101 (data->capture_count + 1) * 2);
6096 #elif V8_TARGET_ARCH_ARM64 6102 #elif V8_TARGET_ARCH_ARM64
6097 RegExpMacroAssemblerARM64 macro_assembler(mode, (data->capture_count + 1) * 2, 6103 RegExpMacroAssemblerARM64 macro_assembler(isolate, zone, mode,
6098 zone); 6104 (data->capture_count + 1) * 2);
6099 #elif V8_TARGET_ARCH_PPC 6105 #elif V8_TARGET_ARCH_PPC
6100 RegExpMacroAssemblerPPC macro_assembler(mode, (data->capture_count + 1) * 2, 6106 RegExpMacroAssemblerPPC macro_assembler(isolate, zone, mode,
6101 zone); 6107 (data->capture_count + 1) * 2);
6102 #elif V8_TARGET_ARCH_MIPS 6108 #elif V8_TARGET_ARCH_MIPS
6103 RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2, 6109 RegExpMacroAssemblerMIPS macro_assembler(isolate, zone, mode,
6104 zone); 6110 (data->capture_count + 1) * 2);
6105 #elif V8_TARGET_ARCH_MIPS64 6111 #elif V8_TARGET_ARCH_MIPS64
6106 RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2, 6112 RegExpMacroAssemblerMIPS macro_assembler(isolate, zone, mode,
6107 zone); 6113 (data->capture_count + 1) * 2);
6108 #elif V8_TARGET_ARCH_X87 6114 #elif V8_TARGET_ARCH_X87
6109 RegExpMacroAssemblerX87 macro_assembler(mode, (data->capture_count + 1) * 2, 6115 RegExpMacroAssemblerX87 macro_assembler(isolate, zone, mode,
6110 zone); 6116 (data->capture_count + 1) * 2);
6111 #else 6117 #else
6112 #error "Unsupported architecture" 6118 #error "Unsupported architecture"
6113 #endif 6119 #endif
6114 6120
6115 #else // V8_INTERPRETED_REGEXP 6121 #else // V8_INTERPRETED_REGEXP
6116 // Interpreted regexp implementation. 6122 // Interpreted regexp implementation.
6117 EmbeddedVector<byte, 1024> codes; 6123 EmbeddedVector<byte, 1024> codes;
6118 RegExpMacroAssemblerIrregexp macro_assembler(codes, zone); 6124 RegExpMacroAssemblerIrregexp macro_assembler(codes, zone);
6119 #endif // V8_INTERPRETED_REGEXP 6125 #endif // V8_INTERPRETED_REGEXP
6120 6126
(...skipping 26 matching lines...) Expand all
6147 Heap* heap = pattern->GetHeap(); 6153 Heap* heap = pattern->GetHeap();
6148 bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize; 6154 bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize;
6149 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && 6155 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit &&
6150 heap->isolate()->memory_allocator()->SizeExecutable() > 6156 heap->isolate()->memory_allocator()->SizeExecutable() >
6151 RegExpImpl::kRegExpExecutableMemoryLimit) { 6157 RegExpImpl::kRegExpExecutableMemoryLimit) {
6152 too_much = true; 6158 too_much = true;
6153 } 6159 }
6154 return too_much; 6160 return too_much;
6155 } 6161 }
6156 }} // namespace v8::internal 6162 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698