| 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_assembler.h" | 5 #include "vm/regexp_assembler.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| 11 #include "vm/il_printer.h" | 11 #include "vm/il_printer.h" |
| 12 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 13 #include "vm/regexp.h" | 13 #include "vm/regexp.h" |
| 14 #include "vm/resolver.h" | 14 #include "vm/resolver.h" |
| 15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
| 16 #include "vm/unibrow-inl.h" | 16 #include "vm/unibrow-inl.h" |
| 17 #include "vm/unicode.h" | 17 #include "vm/unicode.h" |
| 18 | 18 |
| 19 #define I isolate() | 19 #define Z zone() |
| 20 | 20 |
| 21 // Debugging output macros. TAG() is called at the head of each interesting | 21 // Debugging output macros. TAG() is called at the head of each interesting |
| 22 // function and prints its name during execution if irregexp tracing is enabled. | 22 // function and prints its name during execution if irregexp tracing is enabled. |
| 23 #define TAG() if (FLAG_trace_irregexp) { TAG_(); } | 23 #define TAG() if (FLAG_trace_irregexp) { TAG_(); } |
| 24 #define TAG_() \ | 24 #define TAG_() \ |
| 25 Print(PushArgument( \ | 25 Print(PushArgument( \ |
| 26 Bind(new(I) ConstantInstr(String::ZoneHandle(I, String::Concat( \ | 26 Bind(new(Z) ConstantInstr(String::ZoneHandle(Z, String::Concat( \ |
| 27 String::Handle(String::New("TAG: ")), \ | 27 String::Handle(String::New("TAG: ")), \ |
| 28 String::Handle(String::New(__FUNCTION__)), Heap::kOld)))))); | 28 String::Handle(String::New(__FUNCTION__)), Heap::kOld)))))); |
| 29 | 29 |
| 30 #define PRINT(arg) if (FLAG_trace_irregexp) { Print(arg); } | 30 #define PRINT(arg) if (FLAG_trace_irregexp) { Print(arg); } |
| 31 | 31 |
| 32 namespace dart { | 32 namespace dart { |
| 33 | 33 |
| 34 DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps"); | 34 DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps"); |
| 35 | 35 |
| 36 | 36 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 61 * Results are returned though an array of capture indices, stored at | 61 * Results are returned though an array of capture indices, stored at |
| 62 * matches_param_. A null array specifies a failure to match. The match indices | 62 * matches_param_. A null array specifies a failure to match. The match indices |
| 63 * [start_inclusive, end_exclusive] for capture group i are stored at positions | 63 * [start_inclusive, end_exclusive] for capture group i are stored at positions |
| 64 * matches_param_[i * 2] and matches_param_[i * 2 + 1], respectively. Match | 64 * matches_param_[i * 2] and matches_param_[i * 2 + 1], respectively. Match |
| 65 * indices of -1 denote non-matched groups. Note that we store these indices | 65 * indices of -1 denote non-matched groups. Note that we store these indices |
| 66 * as a negative offset from the end of the string in registers_array_ | 66 * as a negative offset from the end of the string in registers_array_ |
| 67 * during processing, and convert them to standard indexes when copying them | 67 * during processing, and convert them to standard indexes when copying them |
| 68 * to matches_param_ on successful match. | 68 * to matches_param_ on successful match. |
| 69 */ | 69 */ |
| 70 | 70 |
| 71 RegExpMacroAssembler::RegExpMacroAssembler(Isolate* isolate) | 71 RegExpMacroAssembler::RegExpMacroAssembler(Zone* zone) |
| 72 : slow_safe_compiler_(false), | 72 : slow_safe_compiler_(false), |
| 73 global_mode_(NOT_GLOBAL), | 73 global_mode_(NOT_GLOBAL), |
| 74 isolate_(isolate) { | 74 zone_(zone) { |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 RegExpMacroAssembler::~RegExpMacroAssembler() { | 78 RegExpMacroAssembler::~RegExpMacroAssembler() { |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 IRRegExpMacroAssembler::IRRegExpMacroAssembler( | 82 IRRegExpMacroAssembler::IRRegExpMacroAssembler( |
| 83 intptr_t specialization_cid, | 83 intptr_t specialization_cid, |
| 84 intptr_t capture_count, | 84 intptr_t capture_count, |
| 85 const ParsedFunction* parsed_function, | 85 const ParsedFunction* parsed_function, |
| 86 const ZoneGrowableArray<const ICData*>& ic_data_array, | 86 const ZoneGrowableArray<const ICData*>& ic_data_array, |
| 87 Isolate* isolate) | 87 Zone* zone) |
| 88 : RegExpMacroAssembler(isolate), | 88 : RegExpMacroAssembler(zone), |
| 89 specialization_cid_(specialization_cid), | 89 specialization_cid_(specialization_cid), |
| 90 parsed_function_(parsed_function), | 90 parsed_function_(parsed_function), |
| 91 ic_data_array_(ic_data_array), | 91 ic_data_array_(ic_data_array), |
| 92 current_instruction_(NULL), | 92 current_instruction_(NULL), |
| 93 stack_(NULL), | 93 stack_(NULL), |
| 94 stack_pointer_(NULL), | 94 stack_pointer_(NULL), |
| 95 current_character_(NULL), | 95 current_character_(NULL), |
| 96 current_position_(NULL), | 96 current_position_(NULL), |
| 97 string_param_(NULL), | 97 string_param_(NULL), |
| 98 string_param_length_(NULL), | 98 string_param_length_(NULL), |
| 99 start_index_param_(NULL), | 99 start_index_param_(NULL), |
| 100 registers_count_(0), | 100 registers_count_(0), |
| 101 saved_registers_count_((capture_count + 1) * 2), | 101 saved_registers_count_((capture_count + 1) * 2), |
| 102 stack_array_cell_(Array::ZoneHandle(isolate, Array::New(1, Heap::kOld))), | 102 stack_array_cell_(Array::ZoneHandle(zone, Array::New(1, Heap::kOld))), |
| 103 // The registers array is allocated at a fixed size after assembly. | 103 // The registers array is allocated at a fixed size after assembly. |
| 104 registers_array_(TypedData::ZoneHandle(isolate, TypedData::null())) { | 104 registers_array_(TypedData::ZoneHandle(zone, TypedData::null())) { |
| 105 switch (specialization_cid) { | 105 switch (specialization_cid) { |
| 106 case kOneByteStringCid: | 106 case kOneByteStringCid: |
| 107 case kExternalOneByteStringCid: mode_ = ASCII; break; | 107 case kExternalOneByteStringCid: mode_ = ASCII; break; |
| 108 case kTwoByteStringCid: | 108 case kTwoByteStringCid: |
| 109 case kExternalTwoByteStringCid: mode_ = UC16; break; | 109 case kExternalTwoByteStringCid: mode_ = UC16; break; |
| 110 default: UNREACHABLE(); | 110 default: UNREACHABLE(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 InitializeLocals(); | 113 InitializeLocals(); |
| 114 | 114 |
| 115 // Allocate an initial stack backing of the minimum stack size. The stack | 115 // Allocate an initial stack backing of the minimum stack size. The stack |
| 116 // backing is indirectly referred to so we can reuse it on subsequent matches | 116 // backing is indirectly referred to so we can reuse it on subsequent matches |
| 117 // even in the case where the backing has been enlarged and thus reallocated. | 117 // even in the case where the backing has been enlarged and thus reallocated. |
| 118 stack_array_cell_.SetAt(0, TypedData::Handle(isolate, | 118 stack_array_cell_.SetAt(0, TypedData::Handle(zone, |
| 119 TypedData::New(kTypedDataInt32ArrayCid, kMinStackSize / 4, Heap::kOld))); | 119 TypedData::New(kTypedDataInt32ArrayCid, kMinStackSize / 4, Heap::kOld))); |
| 120 | 120 |
| 121 // Create and generate all preset blocks. | 121 // Create and generate all preset blocks. |
| 122 entry_block_ = | 122 entry_block_ = |
| 123 new(isolate) GraphEntryInstr( | 123 new(zone) GraphEntryInstr( |
| 124 *parsed_function_, | 124 *parsed_function_, |
| 125 new(isolate) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex), | 125 new(zone) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex), |
| 126 Isolate::kNoDeoptId); | 126 Isolate::kNoDeoptId); |
| 127 start_block_ = | 127 start_block_ = |
| 128 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); | 128 new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); |
| 129 success_block_ = | 129 success_block_ = |
| 130 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); | 130 new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); |
| 131 backtrack_block_ = | 131 backtrack_block_ = |
| 132 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); | 132 new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); |
| 133 exit_block_ = | 133 exit_block_ = |
| 134 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); | 134 new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); |
| 135 | 135 |
| 136 GenerateEntryBlock(); | 136 GenerateEntryBlock(); |
| 137 GenerateSuccessBlock(); | 137 GenerateSuccessBlock(); |
| 138 GenerateExitBlock(); | 138 GenerateExitBlock(); |
| 139 | 139 |
| 140 blocks_.Add(entry_block_); | 140 blocks_.Add(entry_block_); |
| 141 blocks_.Add(entry_block_->normal_entry()); | 141 blocks_.Add(entry_block_->normal_entry()); |
| 142 blocks_.Add(start_block_); | 142 blocks_.Add(start_block_); |
| 143 blocks_.Add(success_block_); | 143 blocks_.Add(success_block_); |
| 144 blocks_.Add(backtrack_block_); | 144 blocks_.Add(backtrack_block_); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 194 |
| 195 // Store (start_index - string.length) as the current position (since it's a | 195 // Store (start_index - string.length) as the current position (since it's a |
| 196 // negative offset from the end of the string). | 196 // negative offset from the end of the string). |
| 197 PushArgumentInstr* start_index_push = PushLocal(start_index_param_); | 197 PushArgumentInstr* start_index_push = PushLocal(start_index_param_); |
| 198 PushArgumentInstr* length_push = PushLocal(string_param_length_); | 198 PushArgumentInstr* length_push = PushLocal(string_param_length_); |
| 199 | 199 |
| 200 StoreLocal(current_position_, Bind(Sub(start_index_push, length_push))); | 200 StoreLocal(current_position_, Bind(Sub(start_index_push, length_push))); |
| 201 | 201 |
| 202 // Generate a local list variable to represent "registers" and | 202 // Generate a local list variable to represent "registers" and |
| 203 // initialize capture registers (others remain garbage). | 203 // initialize capture registers (others remain garbage). |
| 204 StoreLocal(registers_, Bind(new(I) ConstantInstr(registers_array_))); | 204 StoreLocal(registers_, Bind(new(Z) ConstantInstr(registers_array_))); |
| 205 ClearRegisters(0, saved_registers_count_ - 1); | 205 ClearRegisters(0, saved_registers_count_ - 1); |
| 206 | 206 |
| 207 // Generate a local list variable to represent the backtracking stack. | 207 // Generate a local list variable to represent the backtracking stack. |
| 208 PushArgumentInstr* stack_cell_push = | 208 PushArgumentInstr* stack_cell_push = |
| 209 PushArgument(Bind(new(I) ConstantInstr(stack_array_cell_))); | 209 PushArgument(Bind(new(Z) ConstantInstr(stack_array_cell_))); |
| 210 StoreLocal(stack_, Bind(InstanceCall( | 210 StoreLocal(stack_, Bind(InstanceCall( |
| 211 InstanceCallDescriptor::FromToken(Token::kINDEX), | 211 InstanceCallDescriptor::FromToken(Token::kINDEX), |
| 212 stack_cell_push, | 212 stack_cell_push, |
| 213 PushArgument(Bind(Uint64Constant(0)))))); | 213 PushArgument(Bind(Uint64Constant(0)))))); |
| 214 StoreLocal(stack_pointer_, Bind(Int64Constant(-1))); | 214 StoreLocal(stack_pointer_, Bind(Int64Constant(-1))); |
| 215 | 215 |
| 216 // Jump to the start block. | 216 // Jump to the start block. |
| 217 current_instruction_->Goto(start_block_); | 217 current_instruction_->Goto(start_block_); |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 void IRRegExpMacroAssembler::GenerateBacktrackBlock() { | 221 void IRRegExpMacroAssembler::GenerateBacktrackBlock() { |
| 222 set_current_instruction(backtrack_block_); | 222 set_current_instruction(backtrack_block_); |
| 223 TAG(); | 223 TAG(); |
| 224 CheckPreemption(); | 224 CheckPreemption(); |
| 225 | 225 |
| 226 const intptr_t entries_count = entry_block_->indirect_entries().length(); | 226 const intptr_t entries_count = entry_block_->indirect_entries().length(); |
| 227 | 227 |
| 228 TypedData& offsets = TypedData::ZoneHandle(I, | 228 TypedData& offsets = TypedData::ZoneHandle(Z, |
| 229 TypedData::New(kTypedDataInt32ArrayCid, entries_count, Heap::kOld)); | 229 TypedData::New(kTypedDataInt32ArrayCid, entries_count, Heap::kOld)); |
| 230 | 230 |
| 231 PushArgumentInstr* block_offsets_push = | 231 PushArgumentInstr* block_offsets_push = |
| 232 PushArgument(Bind(new(I) ConstantInstr(offsets))); | 232 PushArgument(Bind(new(Z) ConstantInstr(offsets))); |
| 233 PushArgumentInstr* block_id_push = PushArgument(Bind(PopStack())); | 233 PushArgumentInstr* block_id_push = PushArgument(Bind(PopStack())); |
| 234 | 234 |
| 235 Value* offset_value = | 235 Value* offset_value = |
| 236 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX), | 236 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX), |
| 237 block_offsets_push, | 237 block_offsets_push, |
| 238 block_id_push)); | 238 block_id_push)); |
| 239 | 239 |
| 240 backtrack_goto_ = new(I) IndirectGotoInstr(&offsets, offset_value); | 240 backtrack_goto_ = new(Z) IndirectGotoInstr(&offsets, offset_value); |
| 241 CloseBlockWith(backtrack_goto_); | 241 CloseBlockWith(backtrack_goto_); |
| 242 | 242 |
| 243 // Add an edge from the "indirect" goto to each of the targets. | 243 // Add an edge from the "indirect" goto to each of the targets. |
| 244 for (intptr_t j = 0; j < entries_count; j++) { | 244 for (intptr_t j = 0; j < entries_count; j++) { |
| 245 backtrack_goto_->AddSuccessor( | 245 backtrack_goto_->AddSuccessor( |
| 246 TargetWithJoinGoto(entry_block_->indirect_entries().At(j))); | 246 TargetWithJoinGoto(entry_block_->indirect_entries().At(j))); |
| 247 } | 247 } |
| 248 } | 248 } |
| 249 | 249 |
| 250 | 250 |
| 251 void IRRegExpMacroAssembler::GenerateSuccessBlock() { | 251 void IRRegExpMacroAssembler::GenerateSuccessBlock() { |
| 252 set_current_instruction(success_block_); | 252 set_current_instruction(success_block_); |
| 253 TAG(); | 253 TAG(); |
| 254 | 254 |
| 255 Value* type = Bind(new(I) ConstantInstr( | 255 Value* type = Bind(new(Z) ConstantInstr( |
| 256 TypeArguments::ZoneHandle(I, TypeArguments::null()))); | 256 TypeArguments::ZoneHandle(Z, TypeArguments::null()))); |
| 257 Value* length = Bind(Uint64Constant(saved_registers_count_)); | 257 Value* length = Bind(Uint64Constant(saved_registers_count_)); |
| 258 Value* array = Bind(new(I) CreateArrayInstr(kNoSourcePos, type, length)); | 258 Value* array = Bind(new(Z) CreateArrayInstr(kNoSourcePos, type, length)); |
| 259 StoreLocal(result_, array); | 259 StoreLocal(result_, array); |
| 260 | 260 |
| 261 // Store captured offsets in the `matches` parameter. | 261 // Store captured offsets in the `matches` parameter. |
| 262 for (intptr_t i = 0; i < saved_registers_count_; i++) { | 262 for (intptr_t i = 0; i < saved_registers_count_; i++) { |
| 263 PushArgumentInstr* matches_push = PushLocal(result_); | 263 PushArgumentInstr* matches_push = PushLocal(result_); |
| 264 PushArgumentInstr* index_push = PushArgument(Bind(Uint64Constant(i))); | 264 PushArgumentInstr* index_push = PushArgument(Bind(Uint64Constant(i))); |
| 265 | 265 |
| 266 // Convert negative offsets from the end of the string to string indices. | 266 // Convert negative offsets from the end of the string to string indices. |
| 267 // TODO(zerny): use positive offsets from the get-go. | 267 // TODO(zerny): use positive offsets from the get-go. |
| 268 PushArgumentInstr* offset_push = PushArgument(LoadRegister(i)); | 268 PushArgumentInstr* offset_push = PushArgument(LoadRegister(i)); |
| 269 PushArgumentInstr* len_push = PushLocal(string_param_length_); | 269 PushArgumentInstr* len_push = PushLocal(string_param_length_); |
| 270 PushArgumentInstr* value_push = | 270 PushArgumentInstr* value_push = |
| 271 PushArgument(Bind(Add(offset_push, len_push))); | 271 PushArgument(Bind(Add(offset_push, len_push))); |
| 272 | 272 |
| 273 Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX), | 273 Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX), |
| 274 matches_push, | 274 matches_push, |
| 275 index_push, | 275 index_push, |
| 276 value_push)); | 276 value_push)); |
| 277 } | 277 } |
| 278 | 278 |
| 279 // Print the result if tracing. | 279 // Print the result if tracing. |
| 280 PRINT(PushLocal(result_)); | 280 PRINT(PushLocal(result_)); |
| 281 | 281 |
| 282 // Return true on success. | 282 // Return true on success. |
| 283 AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); | 283 AppendInstruction(new(Z) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); |
| 284 } | 284 } |
| 285 | 285 |
| 286 | 286 |
| 287 void IRRegExpMacroAssembler::GenerateExitBlock() { | 287 void IRRegExpMacroAssembler::GenerateExitBlock() { |
| 288 set_current_instruction(exit_block_); | 288 set_current_instruction(exit_block_); |
| 289 TAG(); | 289 TAG(); |
| 290 | 290 |
| 291 // Return false on failure. | 291 // Return false on failure. |
| 292 AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); | 292 AppendInstruction(new(Z) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); |
| 293 } | 293 } |
| 294 | 294 |
| 295 | 295 |
| 296 void IRRegExpMacroAssembler::FinalizeRegistersArray() { | 296 void IRRegExpMacroAssembler::FinalizeRegistersArray() { |
| 297 ASSERT(registers_count_ >= saved_registers_count_); | 297 ASSERT(registers_count_ >= saved_registers_count_); |
| 298 registers_array_ = | 298 registers_array_ = |
| 299 TypedData::New(kTypedDataInt32ArrayCid, registers_count_, Heap::kOld); | 299 TypedData::New(kTypedDataInt32ArrayCid, registers_count_, Heap::kOld); |
| 300 } | 300 } |
| 301 | 301 |
| 302 | 302 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 314 #endif | 314 #endif |
| 315 bool IRRegExpMacroAssembler::CanReadUnaligned() { | 315 bool IRRegExpMacroAssembler::CanReadUnaligned() { |
| 316 return kEnableUnalignedAccesses && !slow_safe(); | 316 return kEnableUnalignedAccesses && !slow_safe(); |
| 317 } | 317 } |
| 318 | 318 |
| 319 | 319 |
| 320 RawArray* IRRegExpMacroAssembler::Execute( | 320 RawArray* IRRegExpMacroAssembler::Execute( |
| 321 const Function& function, | 321 const Function& function, |
| 322 const String& input, | 322 const String& input, |
| 323 const Smi& start_offset, | 323 const Smi& start_offset, |
| 324 Isolate* isolate) { | 324 Zone* zone) { |
| 325 // Create the argument list. | 325 // Create the argument list. |
| 326 const Array& args = Array::Handle(Array::New(2)); | 326 const Array& args = Array::Handle(Array::New(2)); |
| 327 args.SetAt(0, input); | 327 args.SetAt(0, input); |
| 328 args.SetAt(1, start_offset); | 328 args.SetAt(1, start_offset); |
| 329 | 329 |
| 330 // And finally call the generated code. | 330 // And finally call the generated code. |
| 331 | 331 |
| 332 const Object& retval = | 332 const Object& retval = |
| 333 Object::Handle(isolate, DartEntry::InvokeFunction(function, args)); | 333 Object::Handle(zone, DartEntry::InvokeFunction(function, args)); |
| 334 if (retval.IsError()) { | 334 if (retval.IsError()) { |
| 335 const Error& error = Error::Cast(retval); | 335 const Error& error = Error::Cast(retval); |
| 336 OS::Print("%s\n", error.ToErrorCString()); | 336 OS::Print("%s\n", error.ToErrorCString()); |
| 337 // Should never happen. | 337 // Should never happen. |
| 338 UNREACHABLE(); | 338 UNREACHABLE(); |
| 339 } | 339 } |
| 340 | 340 |
| 341 if (retval.IsNull()) { | 341 if (retval.IsNull()) { |
| 342 return Array::null(); | 342 return Array::null(); |
| 343 } | 343 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 } | 377 } |
| 378 } | 378 } |
| 379 return Bool::True().raw(); | 379 return Bool::True().raw(); |
| 380 } | 380 } |
| 381 | 381 |
| 382 | 382 |
| 383 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name, | 383 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name, |
| 384 intptr_t index) const { | 384 intptr_t index) const { |
| 385 const Type& local_type = Type::ZoneHandle(I, Type::DynamicType()); | 385 const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 386 LocalVariable* local = | 386 LocalVariable* local = |
| 387 new(I) LocalVariable(kNoSourcePos, name, local_type); | 387 new(Z) LocalVariable(kNoSourcePos, name, local_type); |
| 388 | 388 |
| 389 intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index; | 389 intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index; |
| 390 local->set_index(param_frame_index); | 390 local->set_index(param_frame_index); |
| 391 | 391 |
| 392 return local; | 392 return local; |
| 393 } | 393 } |
| 394 | 394 |
| 395 | 395 |
| 396 LocalVariable* IRRegExpMacroAssembler::Local(const String& name) { | 396 LocalVariable* IRRegExpMacroAssembler::Local(const String& name) { |
| 397 const Type& local_type = Type::ZoneHandle(I, Type::DynamicType()); | 397 const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 398 LocalVariable* local = | 398 LocalVariable* local = |
| 399 new(I) LocalVariable(kNoSourcePos, name, local_type); | 399 new(Z) LocalVariable(kNoSourcePos, name, local_type); |
| 400 local->set_index(GetNextLocalIndex()); | 400 local->set_index(GetNextLocalIndex()); |
| 401 | 401 |
| 402 return local; | 402 return local; |
| 403 } | 403 } |
| 404 | 404 |
| 405 | 405 |
| 406 ConstantInstr* IRRegExpMacroAssembler::Int64Constant(int64_t value) const { | 406 ConstantInstr* IRRegExpMacroAssembler::Int64Constant(int64_t value) const { |
| 407 return new(I) ConstantInstr( | 407 return new(Z) ConstantInstr( |
| 408 Integer::ZoneHandle(I, Integer::New(value, Heap::kOld))); | 408 Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld))); |
| 409 } | 409 } |
| 410 | 410 |
| 411 | 411 |
| 412 ConstantInstr* IRRegExpMacroAssembler::Uint64Constant(uint64_t value) const { | 412 ConstantInstr* IRRegExpMacroAssembler::Uint64Constant(uint64_t value) const { |
| 413 return new(I) ConstantInstr( | 413 return new(Z) ConstantInstr( |
| 414 Integer::ZoneHandle(I, Integer::NewFromUint64(value, Heap::kOld))); | 414 Integer::ZoneHandle(Z, Integer::NewFromUint64(value, Heap::kOld))); |
| 415 } | 415 } |
| 416 | 416 |
| 417 | 417 |
| 418 ConstantInstr* IRRegExpMacroAssembler::BoolConstant(bool value) const { | 418 ConstantInstr* IRRegExpMacroAssembler::BoolConstant(bool value) const { |
| 419 return new(I) ConstantInstr(value ? Bool::True() : Bool::False()); | 419 return new(Z) ConstantInstr(value ? Bool::True() : Bool::False()); |
| 420 } | 420 } |
| 421 | 421 |
| 422 | 422 |
| 423 ConstantInstr* IRRegExpMacroAssembler::StringConstant(const char* value) const { | 423 ConstantInstr* IRRegExpMacroAssembler::StringConstant(const char* value) const { |
| 424 return new(I) ConstantInstr( | 424 return new(Z) ConstantInstr( |
| 425 String::ZoneHandle(I, String::New(value, Heap::kOld))); | 425 String::ZoneHandle(Z, String::New(value, Heap::kOld))); |
| 426 } | 426 } |
| 427 | 427 |
| 428 | 428 |
| 429 ConstantInstr* IRRegExpMacroAssembler::WordCharacterMapConstant() const { | 429 ConstantInstr* IRRegExpMacroAssembler::WordCharacterMapConstant() const { |
| 430 const Library& lib = Library::Handle(I, Library::CoreLibrary()); | 430 const Library& lib = Library::Handle(Z, Library::CoreLibrary()); |
| 431 const Class& regexp_class = Class::Handle(I, | 431 const Class& regexp_class = Class::Handle(Z, |
| 432 lib.LookupClassAllowPrivate(Symbols::JSSyntaxRegExp())); | 432 lib.LookupClassAllowPrivate(Symbols::JSSyntaxRegExp())); |
| 433 const Field& word_character_field = Field::ZoneHandle(I, | 433 const Field& word_character_field = Field::ZoneHandle(Z, |
| 434 regexp_class.LookupStaticField(Symbols::_wordCharacterMap())); | 434 regexp_class.LookupStaticField(Symbols::_wordCharacterMap())); |
| 435 ASSERT(!word_character_field.IsNull()); | 435 ASSERT(!word_character_field.IsNull()); |
| 436 | 436 |
| 437 if (word_character_field.IsUninitialized()) { | 437 if (word_character_field.IsUninitialized()) { |
| 438 word_character_field.EvaluateInitializer(); | 438 word_character_field.EvaluateInitializer(); |
| 439 } | 439 } |
| 440 ASSERT(!word_character_field.IsUninitialized()); | 440 ASSERT(!word_character_field.IsUninitialized()); |
| 441 | 441 |
| 442 return new(I) ConstantInstr( | 442 return new(Z) ConstantInstr( |
| 443 Instance::ZoneHandle(I, word_character_field.value())); | 443 Instance::ZoneHandle(Z, word_character_field.value())); |
| 444 } | 444 } |
| 445 | 445 |
| 446 | 446 |
| 447 ComparisonInstr* IRRegExpMacroAssembler::Comparison( | 447 ComparisonInstr* IRRegExpMacroAssembler::Comparison( |
| 448 ComparisonKind kind, PushArgumentInstr* lhs, PushArgumentInstr* rhs) { | 448 ComparisonKind kind, PushArgumentInstr* lhs, PushArgumentInstr* rhs) { |
| 449 Token::Kind strict_comparison = Token::kEQ_STRICT; | 449 Token::Kind strict_comparison = Token::kEQ_STRICT; |
| 450 Token::Kind intermediate_operator = Token::kILLEGAL; | 450 Token::Kind intermediate_operator = Token::kILLEGAL; |
| 451 switch (kind) { | 451 switch (kind) { |
| 452 case kEQ: | 452 case kEQ: |
| 453 intermediate_operator = Token::kEQ; | 453 intermediate_operator = Token::kEQ; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 474 | 474 |
| 475 ASSERT(intermediate_operator != Token::kILLEGAL); | 475 ASSERT(intermediate_operator != Token::kILLEGAL); |
| 476 | 476 |
| 477 Value* lhs_value = | 477 Value* lhs_value = |
| 478 Bind(InstanceCall( | 478 Bind(InstanceCall( |
| 479 InstanceCallDescriptor::FromToken(intermediate_operator), | 479 InstanceCallDescriptor::FromToken(intermediate_operator), |
| 480 lhs, | 480 lhs, |
| 481 rhs)); | 481 rhs)); |
| 482 Value* rhs_value = Bind(BoolConstant(true)); | 482 Value* rhs_value = Bind(BoolConstant(true)); |
| 483 | 483 |
| 484 return new(I) StrictCompareInstr( | 484 return new(Z) StrictCompareInstr( |
| 485 kNoSourcePos, strict_comparison, lhs_value, rhs_value, true); | 485 kNoSourcePos, strict_comparison, lhs_value, rhs_value, true); |
| 486 } | 486 } |
| 487 | 487 |
| 488 ComparisonInstr* IRRegExpMacroAssembler::Comparison( | 488 ComparisonInstr* IRRegExpMacroAssembler::Comparison( |
| 489 ComparisonKind kind, Definition* lhs, Definition* rhs) { | 489 ComparisonKind kind, Definition* lhs, Definition* rhs) { |
| 490 PushArgumentInstr* lhs_push = PushArgument(Bind(lhs)); | 490 PushArgumentInstr* lhs_push = PushArgument(Bind(lhs)); |
| 491 PushArgumentInstr* rhs_push = PushArgument(Bind(rhs)); | 491 PushArgumentInstr* rhs_push = PushArgument(Bind(rhs)); |
| 492 return Comparison(kind, lhs_push, rhs_push); | 492 return Comparison(kind, lhs_push, rhs_push); |
| 493 } | 493 } |
| 494 | 494 |
| 495 | 495 |
| 496 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( | 496 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( |
| 497 const Function& function) const { | 497 const Function& function) const { |
| 498 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 498 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 499 new(I) ZoneGrowableArray<PushArgumentInstr*>(0); | 499 new(Z) ZoneGrowableArray<PushArgumentInstr*>(0); |
| 500 return StaticCall(function, arguments); | 500 return StaticCall(function, arguments); |
| 501 } | 501 } |
| 502 | 502 |
| 503 | 503 |
| 504 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( | 504 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( |
| 505 const Function& function, | 505 const Function& function, |
| 506 PushArgumentInstr* arg1) const { | 506 PushArgumentInstr* arg1) const { |
| 507 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 507 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 508 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); | 508 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 509 arguments->Add(arg1); | 509 arguments->Add(arg1); |
| 510 | 510 |
| 511 return StaticCall(function, arguments); | 511 return StaticCall(function, arguments); |
| 512 } | 512 } |
| 513 | 513 |
| 514 | 514 |
| 515 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( | 515 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( |
| 516 const Function& function, | 516 const Function& function, |
| 517 PushArgumentInstr* arg1, | 517 PushArgumentInstr* arg1, |
| 518 PushArgumentInstr* arg2) const { | 518 PushArgumentInstr* arg2) const { |
| 519 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 519 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 520 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); | 520 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 521 arguments->Add(arg1); | 521 arguments->Add(arg1); |
| 522 arguments->Add(arg2); | 522 arguments->Add(arg2); |
| 523 | 523 |
| 524 return StaticCall(function, arguments); | 524 return StaticCall(function, arguments); |
| 525 } | 525 } |
| 526 | 526 |
| 527 | 527 |
| 528 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( | 528 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( |
| 529 const Function& function, | 529 const Function& function, |
| 530 ZoneGrowableArray<PushArgumentInstr*>* arguments) const { | 530 ZoneGrowableArray<PushArgumentInstr*>* arguments) const { |
| 531 return new(I) StaticCallInstr(kNoSourcePos, | 531 return new(Z) StaticCallInstr(kNoSourcePos, |
| 532 function, | 532 function, |
| 533 Object::null_array(), | 533 Object::null_array(), |
| 534 arguments, | 534 arguments, |
| 535 ic_data_array_); | 535 ic_data_array_); |
| 536 } | 536 } |
| 537 | 537 |
| 538 | 538 |
| 539 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( | 539 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( |
| 540 const InstanceCallDescriptor& desc, | 540 const InstanceCallDescriptor& desc, |
| 541 PushArgumentInstr* arg1) const { | 541 PushArgumentInstr* arg1) const { |
| 542 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 542 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 543 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); | 543 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 544 arguments->Add(arg1); | 544 arguments->Add(arg1); |
| 545 | 545 |
| 546 return InstanceCall(desc, arguments); | 546 return InstanceCall(desc, arguments); |
| 547 } | 547 } |
| 548 | 548 |
| 549 | 549 |
| 550 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( | 550 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( |
| 551 const InstanceCallDescriptor& desc, | 551 const InstanceCallDescriptor& desc, |
| 552 PushArgumentInstr* arg1, | 552 PushArgumentInstr* arg1, |
| 553 PushArgumentInstr* arg2) const { | 553 PushArgumentInstr* arg2) const { |
| 554 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 554 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 555 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); | 555 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 556 arguments->Add(arg1); | 556 arguments->Add(arg1); |
| 557 arguments->Add(arg2); | 557 arguments->Add(arg2); |
| 558 | 558 |
| 559 return InstanceCall(desc, arguments); | 559 return InstanceCall(desc, arguments); |
| 560 } | 560 } |
| 561 | 561 |
| 562 | 562 |
| 563 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( | 563 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( |
| 564 const InstanceCallDescriptor& desc, | 564 const InstanceCallDescriptor& desc, |
| 565 PushArgumentInstr* arg1, | 565 PushArgumentInstr* arg1, |
| 566 PushArgumentInstr* arg2, | 566 PushArgumentInstr* arg2, |
| 567 PushArgumentInstr* arg3) const { | 567 PushArgumentInstr* arg3) const { |
| 568 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 568 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 569 new(I) ZoneGrowableArray<PushArgumentInstr*>(3); | 569 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
| 570 arguments->Add(arg1); | 570 arguments->Add(arg1); |
| 571 arguments->Add(arg2); | 571 arguments->Add(arg2); |
| 572 arguments->Add(arg3); | 572 arguments->Add(arg3); |
| 573 | 573 |
| 574 return InstanceCall(desc, arguments); | 574 return InstanceCall(desc, arguments); |
| 575 } | 575 } |
| 576 | 576 |
| 577 | 577 |
| 578 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( | 578 InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( |
| 579 const InstanceCallDescriptor& desc, | 579 const InstanceCallDescriptor& desc, |
| 580 ZoneGrowableArray<PushArgumentInstr*> *arguments) const { | 580 ZoneGrowableArray<PushArgumentInstr*> *arguments) const { |
| 581 return | 581 return |
| 582 new(I) InstanceCallInstr(kNoSourcePos, | 582 new(Z) InstanceCallInstr(kNoSourcePos, |
| 583 desc.name, | 583 desc.name, |
| 584 desc.token_kind, | 584 desc.token_kind, |
| 585 arguments, | 585 arguments, |
| 586 Object::null_array(), | 586 Object::null_array(), |
| 587 desc.checked_argument_count, | 587 desc.checked_argument_count, |
| 588 ic_data_array_); | 588 ic_data_array_); |
| 589 } | 589 } |
| 590 | 590 |
| 591 | 591 |
| 592 LoadLocalInstr* IRRegExpMacroAssembler::LoadLocal(LocalVariable* local) const { | 592 LoadLocalInstr* IRRegExpMacroAssembler::LoadLocal(LocalVariable* local) const { |
| 593 return new(I) LoadLocalInstr(*local); | 593 return new(Z) LoadLocalInstr(*local); |
| 594 } | 594 } |
| 595 | 595 |
| 596 | 596 |
| 597 void IRRegExpMacroAssembler::StoreLocal(LocalVariable* local, | 597 void IRRegExpMacroAssembler::StoreLocal(LocalVariable* local, |
| 598 Value* value) { | 598 Value* value) { |
| 599 Do(new(I) StoreLocalInstr(*local, value)); | 599 Do(new(Z) StoreLocalInstr(*local, value)); |
| 600 } | 600 } |
| 601 | 601 |
| 602 | 602 |
| 603 void IRRegExpMacroAssembler::set_current_instruction(Instruction* instruction) { | 603 void IRRegExpMacroAssembler::set_current_instruction(Instruction* instruction) { |
| 604 current_instruction_ = instruction; | 604 current_instruction_ = instruction; |
| 605 } | 605 } |
| 606 | 606 |
| 607 | 607 |
| 608 Value* IRRegExpMacroAssembler::Bind(Definition* definition) { | 608 Value* IRRegExpMacroAssembler::Bind(Definition* definition) { |
| 609 AppendInstruction(definition); | 609 AppendInstruction(definition); |
| 610 definition->set_temp_index(temp_id_.Alloc()); | 610 definition->set_temp_index(temp_id_.Alloc()); |
| 611 | 611 |
| 612 return new(I) Value(definition); | 612 return new(Z) Value(definition); |
| 613 } | 613 } |
| 614 | 614 |
| 615 | 615 |
| 616 void IRRegExpMacroAssembler::Do(Definition* definition) { | 616 void IRRegExpMacroAssembler::Do(Definition* definition) { |
| 617 AppendInstruction(definition); | 617 AppendInstruction(definition); |
| 618 } | 618 } |
| 619 | 619 |
| 620 | 620 |
| 621 Value* IRRegExpMacroAssembler::BindLoadLocal(const LocalVariable& local) { | 621 Value* IRRegExpMacroAssembler::BindLoadLocal(const LocalVariable& local) { |
| 622 if (local.IsConst()) { | 622 if (local.IsConst()) { |
| 623 return Bind(new(I) ConstantInstr(*local.ConstValue())); | 623 return Bind(new(Z) ConstantInstr(*local.ConstValue())); |
| 624 } | 624 } |
| 625 ASSERT(!local.is_captured()); | 625 ASSERT(!local.is_captured()); |
| 626 return Bind(new(I) LoadLocalInstr(local)); | 626 return Bind(new(Z) LoadLocalInstr(local)); |
| 627 } | 627 } |
| 628 | 628 |
| 629 | 629 |
| 630 // In some cases, the V8 irregexp engine generates unreachable code by emitting | 630 // In some cases, the V8 irregexp engine generates unreachable code by emitting |
| 631 // a jmp not followed by a bind. We cannot do the same, since it is impossible | 631 // a jmp not followed by a bind. We cannot do the same, since it is impossible |
| 632 // to append to a block following a jmp. In such cases, assume that we are doing | 632 // to append to a block following a jmp. In such cases, assume that we are doing |
| 633 // the correct thing, but output a warning when tracing. | 633 // the correct thing, but output a warning when tracing. |
| 634 #define HANDLE_DEAD_CODE_EMISSION() \ | 634 #define HANDLE_DEAD_CODE_EMISSION() \ |
| 635 if (current_instruction_ == NULL) { \ | 635 if (current_instruction_ == NULL) { \ |
| 636 if (FLAG_trace_irregexp) { \ | 636 if (FLAG_trace_irregexp) { \ |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 | 687 |
| 688 ASSERT(current_instruction_ != NULL); | 688 ASSERT(current_instruction_ != NULL); |
| 689 ASSERT(current_instruction_->next() == NULL); | 689 ASSERT(current_instruction_->next() == NULL); |
| 690 current_instruction_->Goto(to); | 690 current_instruction_->Goto(to); |
| 691 set_current_instruction(NULL); | 691 set_current_instruction(NULL); |
| 692 } | 692 } |
| 693 | 693 |
| 694 | 694 |
| 695 PushArgumentInstr* IRRegExpMacroAssembler::PushArgument(Value* value) { | 695 PushArgumentInstr* IRRegExpMacroAssembler::PushArgument(Value* value) { |
| 696 arg_id_.Alloc(); | 696 arg_id_.Alloc(); |
| 697 PushArgumentInstr* push = new(I) PushArgumentInstr(value); | 697 PushArgumentInstr* push = new(Z) PushArgumentInstr(value); |
| 698 // Do *not* use Do() for push argument instructions. | 698 // Do *not* use Do() for push argument instructions. |
| 699 AppendInstruction(push); | 699 AppendInstruction(push); |
| 700 return push; | 700 return push; |
| 701 } | 701 } |
| 702 | 702 |
| 703 | 703 |
| 704 PushArgumentInstr* IRRegExpMacroAssembler::PushLocal(LocalVariable* local) { | 704 PushArgumentInstr* IRRegExpMacroAssembler::PushLocal(LocalVariable* local) { |
| 705 return PushArgument(Bind(LoadLocal(local))); | 705 return PushArgument(Bind(LoadLocal(local))); |
| 706 } | 706 } |
| 707 | 707 |
| 708 | 708 |
| 709 void IRRegExpMacroAssembler::Print(const char* str) { | 709 void IRRegExpMacroAssembler::Print(const char* str) { |
| 710 Print(PushArgument( | 710 Print(PushArgument( |
| 711 Bind(new(I) ConstantInstr( | 711 Bind(new(Z) ConstantInstr( |
| 712 String::ZoneHandle(I, String::New(str, Heap::kOld)))))); | 712 String::ZoneHandle(Z, String::New(str, Heap::kOld)))))); |
| 713 } | 713 } |
| 714 | 714 |
| 715 | 715 |
| 716 void IRRegExpMacroAssembler::Print(PushArgumentInstr* argument) { | 716 void IRRegExpMacroAssembler::Print(PushArgumentInstr* argument) { |
| 717 const Library& lib = Library::Handle(Library::CoreLibrary()); | 717 const Library& lib = Library::Handle(Library::CoreLibrary()); |
| 718 const Function& print_fn = Function::ZoneHandle( | 718 const Function& print_fn = Function::ZoneHandle( |
| 719 I, lib.LookupFunctionAllowPrivate(Symbols::print())); | 719 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
| 720 Do(StaticCall(print_fn, argument)); | 720 Do(StaticCall(print_fn, argument)); |
| 721 } | 721 } |
| 722 | 722 |
| 723 | 723 |
| 724 void IRRegExpMacroAssembler::PrintBlocks() { | 724 void IRRegExpMacroAssembler::PrintBlocks() { |
| 725 for (intptr_t i = 0; i < blocks_.length(); i++) { | 725 for (intptr_t i = 0; i < blocks_.length(); i++) { |
| 726 FlowGraphPrinter::PrintBlock(blocks_[i], false); | 726 FlowGraphPrinter::PrintBlock(blocks_[i], false); |
| 727 } | 727 } |
| 728 } | 728 } |
| 729 | 729 |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 &loop); | 1057 &loop); |
| 1058 } else { | 1058 } else { |
| 1059 ASSERT(mode_ == UC16); | 1059 ASSERT(mode_ == UC16); |
| 1060 | 1060 |
| 1061 Value* string_value = Bind(LoadLocal(string_param_)); | 1061 Value* string_value = Bind(LoadLocal(string_param_)); |
| 1062 Value* lhs_index_value = Bind(LoadLocal(match_start_index_)); | 1062 Value* lhs_index_value = Bind(LoadLocal(match_start_index_)); |
| 1063 Value* rhs_index_value = Bind(LoadLocal(capture_start_index_)); | 1063 Value* rhs_index_value = Bind(LoadLocal(capture_start_index_)); |
| 1064 Value* length_value = Bind(LoadLocal(capture_length_)); | 1064 Value* length_value = Bind(LoadLocal(capture_length_)); |
| 1065 | 1065 |
| 1066 Definition* is_match_def = | 1066 Definition* is_match_def = |
| 1067 new(I) CaseInsensitiveCompareUC16Instr( | 1067 new(Z) CaseInsensitiveCompareUC16Instr( |
| 1068 string_value, | 1068 string_value, |
| 1069 lhs_index_value, | 1069 lhs_index_value, |
| 1070 rhs_index_value, | 1070 rhs_index_value, |
| 1071 length_value, | 1071 length_value, |
| 1072 specialization_cid_); | 1072 specialization_cid_); |
| 1073 | 1073 |
| 1074 BranchOrBacktrack(Comparison(kNE, is_match_def, BoolConstant(true)), | 1074 BranchOrBacktrack(Comparison(kNE, is_match_def, BoolConstant(true)), |
| 1075 on_no_match); | 1075 on_no_match); |
| 1076 } | 1076 } |
| 1077 | 1077 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1287 on_not_in_range); | 1287 on_not_in_range); |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 | 1290 |
| 1291 void IRRegExpMacroAssembler::CheckBitInTable( | 1291 void IRRegExpMacroAssembler::CheckBitInTable( |
| 1292 const TypedData& table, | 1292 const TypedData& table, |
| 1293 BlockLabel* on_bit_set) { | 1293 BlockLabel* on_bit_set) { |
| 1294 TAG(); | 1294 TAG(); |
| 1295 | 1295 |
| 1296 PushArgumentInstr* table_push = | 1296 PushArgumentInstr* table_push = |
| 1297 PushArgument(Bind(new(I) ConstantInstr(table))); | 1297 PushArgument(Bind(new(Z) ConstantInstr(table))); |
| 1298 PushArgumentInstr* index_push = PushLocal(current_character_); | 1298 PushArgumentInstr* index_push = PushLocal(current_character_); |
| 1299 | 1299 |
| 1300 if (mode_ != ASCII || kTableMask != Symbols::kMaxOneCharCodeSymbol) { | 1300 if (mode_ != ASCII || kTableMask != Symbols::kMaxOneCharCodeSymbol) { |
| 1301 PushArgumentInstr* mask_push = | 1301 PushArgumentInstr* mask_push = |
| 1302 PushArgument(Bind(Uint64Constant(kTableSize - 1))); | 1302 PushArgument(Bind(Uint64Constant(kTableSize - 1))); |
| 1303 index_push = PushArgument( | 1303 index_push = PushArgument( |
| 1304 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_AND), | 1304 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kBIT_AND), |
| 1305 index_push, | 1305 index_push, |
| 1306 mask_push))); | 1306 mask_push))); |
| 1307 } | 1307 } |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 TAG(); | 1631 TAG(); |
| 1632 PushArgumentInstr* stack_push = PushLocal(stack_); | 1632 PushArgumentInstr* stack_push = PushLocal(stack_); |
| 1633 PushArgumentInstr* length_push = PushArgument(Bind(InstanceCall( | 1633 PushArgumentInstr* length_push = PushArgument(Bind(InstanceCall( |
| 1634 InstanceCallDescriptor( | 1634 InstanceCallDescriptor( |
| 1635 String::ZoneHandle(Field::GetterSymbol(Symbols::Length()))), | 1635 String::ZoneHandle(Field::GetterSymbol(Symbols::Length()))), |
| 1636 stack_push))); | 1636 stack_push))); |
| 1637 PushArgumentInstr* capacity_push = PushArgument(Bind(Sub( | 1637 PushArgumentInstr* capacity_push = PushArgument(Bind(Sub( |
| 1638 length_push, | 1638 length_push, |
| 1639 PushArgument(Bind(Uint64Constant(stack_limit_slack())))))); | 1639 PushArgument(Bind(Uint64Constant(stack_limit_slack())))))); |
| 1640 PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_); | 1640 PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_); |
| 1641 BranchInstr* branch = new(I) BranchInstr( | 1641 BranchInstr* branch = new(Z) BranchInstr( |
| 1642 Comparison(kGT, capacity_push, stack_pointer_push)); | 1642 Comparison(kGT, capacity_push, stack_pointer_push)); |
| 1643 CloseBlockWith(branch); | 1643 CloseBlockWith(branch); |
| 1644 | 1644 |
| 1645 BlockLabel grow_stack; | 1645 BlockLabel grow_stack; |
| 1646 BlockLabel fallthrough; | 1646 BlockLabel fallthrough; |
| 1647 *branch->true_successor_address() = | 1647 *branch->true_successor_address() = |
| 1648 TargetWithJoinGoto(fallthrough.block()); | 1648 TargetWithJoinGoto(fallthrough.block()); |
| 1649 *branch->false_successor_address() = | 1649 *branch->false_successor_address() = |
| 1650 TargetWithJoinGoto(grow_stack.block()); | 1650 TargetWithJoinGoto(grow_stack.block()); |
| 1651 | 1651 |
| 1652 BindBlock(&grow_stack); | 1652 BindBlock(&grow_stack); |
| 1653 GrowStack(); | 1653 GrowStack(); |
| 1654 | 1654 |
| 1655 BindBlock(&fallthrough); | 1655 BindBlock(&fallthrough); |
| 1656 } | 1656 } |
| 1657 | 1657 |
| 1658 | 1658 |
| 1659 void IRRegExpMacroAssembler::GrowStack() { | 1659 void IRRegExpMacroAssembler::GrowStack() { |
| 1660 TAG(); | 1660 TAG(); |
| 1661 Value* cell = Bind(new(I) ConstantInstr(stack_array_cell_)); | 1661 Value* cell = Bind(new(Z) ConstantInstr(stack_array_cell_)); |
| 1662 StoreLocal(stack_, Bind(new(I) GrowRegExpStackInstr(cell))); | 1662 StoreLocal(stack_, Bind(new(Z) GrowRegExpStackInstr(cell))); |
| 1663 } | 1663 } |
| 1664 | 1664 |
| 1665 | 1665 |
| 1666 void IRRegExpMacroAssembler::ReadCurrentPositionFromRegister(intptr_t reg) { | 1666 void IRRegExpMacroAssembler::ReadCurrentPositionFromRegister(intptr_t reg) { |
| 1667 TAG(); | 1667 TAG(); |
| 1668 StoreLocal(current_position_, LoadRegister(reg)); | 1668 StoreLocal(current_position_, LoadRegister(reg)); |
| 1669 } | 1669 } |
| 1670 | 1670 |
| 1671 // Resets the tip of the stack to the value stored in reg. | 1671 // Resets the tip of the stack to the value stored in reg. |
| 1672 void IRRegExpMacroAssembler::ReadStackPointerFromRegister(intptr_t reg) { | 1672 void IRRegExpMacroAssembler::ReadStackPointerFromRegister(intptr_t reg) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 JoinEntryInstr* true_successor_block = backtrack_block_; | 1792 JoinEntryInstr* true_successor_block = backtrack_block_; |
| 1793 if (true_successor != NULL) { | 1793 if (true_successor != NULL) { |
| 1794 true_successor->SetLinked(); | 1794 true_successor->SetLinked(); |
| 1795 true_successor_block = true_successor->block(); | 1795 true_successor_block = true_successor->block(); |
| 1796 } | 1796 } |
| 1797 ASSERT(true_successor_block != NULL); | 1797 ASSERT(true_successor_block != NULL); |
| 1798 | 1798 |
| 1799 // If the condition is not true, fall through to a new block. | 1799 // If the condition is not true, fall through to a new block. |
| 1800 BlockLabel fallthrough; | 1800 BlockLabel fallthrough; |
| 1801 | 1801 |
| 1802 BranchInstr* branch = new(I) BranchInstr(comparison); | 1802 BranchInstr* branch = new(Z) BranchInstr(comparison); |
| 1803 *branch->true_successor_address() = | 1803 *branch->true_successor_address() = |
| 1804 TargetWithJoinGoto(true_successor_block); | 1804 TargetWithJoinGoto(true_successor_block); |
| 1805 *branch->false_successor_address() = | 1805 *branch->false_successor_address() = |
| 1806 TargetWithJoinGoto(fallthrough.block()); | 1806 TargetWithJoinGoto(fallthrough.block()); |
| 1807 | 1807 |
| 1808 CloseBlockWith(branch); | 1808 CloseBlockWith(branch); |
| 1809 BindBlock(&fallthrough); | 1809 BindBlock(&fallthrough); |
| 1810 } | 1810 } |
| 1811 | 1811 |
| 1812 | 1812 |
| 1813 TargetEntryInstr* IRRegExpMacroAssembler::TargetWithJoinGoto( | 1813 TargetEntryInstr* IRRegExpMacroAssembler::TargetWithJoinGoto( |
| 1814 JoinEntryInstr* dst) { | 1814 JoinEntryInstr* dst) { |
| 1815 TargetEntryInstr* target = new(I) TargetEntryInstr( | 1815 TargetEntryInstr* target = new(Z) TargetEntryInstr( |
| 1816 block_id_.Alloc(), kInvalidTryIndex); | 1816 block_id_.Alloc(), kInvalidTryIndex); |
| 1817 blocks_.Add(target); | 1817 blocks_.Add(target); |
| 1818 | 1818 |
| 1819 target->AppendInstruction(new(I) GotoInstr(dst)); | 1819 target->AppendInstruction(new(Z) GotoInstr(dst)); |
| 1820 | 1820 |
| 1821 return target; | 1821 return target; |
| 1822 } | 1822 } |
| 1823 | 1823 |
| 1824 | 1824 |
| 1825 IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto( | 1825 IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto( |
| 1826 JoinEntryInstr* dst) { | 1826 JoinEntryInstr* dst) { |
| 1827 IndirectEntryInstr* target = new(I) IndirectEntryInstr( | 1827 IndirectEntryInstr* target = new(Z) IndirectEntryInstr( |
| 1828 block_id_.Alloc(), indirect_id_.Alloc(), kInvalidTryIndex); | 1828 block_id_.Alloc(), indirect_id_.Alloc(), kInvalidTryIndex); |
| 1829 blocks_.Add(target); | 1829 blocks_.Add(target); |
| 1830 | 1830 |
| 1831 target->AppendInstruction(new(I) GotoInstr(dst)); | 1831 target->AppendInstruction(new(Z) GotoInstr(dst)); |
| 1832 | 1832 |
| 1833 return target; | 1833 return target; |
| 1834 } | 1834 } |
| 1835 | 1835 |
| 1836 | 1836 |
| 1837 void IRRegExpMacroAssembler::CheckPreemption() { | 1837 void IRRegExpMacroAssembler::CheckPreemption() { |
| 1838 TAG(); | 1838 TAG(); |
| 1839 AppendInstruction(new(I) CheckStackOverflowInstr(kNoSourcePos, 0)); | 1839 AppendInstruction(new(Z) CheckStackOverflowInstr(kNoSourcePos, 0)); |
| 1840 } | 1840 } |
| 1841 | 1841 |
| 1842 | 1842 |
| 1843 Definition* IRRegExpMacroAssembler::Add( | 1843 Definition* IRRegExpMacroAssembler::Add( |
| 1844 PushArgumentInstr* lhs, | 1844 PushArgumentInstr* lhs, |
| 1845 PushArgumentInstr* rhs) { | 1845 PushArgumentInstr* rhs) { |
| 1846 return InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD), lhs, rhs); | 1846 return InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD), lhs, rhs); |
| 1847 } | 1847 } |
| 1848 | 1848 |
| 1849 | 1849 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1906 } else if (specialization_cid_ == kExternalTwoByteStringCid) { | 1906 } else if (specialization_cid_ == kExternalTwoByteStringCid) { |
| 1907 external_offset = ExternalTwoByteString::external_data_offset(); | 1907 external_offset = ExternalTwoByteString::external_data_offset(); |
| 1908 data_offset = RawExternalTwoByteString::ExternalData::data_offset(); | 1908 data_offset = RawExternalTwoByteString::ExternalData::data_offset(); |
| 1909 } else { | 1909 } else { |
| 1910 UNREACHABLE(); | 1910 UNREACHABLE(); |
| 1911 } | 1911 } |
| 1912 // This pushes untagged values on the stack which are immediately consumed: | 1912 // This pushes untagged values on the stack which are immediately consumed: |
| 1913 // the first value is consumed to obtain the second value which is consumed | 1913 // the first value is consumed to obtain the second value which is consumed |
| 1914 // by LoadCodeUnitsAtInstr below. | 1914 // by LoadCodeUnitsAtInstr below. |
| 1915 Value* external_val = | 1915 Value* external_val = |
| 1916 Bind(new(I) LoadUntaggedInstr(pattern_val, external_offset)); | 1916 Bind(new(Z) LoadUntaggedInstr(pattern_val, external_offset)); |
| 1917 pattern_val = | 1917 pattern_val = |
| 1918 Bind(new(I) LoadUntaggedInstr(external_val, data_offset)); | 1918 Bind(new(Z) LoadUntaggedInstr(external_val, data_offset)); |
| 1919 } | 1919 } |
| 1920 | 1920 |
| 1921 // Here pattern_val might be untagged so this must not trigger a GC. | 1921 // Here pattern_val might be untagged so this must not trigger a GC. |
| 1922 Value* index_val = BindLoadLocal(*index); | 1922 Value* index_val = BindLoadLocal(*index); |
| 1923 | 1923 |
| 1924 return Bind(new(I) LoadCodeUnitsInstr( | 1924 return Bind(new(Z) LoadCodeUnitsInstr( |
| 1925 pattern_val, | 1925 pattern_val, |
| 1926 index_val, | 1926 index_val, |
| 1927 characters, | 1927 characters, |
| 1928 specialization_cid_, | 1928 specialization_cid_, |
| 1929 Scanner::kNoSourcePos)); | 1929 Scanner::kNoSourcePos)); |
| 1930 } | 1930 } |
| 1931 | 1931 |
| 1932 | 1932 |
| 1933 #undef __ | 1933 #undef __ |
| 1934 | 1934 |
| 1935 } // namespace dart | 1935 } // namespace dart |
| OLD | NEW |