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

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

Issue 539153002: Port and integrate the irregexp engine from V8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed Ivan's comments. Created 6 years, 2 months 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
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 return const_cast<BlockEntryInstr*>(this); 1211 return const_cast<BlockEntryInstr*>(this);
1208 } 1212 }
1209 1213
1210 // Helper to mutate the graph during inlining. This block should be 1214 // Helper to mutate the graph during inlining. This block should be
1211 // replaced with new_block as a predecessor of all of this block's 1215 // replaced with new_block as a predecessor of all of this block's
1212 // successors. 1216 // successors.
1213 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); 1217 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block);
1214 1218
1215 void set_block_id(intptr_t block_id) { block_id_ = block_id; } 1219 void set_block_id(intptr_t block_id) { block_id_ = block_id; }
1216 1220
1221 intptr_t offset() const { return offset_; }
1222 void set_offset(intptr_t offset) { offset_ = offset; }
1223
1217 // For all instruction in this block: Remove all inputs (including in the 1224 // For all instruction in this block: Remove all inputs (including in the
1218 // environment) from their definition's use lists for all instructions. 1225 // environment) from their definition's use lists for all instructions.
1219 void ClearAllInstructions(); 1226 void ClearAllInstructions();
1220 1227
1221 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) 1228 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
1222 1229
1223 protected: 1230 protected:
1224 BlockEntryInstr(intptr_t block_id, intptr_t try_index) 1231 BlockEntryInstr(intptr_t block_id, intptr_t try_index)
1225 : block_id_(block_id), 1232 : block_id_(block_id),
1226 try_index_(try_index), 1233 try_index_(try_index),
1227 preorder_number_(-1), 1234 preorder_number_(-1),
1228 postorder_number_(-1), 1235 postorder_number_(-1),
1229 dominator_(NULL), 1236 dominator_(NULL),
1230 dominated_blocks_(1), 1237 dominated_blocks_(1),
1231 last_instruction_(NULL), 1238 last_instruction_(NULL),
1239 offset_(-1),
1232 parallel_move_(NULL), 1240 parallel_move_(NULL),
1233 loop_info_(NULL) { 1241 loop_info_(NULL) {
1234 deopt_id_ = Isolate::Current()->GetNextDeoptId(); 1242 deopt_id_ = Isolate::Current()->GetNextDeoptId();
1235 } 1243 }
1236 1244
1237 private: 1245 private:
1238 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1246 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1239 1247
1240 virtual void ClearPredecessors() = 0; 1248 virtual void ClearPredecessors() = 0;
1241 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; 1249 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
1242 1250
1243 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 1251 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
1244 1252
1245 intptr_t block_id_; 1253 intptr_t block_id_;
1246 const intptr_t try_index_; 1254 const intptr_t try_index_;
1247 intptr_t preorder_number_; 1255 intptr_t preorder_number_;
1248 intptr_t postorder_number_; 1256 intptr_t postorder_number_;
1249 // Starting and ending lifetime positions for this block. Used by 1257 // Starting and ending lifetime positions for this block. Used by
1250 // the linear scan register allocator. 1258 // the linear scan register allocator.
1251 intptr_t start_pos_; 1259 intptr_t start_pos_;
1252 intptr_t end_pos_; 1260 intptr_t end_pos_;
1253 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 1261 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1254 // TODO(fschneider): Optimize the case of one child to save space. 1262 // TODO(fschneider): Optimize the case of one child to save space.
1255 GrowableArray<BlockEntryInstr*> dominated_blocks_; 1263 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1256 Instruction* last_instruction_; 1264 Instruction* last_instruction_;
1257 1265
1266 // Offset of this block from the start of the emitted code.
1267 intptr_t offset_;
1268
1258 // Parallel move that will be used by linear scan register allocator to 1269 // Parallel move that will be used by linear scan register allocator to
1259 // connect live ranges at the start of the block. 1270 // connect live ranges at the start of the block.
1260 ParallelMoveInstr* parallel_move_; 1271 ParallelMoveInstr* parallel_move_;
1261 1272
1262 // Bit vector containg loop blocks for a loop header indexed by block 1273 // Bit vector containg loop blocks for a loop header indexed by block
1263 // preorder number. 1274 // preorder number.
1264 BitVector* loop_info_; 1275 BitVector* loop_info_;
1265 1276
1266 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 1277 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1267 }; 1278 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 UNREACHABLE(); 1339 UNREACHABLE();
1329 return NULL; 1340 return NULL;
1330 } 1341 }
1331 virtual intptr_t SuccessorCount() const; 1342 virtual intptr_t SuccessorCount() const;
1332 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1343 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1333 1344
1334 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } 1345 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
1335 1346
1336 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1347 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1337 1348
1349 void AddIndirectEntry(IndirectEntryInstr* entry) {
1350 indirect_entries_.Add(entry);
1351 }
1352
1338 GrowableArray<Definition*>* initial_definitions() { 1353 GrowableArray<Definition*>* initial_definitions() {
1339 return &initial_definitions_; 1354 return &initial_definitions_;
1340 } 1355 }
1341 ConstantInstr* constant_null(); 1356 ConstantInstr* constant_null();
1342 1357
1343 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1358 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1344 1359
1345 intptr_t entry_count() const { return entry_count_; } 1360 intptr_t entry_count() const { return entry_count_; }
1346 void set_entry_count(intptr_t count) { entry_count_ = count; } 1361 void set_entry_count(intptr_t count) { entry_count_ = count; }
1347 1362
(...skipping 14 matching lines...) Expand all
1362 TargetEntryInstr* normal_entry() const { return normal_entry_; } 1377 TargetEntryInstr* normal_entry() const { return normal_entry_; }
1363 1378
1364 const ParsedFunction& parsed_function() const { 1379 const ParsedFunction& parsed_function() const {
1365 return *parsed_function_; 1380 return *parsed_function_;
1366 } 1381 }
1367 1382
1368 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { 1383 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
1369 return catch_entries_; 1384 return catch_entries_;
1370 } 1385 }
1371 1386
1387 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const {
1388 return indirect_entries_;
1389 }
1390
1372 virtual void PrintTo(BufferFormatter* f) const; 1391 virtual void PrintTo(BufferFormatter* f) const;
1373 1392
1374 private: 1393 private:
1375 virtual void ClearPredecessors() {} 1394 virtual void ClearPredecessors() {}
1376 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1395 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1377 1396
1378 const ParsedFunction* parsed_function_; 1397 const ParsedFunction* parsed_function_;
1379 TargetEntryInstr* normal_entry_; 1398 TargetEntryInstr* normal_entry_;
1380 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1399 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1400 // Indirect targets are blocks reachable only through indirect gotos.
1401 GrowableArray<IndirectEntryInstr*> indirect_entries_;
1381 GrowableArray<Definition*> initial_definitions_; 1402 GrowableArray<Definition*> initial_definitions_;
1382 const intptr_t osr_id_; 1403 const intptr_t osr_id_;
1383 intptr_t entry_count_; 1404 intptr_t entry_count_;
1384 intptr_t spill_slot_count_; 1405 intptr_t spill_slot_count_;
1385 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1406 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1386 1407
1387 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1408 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1388 }; 1409 };
1389 1410
1390 1411
(...skipping 25 matching lines...) Expand all
1416 virtual void PrintTo(BufferFormatter* f) const; 1437 virtual void PrintTo(BufferFormatter* f) const;
1417 1438
1418 virtual EffectSet Effects() const { return EffectSet::None(); } 1439 virtual EffectSet Effects() const { return EffectSet::None(); }
1419 virtual EffectSet Dependencies() const { return EffectSet::None(); } 1440 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1420 1441
1421 private: 1442 private:
1422 // Classes that have access to predecessors_ when inlining. 1443 // Classes that have access to predecessors_ when inlining.
1423 friend class BlockEntryInstr; 1444 friend class BlockEntryInstr;
1424 friend class InlineExitCollector; 1445 friend class InlineExitCollector;
1425 friend class PolymorphicInliner; 1446 friend class PolymorphicInliner;
1447 friend class IndirectEntryInstr; // Access in il_printer.cc.
1426 1448
1427 // Direct access to phis_ in order to resize it due to phi elimination. 1449 // Direct access to phis_ in order to resize it due to phi elimination.
1428 friend class ConstantPropagator; 1450 friend class ConstantPropagator;
1429 friend class DeadCodeElimination; 1451 friend class DeadCodeElimination;
1430 1452
1431 virtual void ClearPredecessors() { predecessors_.Clear(); } 1453 virtual void ClearPredecessors() { predecessors_.Clear(); }
1432 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1454 virtual void AddPredecessor(BlockEntryInstr* predecessor);
1433 1455
1434 GrowableArray<BlockEntryInstr*> predecessors_; 1456 GrowableArray<BlockEntryInstr*> predecessors_;
1435 ZoneGrowableArray<PhiInstr*>* phis_; 1457 ZoneGrowableArray<PhiInstr*>* phis_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 predecessor_ = predecessor; 1516 predecessor_ = predecessor;
1495 } 1517 }
1496 1518
1497 BlockEntryInstr* predecessor_; 1519 BlockEntryInstr* predecessor_;
1498 double edge_weight_; 1520 double edge_weight_;
1499 1521
1500 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1522 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1501 }; 1523 };
1502 1524
1503 1525
1526 class IndirectEntryInstr : public JoinEntryInstr {
1527 public:
1528 IndirectEntryInstr(intptr_t block_id,
1529 intptr_t indirect_id,
1530 intptr_t try_index)
1531 : JoinEntryInstr(block_id, try_index),
1532 indirect_id_(indirect_id) { }
1533
1534 DECLARE_INSTRUCTION(IndirectEntry)
1535
1536 virtual void PrintTo(BufferFormatter* f) const;
1537
1538 intptr_t indirect_id() const { return indirect_id_; }
1539
1540 private:
1541 const intptr_t indirect_id_;
1542 };
1543
1544
1504 class CatchBlockEntryInstr : public BlockEntryInstr { 1545 class CatchBlockEntryInstr : public BlockEntryInstr {
1505 public: 1546 public:
1506 CatchBlockEntryInstr(intptr_t block_id, 1547 CatchBlockEntryInstr(intptr_t block_id,
1507 intptr_t try_index, 1548 intptr_t try_index,
1508 const Array& handler_types, 1549 const Array& handler_types,
1509 intptr_t catch_try_index, 1550 intptr_t catch_try_index,
1510 const LocalVariable& exception_var, 1551 const LocalVariable& exception_var,
1511 const LocalVariable& stacktrace_var, 1552 const LocalVariable& stacktrace_var,
1512 bool needs_stacktrace) 1553 bool needs_stacktrace)
1513 : BlockEntryInstr(block_id, try_index), 1554 : BlockEntryInstr(block_id, try_index),
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
2181 private: 2222 private:
2182 JoinEntryInstr* successor_; 2223 JoinEntryInstr* successor_;
2183 double edge_weight_; 2224 double edge_weight_;
2184 2225
2185 // Parallel move that will be used by linear scan register allocator to 2226 // Parallel move that will be used by linear scan register allocator to
2186 // connect live ranges at the end of the block and resolve phis. 2227 // connect live ranges at the end of the block and resolve phis.
2187 ParallelMoveInstr* parallel_move_; 2228 ParallelMoveInstr* parallel_move_;
2188 }; 2229 };
2189 2230
2190 2231
2232 // As a high level description, an indirect goto takes the indirect_id of an
2233 // indirect entry as a parameter, and jumps to that location.
2234 //
2235 // In more detail: in order to preserve split-edge form, an intermediate target
2236 // entry consisting of a goto to the final indirect entry is inserted on
2237 // each possible indirect goto -> indirect entry edge. These target entries are
2238 // accessible through successors_.
2239 //
2240 // Byte offsets of all possible indirect targets are stored in the offsets_
2241 // array. The desired offset is looked up while the generated code is executing,
2242 // and passed to IndirectGoto as an input.
2243 class IndirectGotoInstr : public TemplateInstruction<1> {
2244 public:
2245 IndirectGotoInstr(GrowableObjectArray* offsets,
2246 Value* offset_from_start)
2247 : offsets_(*offsets) {
2248 SetInputAt(0, offset_from_start);
2249 }
2250
2251 DECLARE_INSTRUCTION(IndirectGoto)
2252
2253 virtual intptr_t ArgumentCount() const { return 0; }
2254
2255 void AddSuccessor(TargetEntryInstr* successor) {
2256 ASSERT(successor->next()->IsGoto());
2257 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
2258 successors_.Add(successor);
2259 }
2260
2261 virtual intptr_t SuccessorCount() const { return successors_.length(); }
2262 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const {
2263 ASSERT(index < SuccessorCount());
2264 return successors_[index];
2265 }
2266
2267 virtual bool CanDeoptimize() const { return false; }
2268 virtual bool CanBecomeDeoptimizationTarget() const { return false; }
2269
2270 virtual EffectSet Effects() const { return EffectSet::None(); }
2271
2272 virtual void PrintTo(BufferFormatter* f) const;
2273
2274 virtual bool MayThrow() const { return false; }
2275
2276 const GrowableObjectArray& offsets() const { return offsets_; }
2277 void SetOffsetCount(Isolate* isolate, intptr_t count) {
2278 if (offsets_.Capacity() < count) {
2279 offsets_.Grow(count, Heap::kOld);
2280 }
2281 if (offsets_.Length() < count) {
2282 offsets_.SetLength(count);
2283 }
2284 }
2285 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) {
2286 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset)));
2287 }
2288
2289 private:
2290 GrowableArray<TargetEntryInstr*> successors_;
2291 GrowableObjectArray& offsets_;
2292 };
2293
2294
2191 class ComparisonInstr : public TemplateDefinition<2> { 2295 class ComparisonInstr : public TemplateDefinition<2> {
2192 public: 2296 public:
2193 Value* left() const { return inputs_[0]; } 2297 Value* left() const { return inputs_[0]; }
2194 Value* right() const { return inputs_[1]; } 2298 Value* right() const { return inputs_[1]; }
2195 2299
2196 virtual intptr_t token_pos() const { return token_pos_; } 2300 virtual intptr_t token_pos() const { return token_pos_; }
2197 Token::Kind kind() const { return kind_; } 2301 Token::Kind kind() const { return kind_; }
2198 2302
2199 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; 2303 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2200 2304
(...skipping 1604 matching lines...) Expand 10 before | Expand all | Expand 10 after
3805 3909
3806 private: 3910 private:
3807 const intptr_t index_scale_; 3911 const intptr_t index_scale_;
3808 const intptr_t class_id_; 3912 const intptr_t class_id_;
3809 const intptr_t token_pos_; 3913 const intptr_t token_pos_;
3810 3914
3811 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3915 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3812 }; 3916 };
3813 3917
3814 3918
3919 // Loads the specified number of code units from the given string, packing
3920 // multiple code units into a single datatype. In essence, this is a specialized
3921 // version of LoadIndexedInstr which accepts only string targets and can load
3922 // multiple elements at once. The result datatype differs depending on the
3923 // string type, element count, and architecture; if possible, the result is
3924 // packed into a Smi, falling back to a Mint otherwise.
3925 // TODO(jgruber): Add support for loading into UnboxedInt32x4.
3926 class LoadCodeUnitsInstr : public TemplateDefinition<2> {
3927 public:
3928 LoadCodeUnitsInstr(Value* str,
3929 Value* index,
3930 intptr_t element_count,
3931 intptr_t class_id,
3932 intptr_t token_pos)
3933 : class_id_(class_id),
3934 token_pos_(token_pos),
3935 element_count_(element_count) {
3936 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
3937 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid);
3938 SetInputAt(0, str);
3939 SetInputAt(1, index);
3940 }
3941
3942 intptr_t token_pos() const { return token_pos_; }
3943
3944 DECLARE_INSTRUCTION(LoadCodeUnits)
3945 virtual CompileType ComputeType() const;
3946
3947 bool IsExternal() const {
3948 return array()->definition()->representation() == kUntagged;
3949 }
3950
3951 Value* array() const { return inputs_[0]; }
3952 Value* index() const { return inputs_[1]; }
3953 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); }
3954 intptr_t class_id() const { return class_id_; }
3955 intptr_t element_count() const { return element_count_; }
3956
3957 bool can_pack_into_smi() const {
3958 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte);
3959 }
3960
3961 virtual bool CanDeoptimize() const { return false; }
3962
3963 virtual Representation representation() const;
3964 virtual void InferRange(RangeAnalysis* analysis, Range* range);
3965
3966 virtual bool AllowsCSE() const { return false; }
3967 virtual EffectSet Effects() const { return EffectSet::None(); }
3968 virtual EffectSet Dependencies() const { return EffectSet::All(); }
3969 virtual bool AttributesEqual(Instruction* other) const;
3970
3971 virtual bool MayThrow() const { return false; }
3972
3973 private:
3974 const intptr_t class_id_;
3975 const intptr_t token_pos_;
3976 const intptr_t element_count_;
3977
3978 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr);
3979 };
3980
3981
3815 class StringFromCharCodeInstr : public TemplateDefinition<1> { 3982 class StringFromCharCodeInstr : public TemplateDefinition<1> {
3816 public: 3983 public:
3817 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3984 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3818 ASSERT(char_code != NULL); 3985 ASSERT(char_code != NULL);
3819 ASSERT(char_code->definition()->IsLoadIndexed()); 3986 ASSERT(char_code->definition()->IsLoadIndexed());
3820 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == 3987 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
3821 kOneByteStringCid); 3988 kOneByteStringCid);
3822 SetInputAt(0, char_code); 3989 SetInputAt(0, char_code);
3823 } 3990 }
3824 3991
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after
5039 5206
5040 static const char* KindToCString(MathUnaryKind kind); 5207 static const char* KindToCString(MathUnaryKind kind);
5041 5208
5042 private: 5209 private:
5043 const MathUnaryKind kind_; 5210 const MathUnaryKind kind_;
5044 5211
5045 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); 5212 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr);
5046 }; 5213 };
5047 5214
5048 5215
5216 // Calls into the runtime and performs a case-insensitive comparison of the
5217 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at
5218 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length].
5219 //
5220 // TODO(jgruber): Remove this once (if) functions inherited from unibrow
5221 // are moved to dart code.
5222 class CaseInsensitiveCompareUC16Instr : public TemplateDefinition<4> {
5223 public:
5224 CaseInsensitiveCompareUC16Instr(
5225 Value* str,
5226 Value* lhs_index,
5227 Value* rhs_index,
5228 Value* length,
5229 intptr_t cid)
5230 : cid_(cid) {
5231 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid);
5232 ASSERT(index_scale() == 2);
5233 SetInputAt(0, str);
5234 SetInputAt(1, lhs_index);
5235 SetInputAt(2, rhs_index);
5236 SetInputAt(3, length);
5237 }
5238
5239 Value* str() const { return inputs_[0]; }
5240 Value* lhs_index() const { return inputs_[1]; }
5241 Value* rhs_index() const { return inputs_[2]; }
5242 Value* length() const { return inputs_[3]; }
5243
5244 const RuntimeEntry& TargetFunction() const;
5245 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; }
5246 intptr_t class_id() const { return cid_; }
5247 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); }
5248
5249 virtual bool CanDeoptimize() const { return false; }
5250
5251 virtual Representation representation() const {
5252 return kTagged;
5253 }
5254
5255 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16)
5256 virtual CompileType ComputeType() const;
5257
5258 virtual bool AllowsCSE() const { return true; }
5259 virtual EffectSet Effects() const { return EffectSet::None(); }
5260 virtual EffectSet Dependencies() const { return EffectSet::None(); }
5261
5262 virtual bool MayThrow() const { return false; }
5263
5264 private:
5265 const intptr_t cid_;
5266
5267 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr);
5268 };
5269
5270
5049 // Represents Math's static min and max functions. 5271 // Represents Math's static min and max functions.
5050 class MathMinMaxInstr : public TemplateDefinition<2> { 5272 class MathMinMaxInstr : public TemplateDefinition<2> {
5051 public: 5273 public:
5052 MathMinMaxInstr(MethodRecognizer::Kind op_kind, 5274 MathMinMaxInstr(MethodRecognizer::Kind op_kind,
5053 Value* left_value, 5275 Value* left_value,
5054 Value* right_value, 5276 Value* right_value,
5055 intptr_t deopt_id, 5277 intptr_t deopt_id,
5056 intptr_t result_cid) 5278 intptr_t result_cid)
5057 : op_kind_(op_kind), result_cid_(result_cid) { 5279 : op_kind_(op_kind), result_cid_(result_cid) {
5058 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid)); 5280 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid));
(...skipping 3381 matching lines...) Expand 10 before | Expand all | Expand 10 after
8440 Isolate* isolate, bool opt) const { \ 8662 Isolate* isolate, bool opt) const { \
8441 UNIMPLEMENTED(); \ 8663 UNIMPLEMENTED(); \
8442 return NULL; \ 8664 return NULL; \
8443 } \ 8665 } \
8444 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8666 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
8445 8667
8446 8668
8447 } // namespace dart 8669 } // namespace dart
8448 8670
8449 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8671 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698