| 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 | 
|---|