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

Unified Diff: runtime/vm/regexp_assembler.cc

Issue 765743003: Support use of external strings as inputs to LoadCodeUnitsInstr. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: safety Created 6 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/regexp_assembler.h ('k') | runtime/vm/regexp_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/regexp_assembler.cc
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc
index fa666ae3e55f77a89a0fefa3d1117b628693ded0..ac8f360ec1cff8403890386caef2839d2266155d 100644
--- a/runtime/vm/regexp_assembler.cc
+++ b/runtime/vm/regexp_assembler.cc
@@ -158,6 +158,7 @@ void IRRegExpMacroAssembler::InitializeLocals() {
match_end_index_ = Local(Symbols::match_end_index());
char_in_capture_ = Local(Symbols::char_in_capture());
char_in_match_ = Local(Symbols::char_in_match());
+ index_temp_ = Local(Symbols::index_temp());
result_ = Local(Symbols::result());
string_param_ = Parameter(Symbols::string_param(), 0);
@@ -944,8 +945,8 @@ void IRRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(
BlockLabel loop;
BindBlock(&loop);
- StoreLocal(char_in_capture_, CharacterAt(LoadLocal(capture_start_index_)));
- StoreLocal(char_in_match_, CharacterAt(LoadLocal(match_start_index_)));
+ StoreLocal(char_in_capture_, CharacterAt(capture_start_index_));
+ StoreLocal(char_in_match_, CharacterAt(match_start_index_));
BranchOrBacktrack(Comparison(kEQ,
LoadLocal(char_in_capture_),
@@ -1105,8 +1106,8 @@ void IRRegExpMacroAssembler::CheckNotBackReference(
BlockLabel loop;
BindBlock(&loop);
- StoreLocal(char_in_capture_, CharacterAt(LoadLocal(capture_start_index_)));
- StoreLocal(char_in_match_, CharacterAt(LoadLocal(match_start_index_)));
+ StoreLocal(char_in_capture_, CharacterAt(capture_start_index_));
+ StoreLocal(char_in_match_, CharacterAt(match_start_index_));
BranchOrBacktrack(Comparison(kNE,
LoadLocal(char_in_capture_),
@@ -1765,9 +1766,6 @@ void IRRegExpMacroAssembler::LoadCurrentCharacterUnchecked(
ASSERT(characters == 1 || characters == 2);
}
- // Bind the pattern as the load receiver.
- Value* pattern = BindLoadLocal(*string_param_);
-
// Calculate the addressed string index as:
// cp_offset + current_position_ + string_param_length_
// TODO(zerny): Avoid generating 'add' instance-calls here.
@@ -1779,30 +1777,53 @@ void IRRegExpMacroAssembler::LoadCurrentCharacterUnchecked(
PushArgument(Bind(Add(off_arg, pos_arg)));
PushArgumentInstr* len_arg =
PushArgument(BindLoadLocal(*string_param_length_));
- Value* index = Bind(Add(off_pos_arg, len_arg));
+ // Index is stored in a temporary local so that we can later load it safely.
+ StoreLocal(index_temp_, Bind(Add(off_pos_arg, len_arg)));
// Load and store the code units.
- Value* code_unit_value = LoadCodeUnitsAt(pattern, index, characters);
+ Value* code_unit_value = LoadCodeUnitsAt(index_temp_, characters);
StoreLocal(current_character_, code_unit_value);
PRINT(PushLocal(current_character_));
}
-Value* IRRegExpMacroAssembler::CharacterAt(Definition* index) {
- Value* pattern_val = BindLoadLocal(*string_param_);
- Value* index_val = Bind(index);
- return LoadCodeUnitsAt(pattern_val, index_val, 1);
+Value* IRRegExpMacroAssembler::CharacterAt(LocalVariable* index) {
+ return LoadCodeUnitsAt(index, 1);
}
-// Note: We can't replace pattern with a load-local of string_param_
-// because we need to maintain the stack discipline in unoptimized code.
-Value* IRRegExpMacroAssembler::LoadCodeUnitsAt(Value* pattern,
- Value* index,
+Value* IRRegExpMacroAssembler::LoadCodeUnitsAt(LocalVariable* index,
intptr_t characters) {
+ // Bind the pattern as the load receiver.
+ Value* pattern_val = BindLoadLocal(*string_param_);
+ if (RawObject::IsExternalStringClassId(specialization_cid_)) {
+ // The data of an external string is stored through two indirections.
+ intptr_t external_offset;
+ intptr_t data_offset;
+ if (specialization_cid_ == kExternalOneByteStringCid) {
+ external_offset = ExternalOneByteString::external_data_offset();
+ data_offset = RawExternalOneByteString::ExternalData::data_offset();
+ } else if (specialization_cid_ == kExternalTwoByteStringCid) {
+ external_offset = ExternalTwoByteString::external_data_offset();
+ data_offset = RawExternalTwoByteString::ExternalData::data_offset();
+ } else {
+ UNREACHABLE();
+ }
+ // This pushes untagged values on the stack which are immediately consumed:
+ // the first value is consumed to obtain the second value which is consumed
+ // by LoadCodeUnitsAtInstr below.
+ Value* external_val =
+ Bind(new(I) LoadUntaggedInstr(pattern_val, external_offset));
+ pattern_val =
+ Bind(new(I) LoadUntaggedInstr(external_val, data_offset));
+ }
+
+ // Here pattern_val might be untagged so this must not trigger a GC.
+ Value* index_val = BindLoadLocal(*index);
+
return Bind(new(I) LoadCodeUnitsInstr(
- pattern,
- index,
+ pattern_val,
+ index_val,
characters,
specialization_cid_,
Scanner::kNoSourcePos));
« no previous file with comments | « runtime/vm/regexp_assembler.h ('k') | runtime/vm/regexp_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698