OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/regexp.h" | 5 #include "vm/regexp.h" |
6 | 6 |
7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
8 #include "vm/regexp_assembler.h" | 8 #include "vm/regexp_assembler.h" |
9 #include "vm/regexp_assembler_bytecode.h" | 9 #include "vm/regexp_assembler_bytecode.h" |
10 #include "vm/regexp_assembler_ir.h" | 10 #include "vm/regexp_assembler_ir.h" |
11 #include "vm/regexp_ast.h" | 11 #include "vm/regexp_ast.h" |
12 #include "vm/unibrow-inl.h" | 12 #include "vm/unibrow-inl.h" |
13 #include "vm/unicode.h" | 13 #include "vm/unicode.h" |
14 #include "vm/symbols.h" | 14 #include "vm/symbols.h" |
15 #include "vm/thread.h" | 15 #include "vm/thread.h" |
16 | 16 |
17 #define Z (zone()) | 17 #define Z (zone()) |
18 | 18 |
19 namespace dart { | 19 namespace dart { |
20 | 20 |
21 DECLARE_FLAG(bool, trace_irregexp); | |
22 | |
23 // Default to generating optimized regexp code. | 21 // Default to generating optimized regexp code. |
24 static const bool kRegexpOptimization = true; | 22 static const bool kRegexpOptimization = true; |
25 | 23 |
26 // More makes code generation slower, less makes V8 benchmark score lower. | 24 // More makes code generation slower, less makes V8 benchmark score lower. |
27 static const intptr_t kMaxLookaheadForBoyerMoore = 8; | 25 static const intptr_t kMaxLookaheadForBoyerMoore = 8; |
28 | 26 |
29 ContainedInLattice AddRange(ContainedInLattice containment, | 27 ContainedInLattice AddRange(ContainedInLattice containment, |
30 const intptr_t* ranges, | 28 const intptr_t* ranges, |
31 intptr_t ranges_length, | 29 intptr_t ranges_length, |
32 Interval new_range) { | 30 Interval new_range) { |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 intptr_t total_samples_; | 289 intptr_t total_samples_; |
292 }; | 290 }; |
293 | 291 |
294 | 292 |
295 class RegExpCompiler : public ValueObject { | 293 class RegExpCompiler : public ValueObject { |
296 public: | 294 public: |
297 RegExpCompiler(intptr_t capture_count, bool ignore_case, bool is_one_byte); | 295 RegExpCompiler(intptr_t capture_count, bool ignore_case, bool is_one_byte); |
298 | 296 |
299 intptr_t AllocateRegister() { return next_register_++; } | 297 intptr_t AllocateRegister() { return next_register_++; } |
300 | 298 |
| 299 #if !defined(DART_PRECOMPILED_RUNTIME) |
301 RegExpEngine::CompilationResult Assemble(IRRegExpMacroAssembler* assembler, | 300 RegExpEngine::CompilationResult Assemble(IRRegExpMacroAssembler* assembler, |
302 RegExpNode* start, | 301 RegExpNode* start, |
303 intptr_t capture_count, | 302 intptr_t capture_count, |
304 const String& pattern); | 303 const String& pattern); |
| 304 #endif |
305 | 305 |
306 RegExpEngine::CompilationResult Assemble( | 306 RegExpEngine::CompilationResult Assemble( |
307 BytecodeRegExpMacroAssembler* assembler, | 307 BytecodeRegExpMacroAssembler* assembler, |
308 RegExpNode* start, | 308 RegExpNode* start, |
309 intptr_t capture_count, | 309 intptr_t capture_count, |
310 const String& pattern); | 310 const String& pattern); |
311 | 311 |
312 inline void AddWork(RegExpNode* node) { work_list_->Add(node); } | 312 inline void AddWork(RegExpNode* node) { work_list_->Add(node); } |
313 | 313 |
314 static const intptr_t kImplementationOffset = 0; | 314 static const intptr_t kImplementationOffset = 0; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 recursion_depth_(0), | 380 recursion_depth_(0), |
381 ignore_case_(ignore_case), | 381 ignore_case_(ignore_case), |
382 is_one_byte_(is_one_byte), | 382 is_one_byte_(is_one_byte), |
383 reg_exp_too_big_(false), | 383 reg_exp_too_big_(false), |
384 current_expansion_factor_(1), | 384 current_expansion_factor_(1), |
385 zone_(Thread::Current()->zone()) { | 385 zone_(Thread::Current()->zone()) { |
386 accept_ = new (Z) EndNode(EndNode::ACCEPT, Z); | 386 accept_ = new (Z) EndNode(EndNode::ACCEPT, Z); |
387 } | 387 } |
388 | 388 |
389 | 389 |
| 390 #if !defined(DART_PRECOMPILED_RUNTIME) |
390 RegExpEngine::CompilationResult RegExpCompiler::Assemble( | 391 RegExpEngine::CompilationResult RegExpCompiler::Assemble( |
391 IRRegExpMacroAssembler* macro_assembler, | 392 IRRegExpMacroAssembler* macro_assembler, |
392 RegExpNode* start, | 393 RegExpNode* start, |
393 intptr_t capture_count, | 394 intptr_t capture_count, |
394 const String& pattern) { | 395 const String& pattern) { |
395 macro_assembler->set_slow_safe(false /* use_slow_safe_regexp_compiler */); | 396 macro_assembler->set_slow_safe(false /* use_slow_safe_regexp_compiler */); |
396 macro_assembler_ = macro_assembler; | 397 macro_assembler_ = macro_assembler; |
397 | 398 |
398 ZoneGrowableArray<RegExpNode*> work_list(0); | 399 ZoneGrowableArray<RegExpNode*> work_list(0); |
399 work_list_ = &work_list; | 400 work_list_ = &work_list; |
400 BlockLabel fail; | 401 BlockLabel fail; |
401 macro_assembler_->PushBacktrack(&fail); | 402 macro_assembler_->PushBacktrack(&fail); |
402 Trace new_trace; | 403 Trace new_trace; |
403 start->Emit(this, &new_trace); | 404 start->Emit(this, &new_trace); |
404 macro_assembler_->BindBlock(&fail); | 405 macro_assembler_->BindBlock(&fail); |
405 macro_assembler_->Fail(); | 406 macro_assembler_->Fail(); |
406 while (!work_list.is_empty()) { | 407 while (!work_list.is_empty()) { |
407 work_list.RemoveLast()->Emit(this, &new_trace); | 408 work_list.RemoveLast()->Emit(this, &new_trace); |
408 } | 409 } |
409 if (reg_exp_too_big_) return IrregexpRegExpTooBig(); | 410 if (reg_exp_too_big_) return IrregexpRegExpTooBig(); |
410 | 411 |
411 macro_assembler->GenerateBacktrackBlock(); | 412 macro_assembler->GenerateBacktrackBlock(); |
412 macro_assembler->FinalizeRegistersArray(); | 413 macro_assembler->FinalizeRegistersArray(); |
413 | 414 |
414 return RegExpEngine::CompilationResult( | 415 return RegExpEngine::CompilationResult( |
415 macro_assembler->backtrack_goto(), macro_assembler->graph_entry(), | 416 macro_assembler->backtrack_goto(), macro_assembler->graph_entry(), |
416 macro_assembler->num_blocks(), macro_assembler->num_stack_locals(), | 417 macro_assembler->num_blocks(), macro_assembler->num_stack_locals(), |
417 next_register_); | 418 next_register_); |
418 } | 419 } |
| 420 #endif |
419 | 421 |
420 | 422 |
421 RegExpEngine::CompilationResult RegExpCompiler::Assemble( | 423 RegExpEngine::CompilationResult RegExpCompiler::Assemble( |
422 BytecodeRegExpMacroAssembler* macro_assembler, | 424 BytecodeRegExpMacroAssembler* macro_assembler, |
423 RegExpNode* start, | 425 RegExpNode* start, |
424 intptr_t capture_count, | 426 intptr_t capture_count, |
425 const String& pattern) { | 427 const String& pattern) { |
426 macro_assembler->set_slow_safe(false /* use_slow_safe_regexp_compiler */); | 428 macro_assembler->set_slow_safe(false /* use_slow_safe_regexp_compiler */); |
427 macro_assembler_ = macro_assembler; | 429 macro_assembler_ = macro_assembler; |
428 | 430 |
(...skipping 4381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4810 if (offset >= bm->length()) { | 4812 if (offset >= bm->length()) { |
4811 if (initial_offset == 0) set_bm_info(not_at_start, bm); | 4813 if (initial_offset == 0) set_bm_info(not_at_start, bm); |
4812 return; | 4814 return; |
4813 } | 4815 } |
4814 on_success()->FillInBMInfo(offset, budget - 1, bm, | 4816 on_success()->FillInBMInfo(offset, budget - 1, bm, |
4815 true); // Not at start after a text node. | 4817 true); // Not at start after a text node. |
4816 if (initial_offset == 0) set_bm_info(not_at_start, bm); | 4818 if (initial_offset == 0) set_bm_info(not_at_start, bm); |
4817 } | 4819 } |
4818 | 4820 |
4819 | 4821 |
| 4822 #if !defined(DART_PRECOMPILED_RUNTIME) |
4820 RegExpEngine::CompilationResult RegExpEngine::CompileIR( | 4823 RegExpEngine::CompilationResult RegExpEngine::CompileIR( |
4821 RegExpCompileData* data, | 4824 RegExpCompileData* data, |
4822 const ParsedFunction* parsed_function, | 4825 const ParsedFunction* parsed_function, |
4823 const ZoneGrowableArray<const ICData*>& ic_data_array, | 4826 const ZoneGrowableArray<const ICData*>& ic_data_array, |
4824 intptr_t osr_id) { | 4827 intptr_t osr_id) { |
4825 ASSERT(!FLAG_interpret_irregexp); | 4828 ASSERT(!FLAG_interpret_irregexp); |
4826 Zone* zone = Thread::Current()->zone(); | 4829 Zone* zone = Thread::Current()->zone(); |
4827 | 4830 |
4828 const Function& function = parsed_function->function(); | 4831 const Function& function = parsed_function->function(); |
4829 const intptr_t specialization_cid = function.string_specialization_cid(); | 4832 const intptr_t specialization_cid = function.string_specialization_cid(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4918 | 4921 |
4919 RegExpEngine::CompilationResult result = | 4922 RegExpEngine::CompilationResult result = |
4920 compiler.Assemble(macro_assembler, node, data->capture_count, pattern); | 4923 compiler.Assemble(macro_assembler, node, data->capture_count, pattern); |
4921 | 4924 |
4922 if (FLAG_trace_irregexp) { | 4925 if (FLAG_trace_irregexp) { |
4923 macro_assembler->PrintBlocks(); | 4926 macro_assembler->PrintBlocks(); |
4924 } | 4927 } |
4925 | 4928 |
4926 return result; | 4929 return result; |
4927 } | 4930 } |
| 4931 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
4928 | 4932 |
4929 | 4933 |
4930 RegExpEngine::CompilationResult RegExpEngine::CompileBytecode( | 4934 RegExpEngine::CompilationResult RegExpEngine::CompileBytecode( |
4931 RegExpCompileData* data, | 4935 RegExpCompileData* data, |
4932 const RegExp& regexp, | 4936 const RegExp& regexp, |
4933 bool is_one_byte, | 4937 bool is_one_byte, |
4934 bool is_sticky, | 4938 bool is_sticky, |
4935 Zone* zone) { | 4939 Zone* zone) { |
4936 ASSERT(FLAG_interpret_irregexp); | 4940 ASSERT(FLAG_interpret_irregexp); |
4937 const String& pattern = String::Handle(zone, regexp.pattern()); | 4941 const String& pattern = String::Handle(zone, regexp.pattern()); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5111 CreateSpecializedFunction(thread, zone, regexp, cid, /*sticky=*/true, | 5115 CreateSpecializedFunction(thread, zone, regexp, cid, /*sticky=*/true, |
5112 owner); | 5116 owner); |
5113 } | 5117 } |
5114 } | 5118 } |
5115 | 5119 |
5116 return regexp.raw(); | 5120 return regexp.raw(); |
5117 } | 5121 } |
5118 | 5122 |
5119 | 5123 |
5120 } // namespace dart | 5124 } // namespace dart |
OLD | NEW |