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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 683433003: Integrate the Irregexp Regular Expression Engine. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 416
417 // Instructions. 417 // Instructions.
418 418
419 // M is a single argument macro. It is applied to each concrete instruction 419 // M is a single argument macro. It is applied to each concrete instruction
420 // type name. The concrete instruction classes are the name with Instr 420 // type name. The concrete instruction classes are the name with Instr
421 // concatenated. 421 // concatenated.
422 #define FOR_EACH_INSTRUCTION(M) \ 422 #define FOR_EACH_INSTRUCTION(M) \
423 M(GraphEntry) \ 423 M(GraphEntry) \
424 M(JoinEntry) \ 424 M(JoinEntry) \
425 M(TargetEntry) \ 425 M(TargetEntry) \
426 M(IndirectEntry) \
426 M(CatchBlockEntry) \ 427 M(CatchBlockEntry) \
427 M(Phi) \ 428 M(Phi) \
428 M(Redefinition) \ 429 M(Redefinition) \
429 M(Parameter) \ 430 M(Parameter) \
430 M(ParallelMove) \ 431 M(ParallelMove) \
431 M(PushArgument) \ 432 M(PushArgument) \
432 M(Return) \ 433 M(Return) \
433 M(Throw) \ 434 M(Throw) \
434 M(ReThrow) \ 435 M(ReThrow) \
435 M(Goto) \ 436 M(Goto) \
437 M(IndirectGoto) \
436 M(Branch) \ 438 M(Branch) \
437 M(AssertAssignable) \ 439 M(AssertAssignable) \
438 M(AssertBoolean) \ 440 M(AssertBoolean) \
439 M(CurrentContext) \ 441 M(CurrentContext) \
440 M(StoreContext) \ 442 M(StoreContext) \
441 M(ClosureCall) \ 443 M(ClosureCall) \
442 M(InstanceCall) \ 444 M(InstanceCall) \
443 M(PolymorphicInstanceCall) \ 445 M(PolymorphicInstanceCall) \
444 M(StaticCall) \ 446 M(StaticCall) \
445 M(LoadLocal) \ 447 M(LoadLocal) \
446 M(PushTemp) \ 448 M(PushTemp) \
447 M(DropTemps) \ 449 M(DropTemps) \
448 M(StoreLocal) \ 450 M(StoreLocal) \
449 M(StrictCompare) \ 451 M(StrictCompare) \
450 M(EqualityCompare) \ 452 M(EqualityCompare) \
451 M(RelationalOp) \ 453 M(RelationalOp) \
452 M(NativeCall) \ 454 M(NativeCall) \
453 M(DebugStepCheck) \ 455 M(DebugStepCheck) \
454 M(LoadIndexed) \ 456 M(LoadIndexed) \
457 M(LoadCodeUnits) \
455 M(StoreIndexed) \ 458 M(StoreIndexed) \
456 M(StoreInstanceField) \ 459 M(StoreInstanceField) \
457 M(InitStaticField) \ 460 M(InitStaticField) \
458 M(LoadStaticField) \ 461 M(LoadStaticField) \
459 M(StoreStaticField) \ 462 M(StoreStaticField) \
460 M(BooleanNegate) \ 463 M(BooleanNegate) \
461 M(InstanceOf) \ 464 M(InstanceOf) \
462 M(CreateArray) \ 465 M(CreateArray) \
463 M(AllocateObject) \ 466 M(AllocateObject) \
464 M(LoadField) \ 467 M(LoadField) \
(...skipping 19 matching lines...) Expand all
484 M(FloatToDouble) \ 487 M(FloatToDouble) \
485 M(CheckClass) \ 488 M(CheckClass) \
486 M(CheckClassId) \ 489 M(CheckClassId) \
487 M(CheckSmi) \ 490 M(CheckSmi) \
488 M(Constant) \ 491 M(Constant) \
489 M(UnboxedConstant) \ 492 M(UnboxedConstant) \
490 M(CheckEitherNonSmi) \ 493 M(CheckEitherNonSmi) \
491 M(BinaryDoubleOp) \ 494 M(BinaryDoubleOp) \
492 M(MathUnary) \ 495 M(MathUnary) \
493 M(MathMinMax) \ 496 M(MathMinMax) \
497 M(CaseInsensitiveCompareUC16) \
494 M(UnboxDouble) \ 498 M(UnboxDouble) \
495 M(BoxDouble) \ 499 M(BoxDouble) \
496 M(BoxFloat32x4) \ 500 M(BoxFloat32x4) \
497 M(UnboxFloat32x4) \ 501 M(UnboxFloat32x4) \
498 M(BoxInt32x4) \ 502 M(BoxInt32x4) \
499 M(UnboxInt32x4) \ 503 M(UnboxInt32x4) \
500 M(UnboxInteger) \ 504 M(UnboxInteger) \
501 M(BoxInteger) \ 505 M(BoxInteger) \
502 M(BinaryMintOp) \ 506 M(BinaryMintOp) \
503 M(ShiftMintOp) \ 507 M(ShiftMintOp) \
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 return const_cast<BlockEntryInstr*>(this); 1162 return const_cast<BlockEntryInstr*>(this);
1159 } 1163 }
1160 1164
1161 // Helper to mutate the graph during inlining. This block should be 1165 // Helper to mutate the graph during inlining. This block should be
1162 // replaced with new_block as a predecessor of all of this block's 1166 // replaced with new_block as a predecessor of all of this block's
1163 // successors. 1167 // successors.
1164 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); 1168 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block);
1165 1169
1166 void set_block_id(intptr_t block_id) { block_id_ = block_id; } 1170 void set_block_id(intptr_t block_id) { block_id_ = block_id; }
1167 1171
1172 intptr_t offset() const { return offset_; }
1173 void set_offset(intptr_t offset) { offset_ = offset; }
1174
1168 // For all instruction in this block: Remove all inputs (including in the 1175 // For all instruction in this block: Remove all inputs (including in the
1169 // environment) from their definition's use lists for all instructions. 1176 // environment) from their definition's use lists for all instructions.
1170 void ClearAllInstructions(); 1177 void ClearAllInstructions();
1171 1178
1172 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) 1179 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
1173 1180
1174 protected: 1181 protected:
1175 BlockEntryInstr(intptr_t block_id, intptr_t try_index) 1182 BlockEntryInstr(intptr_t block_id, intptr_t try_index)
1176 : Instruction(Isolate::Current()->GetNextDeoptId()), 1183 : Instruction(Isolate::Current()->GetNextDeoptId()),
1177 block_id_(block_id), 1184 block_id_(block_id),
1178 try_index_(try_index), 1185 try_index_(try_index),
1179 preorder_number_(-1), 1186 preorder_number_(-1),
1180 postorder_number_(-1), 1187 postorder_number_(-1),
1181 dominator_(NULL), 1188 dominator_(NULL),
1182 dominated_blocks_(1), 1189 dominated_blocks_(1),
1183 last_instruction_(NULL), 1190 last_instruction_(NULL),
1191 offset_(-1),
1184 parallel_move_(NULL), 1192 parallel_move_(NULL),
1185 loop_info_(NULL) { 1193 loop_info_(NULL) {
1186 } 1194 }
1187 1195
1188 private: 1196 private:
1189 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1197 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1190 1198
1191 virtual void ClearPredecessors() = 0; 1199 virtual void ClearPredecessors() = 0;
1192 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; 1200 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
1193 1201
1194 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 1202 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
1195 1203
1196 intptr_t block_id_; 1204 intptr_t block_id_;
1197 const intptr_t try_index_; 1205 const intptr_t try_index_;
1198 intptr_t preorder_number_; 1206 intptr_t preorder_number_;
1199 intptr_t postorder_number_; 1207 intptr_t postorder_number_;
1200 // Starting and ending lifetime positions for this block. Used by 1208 // Starting and ending lifetime positions for this block. Used by
1201 // the linear scan register allocator. 1209 // the linear scan register allocator.
1202 intptr_t start_pos_; 1210 intptr_t start_pos_;
1203 intptr_t end_pos_; 1211 intptr_t end_pos_;
1204 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 1212 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1205 // TODO(fschneider): Optimize the case of one child to save space. 1213 // TODO(fschneider): Optimize the case of one child to save space.
1206 GrowableArray<BlockEntryInstr*> dominated_blocks_; 1214 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1207 Instruction* last_instruction_; 1215 Instruction* last_instruction_;
1208 1216
1217 // Offset of this block from the start of the emitted code.
1218 intptr_t offset_;
1219
1209 // Parallel move that will be used by linear scan register allocator to 1220 // Parallel move that will be used by linear scan register allocator to
1210 // connect live ranges at the start of the block. 1221 // connect live ranges at the start of the block.
1211 ParallelMoveInstr* parallel_move_; 1222 ParallelMoveInstr* parallel_move_;
1212 1223
1213 // Bit vector containg loop blocks for a loop header indexed by block 1224 // Bit vector containg loop blocks for a loop header indexed by block
1214 // preorder number. 1225 // preorder number.
1215 BitVector* loop_info_; 1226 BitVector* loop_info_;
1216 1227
1217 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 1228 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1218 }; 1229 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 UNREACHABLE(); 1290 UNREACHABLE();
1280 return NULL; 1291 return NULL;
1281 } 1292 }
1282 virtual intptr_t SuccessorCount() const; 1293 virtual intptr_t SuccessorCount() const;
1283 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1294 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1284 1295
1285 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } 1296 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
1286 1297
1287 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1298 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1288 1299
1300 void AddIndirectEntry(IndirectEntryInstr* entry) {
1301 indirect_entries_.Add(entry);
1302 }
1303
1289 GrowableArray<Definition*>* initial_definitions() { 1304 GrowableArray<Definition*>* initial_definitions() {
1290 return &initial_definitions_; 1305 return &initial_definitions_;
1291 } 1306 }
1292 ConstantInstr* constant_null(); 1307 ConstantInstr* constant_null();
1293 1308
1294 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1309 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1295 1310
1296 intptr_t entry_count() const { return entry_count_; } 1311 intptr_t entry_count() const { return entry_count_; }
1297 void set_entry_count(intptr_t count) { entry_count_ = count; } 1312 void set_entry_count(intptr_t count) { entry_count_ = count; }
1298 1313
(...skipping 14 matching lines...) Expand all
1313 TargetEntryInstr* normal_entry() const { return normal_entry_; } 1328 TargetEntryInstr* normal_entry() const { return normal_entry_; }
1314 1329
1315 const ParsedFunction& parsed_function() const { 1330 const ParsedFunction& parsed_function() const {
1316 return *parsed_function_; 1331 return *parsed_function_;
1317 } 1332 }
1318 1333
1319 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { 1334 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
1320 return catch_entries_; 1335 return catch_entries_;
1321 } 1336 }
1322 1337
1338 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const {
1339 return indirect_entries_;
1340 }
1341
1323 virtual void PrintTo(BufferFormatter* f) const; 1342 virtual void PrintTo(BufferFormatter* f) const;
1324 1343
1325 private: 1344 private:
1326 virtual void ClearPredecessors() {} 1345 virtual void ClearPredecessors() {}
1327 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1346 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1328 1347
1329 const ParsedFunction* parsed_function_; 1348 const ParsedFunction* parsed_function_;
1330 TargetEntryInstr* normal_entry_; 1349 TargetEntryInstr* normal_entry_;
1331 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1350 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1351 // Indirect targets are blocks reachable only through indirect gotos.
1352 GrowableArray<IndirectEntryInstr*> indirect_entries_;
1332 GrowableArray<Definition*> initial_definitions_; 1353 GrowableArray<Definition*> initial_definitions_;
1333 const intptr_t osr_id_; 1354 const intptr_t osr_id_;
1334 intptr_t entry_count_; 1355 intptr_t entry_count_;
1335 intptr_t spill_slot_count_; 1356 intptr_t spill_slot_count_;
1336 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1357 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1337 1358
1338 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1359 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1339 }; 1360 };
1340 1361
1341 1362
(...skipping 25 matching lines...) Expand all
1367 virtual void PrintTo(BufferFormatter* f) const; 1388 virtual void PrintTo(BufferFormatter* f) const;
1368 1389
1369 virtual EffectSet Effects() const { return EffectSet::None(); } 1390 virtual EffectSet Effects() const { return EffectSet::None(); }
1370 virtual EffectSet Dependencies() const { return EffectSet::None(); } 1391 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1371 1392
1372 private: 1393 private:
1373 // Classes that have access to predecessors_ when inlining. 1394 // Classes that have access to predecessors_ when inlining.
1374 friend class BlockEntryInstr; 1395 friend class BlockEntryInstr;
1375 friend class InlineExitCollector; 1396 friend class InlineExitCollector;
1376 friend class PolymorphicInliner; 1397 friend class PolymorphicInliner;
1398 friend class IndirectEntryInstr; // Access in il_printer.cc.
1377 1399
1378 // Direct access to phis_ in order to resize it due to phi elimination. 1400 // Direct access to phis_ in order to resize it due to phi elimination.
1379 friend class ConstantPropagator; 1401 friend class ConstantPropagator;
1380 friend class DeadCodeElimination; 1402 friend class DeadCodeElimination;
1381 1403
1382 virtual void ClearPredecessors() { predecessors_.Clear(); } 1404 virtual void ClearPredecessors() { predecessors_.Clear(); }
1383 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1405 virtual void AddPredecessor(BlockEntryInstr* predecessor);
1384 1406
1385 GrowableArray<BlockEntryInstr*> predecessors_; 1407 GrowableArray<BlockEntryInstr*> predecessors_;
1386 ZoneGrowableArray<PhiInstr*>* phis_; 1408 ZoneGrowableArray<PhiInstr*>* phis_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 predecessor_ = predecessor; 1467 predecessor_ = predecessor;
1446 } 1468 }
1447 1469
1448 BlockEntryInstr* predecessor_; 1470 BlockEntryInstr* predecessor_;
1449 double edge_weight_; 1471 double edge_weight_;
1450 1472
1451 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1473 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1452 }; 1474 };
1453 1475
1454 1476
1477 class IndirectEntryInstr : public JoinEntryInstr {
1478 public:
1479 IndirectEntryInstr(intptr_t block_id,
1480 intptr_t indirect_id,
1481 intptr_t try_index)
1482 : JoinEntryInstr(block_id, try_index),
1483 indirect_id_(indirect_id) { }
1484
1485 DECLARE_INSTRUCTION(IndirectEntry)
1486
1487 virtual void PrintTo(BufferFormatter* f) const;
1488
1489 intptr_t indirect_id() const { return indirect_id_; }
1490
1491 private:
1492 const intptr_t indirect_id_;
1493 };
1494
1495
1455 class CatchBlockEntryInstr : public BlockEntryInstr { 1496 class CatchBlockEntryInstr : public BlockEntryInstr {
1456 public: 1497 public:
1457 CatchBlockEntryInstr(intptr_t block_id, 1498 CatchBlockEntryInstr(intptr_t block_id,
1458 intptr_t try_index, 1499 intptr_t try_index,
1459 const Array& handler_types, 1500 const Array& handler_types,
1460 intptr_t catch_try_index, 1501 intptr_t catch_try_index,
1461 const LocalVariable& exception_var, 1502 const LocalVariable& exception_var,
1462 const LocalVariable& stacktrace_var, 1503 const LocalVariable& stacktrace_var,
1463 bool needs_stacktrace) 1504 bool needs_stacktrace)
1464 : BlockEntryInstr(block_id, try_index), 1505 : BlockEntryInstr(block_id, try_index),
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
2150 private: 2191 private:
2151 JoinEntryInstr* successor_; 2192 JoinEntryInstr* successor_;
2152 double edge_weight_; 2193 double edge_weight_;
2153 2194
2154 // Parallel move that will be used by linear scan register allocator to 2195 // Parallel move that will be used by linear scan register allocator to
2155 // connect live ranges at the end of the block and resolve phis. 2196 // connect live ranges at the end of the block and resolve phis.
2156 ParallelMoveInstr* parallel_move_; 2197 ParallelMoveInstr* parallel_move_;
2157 }; 2198 };
2158 2199
2159 2200
2201 // As a high level description, an indirect goto takes the indirect_id of an
2202 // indirect entry as a parameter, and jumps to that location.
2203 //
2204 // In more detail: in order to preserve split-edge form, an intermediate target
2205 // entry consisting of a goto to the final indirect entry is inserted on
2206 // each possible indirect goto -> indirect entry edge. These target entries are
2207 // accessible through successors_.
2208 //
2209 // Byte offsets of all possible indirect targets are stored in the offsets_
2210 // array. The desired offset is looked up while the generated code is executing,
2211 // and passed to IndirectGoto as an input.
2212 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> {
2213 public:
2214 IndirectGotoInstr(GrowableObjectArray* offsets,
2215 Value* offset_from_start)
2216 : offsets_(*offsets) {
2217 SetInputAt(0, offset_from_start);
2218 }
2219
2220 DECLARE_INSTRUCTION(IndirectGoto)
2221
2222 virtual intptr_t ArgumentCount() const { return 0; }
2223
2224 void AddSuccessor(TargetEntryInstr* successor) {
2225 ASSERT(successor->next()->IsGoto());
2226 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
2227 successors_.Add(successor);
2228 }
2229
2230 virtual intptr_t SuccessorCount() const { return successors_.length(); }
2231 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const {
2232 ASSERT(index < SuccessorCount());
2233 return successors_[index];
2234 }
2235
2236 virtual bool CanDeoptimize() const { return false; }
2237 virtual bool CanBecomeDeoptimizationTarget() const { return false; }
2238
2239 virtual EffectSet Effects() const { return EffectSet::None(); }
2240
2241 virtual void PrintTo(BufferFormatter* f) const;
2242
2243 const GrowableObjectArray& offsets() const { return offsets_; }
2244 void SetOffsetCount(Isolate* isolate, intptr_t count) {
2245 if (offsets_.Capacity() < count) {
2246 offsets_.Grow(count, Heap::kOld);
2247 }
2248 if (offsets_.Length() < count) {
2249 offsets_.SetLength(count);
2250 }
2251 }
2252 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) {
2253 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset)));
2254 }
2255
2256 private:
2257 GrowableArray<TargetEntryInstr*> successors_;
2258 GrowableObjectArray& offsets_;
2259 };
2260
2261
2160 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { 2262 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> {
2161 public: 2263 public:
2162 Value* left() const { return inputs_[0]; } 2264 Value* left() const { return inputs_[0]; }
2163 Value* right() const { return inputs_[1]; } 2265 Value* right() const { return inputs_[1]; }
2164 2266
2165 virtual intptr_t token_pos() const { return token_pos_; } 2267 virtual intptr_t token_pos() const { return token_pos_; }
2166 Token::Kind kind() const { return kind_; } 2268 Token::Kind kind() const { return kind_; }
2167 2269
2168 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; 2270 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2169 2271
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after
3644 3746
3645 private: 3747 private:
3646 const intptr_t index_scale_; 3748 const intptr_t index_scale_;
3647 const intptr_t class_id_; 3749 const intptr_t class_id_;
3648 const intptr_t token_pos_; 3750 const intptr_t token_pos_;
3649 3751
3650 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3752 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3651 }; 3753 };
3652 3754
3653 3755
3756 // Loads the specified number of code units from the given string, packing
3757 // multiple code units into a single datatype. In essence, this is a specialized
3758 // version of LoadIndexedInstr which accepts only string targets and can load
3759 // multiple elements at once. The result datatype differs depending on the
3760 // string type, element count, and architecture; if possible, the result is
3761 // packed into a Smi, falling back to a Mint otherwise.
3762 // TODO(jgruber): Add support for loading into UnboxedInt32x4.
3763 class LoadCodeUnitsInstr : public TemplateDefinition<2, NoThrow> {
3764 public:
3765 LoadCodeUnitsInstr(Value* str,
3766 Value* index,
3767 intptr_t element_count,
3768 intptr_t class_id,
3769 intptr_t token_pos)
3770 : class_id_(class_id),
3771 token_pos_(token_pos),
3772 element_count_(element_count) {
3773 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
3774 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid);
3775 SetInputAt(0, str);
3776 SetInputAt(1, index);
3777 }
3778
3779 intptr_t token_pos() const { return token_pos_; }
3780
3781 DECLARE_INSTRUCTION(LoadCodeUnits)
3782 virtual CompileType ComputeType() const;
3783
3784 bool IsExternal() const {
3785 return array()->definition()->representation() == kUntagged;
3786 }
3787
3788 Value* array() const { return inputs_[0]; }
3789 Value* index() const { return inputs_[1]; }
3790 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); }
3791 intptr_t class_id() const { return class_id_; }
3792 intptr_t element_count() const { return element_count_; }
3793
3794 bool can_pack_into_smi() const {
3795 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte);
3796 }
3797
3798 virtual bool CanDeoptimize() const { return false; }
3799
3800 virtual Representation representation() const;
3801 virtual void InferRange(RangeAnalysis* analysis, Range* range);
3802
3803 virtual EffectSet Effects() const { return EffectSet::None(); }
3804
3805 private:
3806 const intptr_t class_id_;
3807 const intptr_t token_pos_;
3808 const intptr_t element_count_;
3809
3810 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr);
3811 };
3812
3813
3654 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { 3814 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
3655 public: 3815 public:
3656 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3816 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3657 ASSERT(char_code != NULL); 3817 ASSERT(char_code != NULL);
3658 ASSERT(char_code->definition()->IsLoadIndexed()); 3818 ASSERT(char_code->definition()->IsLoadIndexed());
3659 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == 3819 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
3660 kOneByteStringCid); 3820 kOneByteStringCid);
3661 SetInputAt(0, char_code); 3821 SetInputAt(0, char_code);
3662 } 3822 }
3663 3823
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4782 4942
4783 static const char* KindToCString(MathUnaryKind kind); 4943 static const char* KindToCString(MathUnaryKind kind);
4784 4944
4785 private: 4945 private:
4786 const MathUnaryKind kind_; 4946 const MathUnaryKind kind_;
4787 4947
4788 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); 4948 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr);
4789 }; 4949 };
4790 4950
4791 4951
4952 // Calls into the runtime and performs a case-insensitive comparison of the
4953 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at
4954 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length].
4955 //
4956 // TODO(jgruber): Remove this once (if) functions inherited from unibrow
4957 // are moved to dart code.
4958 class CaseInsensitiveCompareUC16Instr
4959 : public TemplateDefinition<4, NoThrow, Pure> {
4960 public:
4961 CaseInsensitiveCompareUC16Instr(
4962 Value* str,
4963 Value* lhs_index,
4964 Value* rhs_index,
4965 Value* length,
4966 intptr_t cid)
4967 : cid_(cid) {
4968 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid);
4969 ASSERT(index_scale() == 2);
4970 SetInputAt(0, str);
4971 SetInputAt(1, lhs_index);
4972 SetInputAt(2, rhs_index);
4973 SetInputAt(3, length);
4974 }
4975
4976 Value* str() const { return inputs_[0]; }
4977 Value* lhs_index() const { return inputs_[1]; }
4978 Value* rhs_index() const { return inputs_[2]; }
4979 Value* length() const { return inputs_[3]; }
4980
4981 const RuntimeEntry& TargetFunction() const;
4982 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; }
4983 intptr_t class_id() const { return cid_; }
4984 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); }
4985
4986 virtual bool CanDeoptimize() const { return false; }
4987
4988 virtual Representation representation() const {
4989 return kTagged;
4990 }
4991
4992 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16)
4993 virtual CompileType ComputeType() const;
4994
4995 virtual bool AttributesEqual(Instruction* other) const {
4996 return other->AsCaseInsensitiveCompareUC16()->cid_ == cid_;
4997 }
4998
4999 private:
5000 const intptr_t cid_;
5001
5002 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr);
5003 };
5004
5005
4792 // Represents Math's static min and max functions. 5006 // Represents Math's static min and max functions.
4793 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> { 5007 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> {
4794 public: 5008 public:
4795 MathMinMaxInstr(MethodRecognizer::Kind op_kind, 5009 MathMinMaxInstr(MethodRecognizer::Kind op_kind,
4796 Value* left_value, 5010 Value* left_value,
4797 Value* right_value, 5011 Value* right_value,
4798 intptr_t deopt_id, 5012 intptr_t deopt_id,
4799 intptr_t result_cid) 5013 intptr_t result_cid)
4800 : TemplateDefinition(deopt_id), 5014 : TemplateDefinition(deopt_id),
4801 op_kind_(op_kind), 5015 op_kind_(op_kind),
(...skipping 3117 matching lines...) Expand 10 before | Expand all | Expand 10 after
7919 Isolate* isolate, bool opt) const { \ 8133 Isolate* isolate, bool opt) const { \
7920 UNIMPLEMENTED(); \ 8134 UNIMPLEMENTED(); \
7921 return NULL; \ 8135 return NULL; \
7922 } \ 8136 } \
7923 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8137 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
7924 8138
7925 8139
7926 } // namespace dart 8140 } // namespace dart
7927 8141
7928 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8142 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698