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 |