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

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: Do not break JSCRE build, pt 2. 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
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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 417
418 // Instructions. 418 // Instructions.
419 419
420 // M is a single argument macro. It is applied to each concrete instruction 420 // M is a single argument macro. It is applied to each concrete instruction
421 // type name. The concrete instruction classes are the name with Instr 421 // type name. The concrete instruction classes are the name with Instr
422 // concatenated. 422 // concatenated.
423 #define FOR_EACH_INSTRUCTION(M) \ 423 #define FOR_EACH_INSTRUCTION(M) \
424 M(GraphEntry) \ 424 M(GraphEntry) \
425 M(JoinEntry) \ 425 M(JoinEntry) \
426 M(TargetEntry) \ 426 M(TargetEntry) \
427 M(IndirectEntry) \
427 M(CatchBlockEntry) \ 428 M(CatchBlockEntry) \
428 M(Phi) \ 429 M(Phi) \
429 M(Redefinition) \ 430 M(Redefinition) \
430 M(Parameter) \ 431 M(Parameter) \
431 M(ParallelMove) \ 432 M(ParallelMove) \
432 M(PushArgument) \ 433 M(PushArgument) \
433 M(Return) \ 434 M(Return) \
434 M(Throw) \ 435 M(Throw) \
435 M(ReThrow) \ 436 M(ReThrow) \
436 M(Goto) \ 437 M(Goto) \
438 M(IndirectGoto) \
437 M(Branch) \ 439 M(Branch) \
438 M(AssertAssignable) \ 440 M(AssertAssignable) \
439 M(AssertBoolean) \ 441 M(AssertBoolean) \
440 M(CurrentContext) \ 442 M(CurrentContext) \
441 M(StoreContext) \ 443 M(StoreContext) \
442 M(ClosureCall) \ 444 M(ClosureCall) \
443 M(InstanceCall) \ 445 M(InstanceCall) \
444 M(PolymorphicInstanceCall) \ 446 M(PolymorphicInstanceCall) \
445 M(StaticCall) \ 447 M(StaticCall) \
446 M(LoadLocal) \ 448 M(LoadLocal) \
447 M(PushTemp) \ 449 M(PushTemp) \
448 M(DropTemps) \ 450 M(DropTemps) \
449 M(StoreLocal) \ 451 M(StoreLocal) \
450 M(StrictCompare) \ 452 M(StrictCompare) \
451 M(EqualityCompare) \ 453 M(EqualityCompare) \
452 M(RelationalOp) \ 454 M(RelationalOp) \
453 M(NativeCall) \ 455 M(NativeCall) \
454 M(DebugStepCheck) \ 456 M(DebugStepCheck) \
455 M(LoadIndexed) \ 457 M(LoadIndexed) \
458 M(LoadCodeUnits) \
456 M(StoreIndexed) \ 459 M(StoreIndexed) \
457 M(StoreInstanceField) \ 460 M(StoreInstanceField) \
458 M(InitStaticField) \ 461 M(InitStaticField) \
459 M(LoadStaticField) \ 462 M(LoadStaticField) \
460 M(StoreStaticField) \ 463 M(StoreStaticField) \
461 M(BooleanNegate) \ 464 M(BooleanNegate) \
462 M(InstanceOf) \ 465 M(InstanceOf) \
463 M(CreateArray) \ 466 M(CreateArray) \
464 M(AllocateObject) \ 467 M(AllocateObject) \
465 M(LoadField) \ 468 M(LoadField) \
(...skipping 19 matching lines...) Expand all
485 M(FloatToDouble) \ 488 M(FloatToDouble) \
486 M(CheckClass) \ 489 M(CheckClass) \
487 M(CheckClassId) \ 490 M(CheckClassId) \
488 M(CheckSmi) \ 491 M(CheckSmi) \
489 M(Constant) \ 492 M(Constant) \
490 M(UnboxedConstant) \ 493 M(UnboxedConstant) \
491 M(CheckEitherNonSmi) \ 494 M(CheckEitherNonSmi) \
492 M(BinaryDoubleOp) \ 495 M(BinaryDoubleOp) \
493 M(MathUnary) \ 496 M(MathUnary) \
494 M(MathMinMax) \ 497 M(MathMinMax) \
498 M(CaseInsensitiveCompareUC16) \
495 M(UnboxDouble) \ 499 M(UnboxDouble) \
496 M(BoxDouble) \ 500 M(BoxDouble) \
497 M(BoxFloat32x4) \ 501 M(BoxFloat32x4) \
498 M(UnboxFloat32x4) \ 502 M(UnboxFloat32x4) \
499 M(BoxInt32x4) \ 503 M(BoxInt32x4) \
500 M(UnboxInt32x4) \ 504 M(UnboxInt32x4) \
501 M(UnboxInteger) \ 505 M(UnboxInteger) \
502 M(BoxInteger) \ 506 M(BoxInteger) \
503 M(BinaryMintOp) \ 507 M(BinaryMintOp) \
504 M(ShiftMintOp) \ 508 M(ShiftMintOp) \
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 return const_cast<BlockEntryInstr*>(this); 1205 return const_cast<BlockEntryInstr*>(this);
1202 } 1206 }
1203 1207
1204 // Helper to mutate the graph during inlining. This block should be 1208 // Helper to mutate the graph during inlining. This block should be
1205 // replaced with new_block as a predecessor of all of this block's 1209 // replaced with new_block as a predecessor of all of this block's
1206 // successors. 1210 // successors.
1207 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); 1211 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block);
1208 1212
1209 void set_block_id(intptr_t block_id) { block_id_ = block_id; } 1213 void set_block_id(intptr_t block_id) { block_id_ = block_id; }
1210 1214
1215 intptr_t offset() const { return offset_; }
1216 void set_offset(intptr_t offset) { offset_ = offset; }
1217
1211 // For all instruction in this block: Remove all inputs (including in the 1218 // For all instruction in this block: Remove all inputs (including in the
1212 // environment) from their definition's use lists for all instructions. 1219 // environment) from their definition's use lists for all instructions.
1213 void ClearAllInstructions(); 1220 void ClearAllInstructions();
1214 1221
1215 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) 1222 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
1216 1223
1217 protected: 1224 protected:
1218 BlockEntryInstr(intptr_t block_id, intptr_t try_index) 1225 BlockEntryInstr(intptr_t block_id, intptr_t try_index)
1219 : block_id_(block_id), 1226 : block_id_(block_id),
1220 try_index_(try_index), 1227 try_index_(try_index),
1221 preorder_number_(-1), 1228 preorder_number_(-1),
1222 postorder_number_(-1), 1229 postorder_number_(-1),
1223 dominator_(NULL), 1230 dominator_(NULL),
1224 dominated_blocks_(1), 1231 dominated_blocks_(1),
1225 last_instruction_(NULL), 1232 last_instruction_(NULL),
1233 offset_(-1),
1226 parallel_move_(NULL), 1234 parallel_move_(NULL),
1227 loop_info_(NULL) { 1235 loop_info_(NULL) {
1228 deopt_id_ = Isolate::Current()->GetNextDeoptId(); 1236 deopt_id_ = Isolate::Current()->GetNextDeoptId();
1229 } 1237 }
1230 1238
1231 private: 1239 private:
1232 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1240 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1233 1241
1234 virtual void ClearPredecessors() = 0; 1242 virtual void ClearPredecessors() = 0;
1235 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; 1243 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
1236 1244
1237 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 1245 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
1238 1246
1239 intptr_t block_id_; 1247 intptr_t block_id_;
1240 const intptr_t try_index_; 1248 const intptr_t try_index_;
1241 intptr_t preorder_number_; 1249 intptr_t preorder_number_;
1242 intptr_t postorder_number_; 1250 intptr_t postorder_number_;
1243 // Starting and ending lifetime positions for this block. Used by 1251 // Starting and ending lifetime positions for this block. Used by
1244 // the linear scan register allocator. 1252 // the linear scan register allocator.
1245 intptr_t start_pos_; 1253 intptr_t start_pos_;
1246 intptr_t end_pos_; 1254 intptr_t end_pos_;
1247 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 1255 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1248 // TODO(fschneider): Optimize the case of one child to save space. 1256 // TODO(fschneider): Optimize the case of one child to save space.
1249 GrowableArray<BlockEntryInstr*> dominated_blocks_; 1257 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1250 Instruction* last_instruction_; 1258 Instruction* last_instruction_;
1251 1259
1260 // Offset of this block from the start of the emitted code.
1261 intptr_t offset_;
1262
1252 // Parallel move that will be used by linear scan register allocator to 1263 // Parallel move that will be used by linear scan register allocator to
1253 // connect live ranges at the start of the block. 1264 // connect live ranges at the start of the block.
1254 ParallelMoveInstr* parallel_move_; 1265 ParallelMoveInstr* parallel_move_;
1255 1266
1256 // Bit vector containg loop blocks for a loop header indexed by block 1267 // Bit vector containg loop blocks for a loop header indexed by block
1257 // preorder number. 1268 // preorder number.
1258 BitVector* loop_info_; 1269 BitVector* loop_info_;
1259 1270
1260 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 1271 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1261 }; 1272 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 UNREACHABLE(); 1333 UNREACHABLE();
1323 return NULL; 1334 return NULL;
1324 } 1335 }
1325 virtual intptr_t SuccessorCount() const; 1336 virtual intptr_t SuccessorCount() const;
1326 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1337 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1327 1338
1328 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } 1339 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
1329 1340
1330 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1341 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1331 1342
1343 void AddIndirectEntry(IndirectEntryInstr* entry) {
1344 indirect_entries_.Add(entry);
1345 }
1346
1332 GrowableArray<Definition*>* initial_definitions() { 1347 GrowableArray<Definition*>* initial_definitions() {
1333 return &initial_definitions_; 1348 return &initial_definitions_;
1334 } 1349 }
1335 ConstantInstr* constant_null(); 1350 ConstantInstr* constant_null();
1336 1351
1337 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1352 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1338 1353
1339 intptr_t entry_count() const { return entry_count_; } 1354 intptr_t entry_count() const { return entry_count_; }
1340 void set_entry_count(intptr_t count) { entry_count_ = count; } 1355 void set_entry_count(intptr_t count) { entry_count_ = count; }
1341 1356
(...skipping 14 matching lines...) Expand all
1356 TargetEntryInstr* normal_entry() const { return normal_entry_; } 1371 TargetEntryInstr* normal_entry() const { return normal_entry_; }
1357 1372
1358 const ParsedFunction& parsed_function() const { 1373 const ParsedFunction& parsed_function() const {
1359 return *parsed_function_; 1374 return *parsed_function_;
1360 } 1375 }
1361 1376
1362 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { 1377 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
1363 return catch_entries_; 1378 return catch_entries_;
1364 } 1379 }
1365 1380
1381 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const {
1382 return indirect_entries_;
1383 }
1384
1366 virtual void PrintTo(BufferFormatter* f) const; 1385 virtual void PrintTo(BufferFormatter* f) const;
1367 1386
1368 private: 1387 private:
1369 virtual void ClearPredecessors() {} 1388 virtual void ClearPredecessors() {}
1370 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1389 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1371 1390
1372 const ParsedFunction* parsed_function_; 1391 const ParsedFunction* parsed_function_;
1373 TargetEntryInstr* normal_entry_; 1392 TargetEntryInstr* normal_entry_;
1374 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1393 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1394 // Indirect targets are blocks reachable only through indirect gotos.
1395 GrowableArray<IndirectEntryInstr*> indirect_entries_;
1375 GrowableArray<Definition*> initial_definitions_; 1396 GrowableArray<Definition*> initial_definitions_;
1376 const intptr_t osr_id_; 1397 const intptr_t osr_id_;
1377 intptr_t entry_count_; 1398 intptr_t entry_count_;
1378 intptr_t spill_slot_count_; 1399 intptr_t spill_slot_count_;
1379 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1400 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1380 1401
1381 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1402 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1382 }; 1403 };
1383 1404
1384 1405
(...skipping 25 matching lines...) Expand all
1410 virtual void PrintTo(BufferFormatter* f) const; 1431 virtual void PrintTo(BufferFormatter* f) const;
1411 1432
1412 virtual EffectSet Effects() const { return EffectSet::None(); } 1433 virtual EffectSet Effects() const { return EffectSet::None(); }
1413 virtual EffectSet Dependencies() const { return EffectSet::None(); } 1434 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1414 1435
1415 private: 1436 private:
1416 // Classes that have access to predecessors_ when inlining. 1437 // Classes that have access to predecessors_ when inlining.
1417 friend class BlockEntryInstr; 1438 friend class BlockEntryInstr;
1418 friend class InlineExitCollector; 1439 friend class InlineExitCollector;
1419 friend class PolymorphicInliner; 1440 friend class PolymorphicInliner;
1441 friend class IndirectEntryInstr; // Access in il_printer.cc.
1420 1442
1421 // Direct access to phis_ in order to resize it due to phi elimination. 1443 // Direct access to phis_ in order to resize it due to phi elimination.
1422 friend class ConstantPropagator; 1444 friend class ConstantPropagator;
1423 friend class DeadCodeElimination; 1445 friend class DeadCodeElimination;
1424 1446
1425 virtual void ClearPredecessors() { predecessors_.Clear(); } 1447 virtual void ClearPredecessors() { predecessors_.Clear(); }
1426 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1448 virtual void AddPredecessor(BlockEntryInstr* predecessor);
1427 1449
1428 GrowableArray<BlockEntryInstr*> predecessors_; 1450 GrowableArray<BlockEntryInstr*> predecessors_;
1429 ZoneGrowableArray<PhiInstr*>* phis_; 1451 ZoneGrowableArray<PhiInstr*>* phis_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 predecessor_ = predecessor; 1510 predecessor_ = predecessor;
1489 } 1511 }
1490 1512
1491 BlockEntryInstr* predecessor_; 1513 BlockEntryInstr* predecessor_;
1492 double edge_weight_; 1514 double edge_weight_;
1493 1515
1494 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1516 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1495 }; 1517 };
1496 1518
1497 1519
1520 class IndirectEntryInstr : public JoinEntryInstr {
1521 public:
1522 IndirectEntryInstr(intptr_t block_id,
1523 intptr_t indirect_id,
1524 intptr_t try_index)
1525 : JoinEntryInstr(block_id, try_index),
1526 indirect_id_(indirect_id) { }
1527
1528 DECLARE_INSTRUCTION(IndirectEntry)
1529
1530 virtual void PrintTo(BufferFormatter* f) const;
1531
1532 intptr_t indirect_id() const { return indirect_id_; }
1533
1534 private:
1535 const intptr_t indirect_id_;
1536 };
1537
1538
1498 class CatchBlockEntryInstr : public BlockEntryInstr { 1539 class CatchBlockEntryInstr : public BlockEntryInstr {
1499 public: 1540 public:
1500 CatchBlockEntryInstr(intptr_t block_id, 1541 CatchBlockEntryInstr(intptr_t block_id,
1501 intptr_t try_index, 1542 intptr_t try_index,
1502 const Array& handler_types, 1543 const Array& handler_types,
1503 intptr_t catch_try_index, 1544 intptr_t catch_try_index,
1504 const LocalVariable& exception_var, 1545 const LocalVariable& exception_var,
1505 const LocalVariable& stacktrace_var, 1546 const LocalVariable& stacktrace_var,
1506 bool needs_stacktrace) 1547 bool needs_stacktrace)
1507 : BlockEntryInstr(block_id, try_index), 1548 : BlockEntryInstr(block_id, try_index),
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 private: 2203 private:
2163 JoinEntryInstr* successor_; 2204 JoinEntryInstr* successor_;
2164 double edge_weight_; 2205 double edge_weight_;
2165 2206
2166 // Parallel move that will be used by linear scan register allocator to 2207 // Parallel move that will be used by linear scan register allocator to
2167 // connect live ranges at the end of the block and resolve phis. 2208 // connect live ranges at the end of the block and resolve phis.
2168 ParallelMoveInstr* parallel_move_; 2209 ParallelMoveInstr* parallel_move_;
2169 }; 2210 };
2170 2211
2171 2212
2213 // As a high level description, an indirect goto takes the indirect_id of an
2214 // indirect entry as a parameter, and jumps to that location.
2215 //
2216 // In more detail: in order to preserve split-edge form, an intermediate target
2217 // entry consisting of a goto to the final indirect entry is inserted on
2218 // each possible indirect goto -> indirect entry edge. These target entries are
2219 // accessible through successors_.
2220 //
2221 // Byte offsets of all possible indirect targets are stored in the offsets_
2222 // array and are looked up at runtime.
Ivan Posva 2014/10/09 09:54:15 It is not clear what runtime means here. While exe
jgruber1 2014/10/09 13:36:16 Yes. Clarified the comment.
2223 class IndirectGotoInstr : public TemplateInstruction<1> {
2224 public:
2225 IndirectGotoInstr(GrowableObjectArray* offsets,
2226 Value* offset_from_start)
2227 : offsets_(*offsets) {
2228 SetInputAt(0, offset_from_start);
2229 }
2230
2231 DECLARE_INSTRUCTION(IndirectGoto)
2232
2233 virtual intptr_t ArgumentCount() const { return 0; }
2234
2235 void AddSuccessor(TargetEntryInstr* successor) {
2236 ASSERT(successor->next()->IsGoto());
2237 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
2238 successors_.Add(successor);
2239 }
2240
2241 virtual intptr_t SuccessorCount() const { return successors_.length(); }
2242 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const {
2243 ASSERT(index < SuccessorCount());
2244 return successors_[index];
2245 }
2246
2247 virtual bool CanDeoptimize() const { return false; }
2248 virtual bool CanBecomeDeoptimizationTarget() const { return false; }
2249
2250 virtual EffectSet Effects() const { return EffectSet::None(); }
2251
2252 virtual void PrintTo(BufferFormatter* f) const;
2253
2254 virtual bool MayThrow() const { return false; }
2255
2256 const GrowableObjectArray& offsets() const { return offsets_; }
2257 void SetOffsetCount(Isolate* isolate, intptr_t count) {
2258 if (offsets_.Capacity() < count) {
2259 offsets_.Grow(count, Heap::kOld);
2260 }
2261 if (offsets_.Length() < count) {
2262 offsets_.SetLength(count);
2263 }
2264 }
2265 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) {
2266 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset)));
2267 }
2268
2269 private:
2270 GrowableArray<TargetEntryInstr*> successors_;
2271 GrowableObjectArray& offsets_;
2272 };
2273
2274
2172 class ComparisonInstr : public TemplateDefinition<2> { 2275 class ComparisonInstr : public TemplateDefinition<2> {
2173 public: 2276 public:
2174 Value* left() const { return inputs_[0]; } 2277 Value* left() const { return inputs_[0]; }
2175 Value* right() const { return inputs_[1]; } 2278 Value* right() const { return inputs_[1]; }
2176 2279
2177 virtual intptr_t token_pos() const { return token_pos_; } 2280 virtual intptr_t token_pos() const { return token_pos_; }
2178 Token::Kind kind() const { return kind_; } 2281 Token::Kind kind() const { return kind_; }
2179 2282
2180 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; 2283 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2181 2284
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after
3800 3903
3801 private: 3904 private:
3802 const intptr_t index_scale_; 3905 const intptr_t index_scale_;
3803 const intptr_t class_id_; 3906 const intptr_t class_id_;
3804 const intptr_t token_pos_; 3907 const intptr_t token_pos_;
3805 3908
3806 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3909 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3807 }; 3910 };
3808 3911
3809 3912
3913 // Loads the specified number of code units from the given string, packing
3914 // multiple code units into a single datatype. In essence, this is a specialized
3915 // version of LoadIndexedInstr which accepts only string targets and can load
3916 // multiple elements at once. The result datatype differs depending on the
3917 // string type, element count, and architecture; if possible, the result is
3918 // packed into a Smi, falling back to a Mint otherwise.
3919 // TODO(jgruber): Add support for loading into UnboxedInt32x4.
3920 class LoadCodeUnitsInstr : public TemplateDefinition<2> {
3921 public:
3922 LoadCodeUnitsInstr(Value* array,
Ivan Posva 2014/10/09 09:54:15 Why do we need a special instruction here? Can't t
jgruber1 2014/10/09 13:36:16 The instruction is needed because the correspondin
3923 Value* index,
3924 intptr_t element_count,
3925 intptr_t class_id,
3926 intptr_t token_pos)
3927 : class_id_(class_id),
3928 token_pos_(token_pos),
3929 element_count_(element_count) {
3930 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
3931 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid);
3932 SetInputAt(0, array);
3933 SetInputAt(1, index);
3934 }
3935
3936 intptr_t token_pos() const { return token_pos_; }
3937
3938 DECLARE_INSTRUCTION(LoadCodeUnits)
3939 virtual CompileType ComputeType() const;
3940
3941 bool IsExternal() const {
3942 return array()->definition()->representation() == kUntagged;
3943 }
3944
3945 Value* array() const { return inputs_[0]; }
3946 Value* index() const { return inputs_[1]; }
3947 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); }
3948 intptr_t class_id() const { return class_id_; }
3949 intptr_t element_count() const { return element_count_; }
3950
3951 bool can_pack_into_smi() const {
3952 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte);
3953 }
3954
3955 virtual bool CanDeoptimize() const { return false; }
3956
3957 virtual Representation representation() const;
3958 virtual void InferRange(RangeAnalysis* analysis, Range* range);
3959
3960 virtual bool AllowsCSE() const { return false; }
3961 virtual EffectSet Effects() const { return EffectSet::None(); }
3962 virtual EffectSet Dependencies() const { return EffectSet::All(); }
3963 virtual bool AttributesEqual(Instruction* other) const;
3964
3965 virtual bool MayThrow() const { return false; }
3966
3967 private:
3968 const intptr_t class_id_;
3969 const intptr_t token_pos_;
3970 const intptr_t element_count_;
3971
3972 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr);
3973 };
3974
3975
3810 class StringFromCharCodeInstr : public TemplateDefinition<1> { 3976 class StringFromCharCodeInstr : public TemplateDefinition<1> {
3811 public: 3977 public:
3812 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3978 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3813 ASSERT(char_code != NULL); 3979 ASSERT(char_code != NULL);
3814 ASSERT(char_code->definition()->IsLoadIndexed()); 3980 ASSERT(char_code->definition()->IsLoadIndexed());
3815 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == 3981 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
3816 kOneByteStringCid); 3982 kOneByteStringCid);
3817 SetInputAt(0, char_code); 3983 SetInputAt(0, char_code);
3818 } 3984 }
3819 3985
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after
5034 5200
5035 static const char* KindToCString(MathUnaryKind kind); 5201 static const char* KindToCString(MathUnaryKind kind);
5036 5202
5037 private: 5203 private:
5038 const MathUnaryKind kind_; 5204 const MathUnaryKind kind_;
5039 5205
5040 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); 5206 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr);
5041 }; 5207 };
5042 5208
5043 5209
5210 // Calls into the runtime and performs a case-insensitive comparison of the
5211 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at
5212 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length].
5213 //
5214 // TODO(jgruber): Remove this once (if) functions inherited from unibrow
5215 // are moved to dart code.
5216 class CaseInsensitiveCompareUC16Instr : public TemplateDefinition<4> {
5217 public:
5218 CaseInsensitiveCompareUC16Instr(
5219 Value* str,
5220 Value* lhs_index,
5221 Value* rhs_index,
5222 Value* length,
5223 intptr_t cid)
5224 : cid_(cid) {
5225 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid);
5226 ASSERT(index_scale() == 2);
5227 SetInputAt(0, str);
5228 SetInputAt(1, lhs_index);
5229 SetInputAt(2, rhs_index);
5230 SetInputAt(3, length);
5231 }
5232
5233 Value* str() const { return inputs_[0]; }
5234 Value* lhs_index() const { return inputs_[1]; }
5235 Value* rhs_index() const { return inputs_[2]; }
5236 Value* length() const { return inputs_[3]; }
5237
5238 const RuntimeEntry& TargetFunction() const;
5239 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; }
5240 intptr_t class_id() const { return cid_; }
5241 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); }
5242
5243 virtual bool CanDeoptimize() const { return false; }
5244
5245 virtual Representation representation() const {
5246 return kTagged;
5247 }
5248
5249 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16)
5250 virtual CompileType ComputeType() const;
5251
5252 virtual bool AllowsCSE() const { return true; }
5253 virtual EffectSet Effects() const { return EffectSet::None(); }
5254 virtual EffectSet Dependencies() const { return EffectSet::None(); }
5255
5256 virtual bool MayThrow() const { return false; }
5257
5258 private:
5259 const intptr_t cid_;
5260
5261 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr);
5262 };
5263
5264
5044 // Represents Math's static min and max functions. 5265 // Represents Math's static min and max functions.
5045 class MathMinMaxInstr : public TemplateDefinition<2> { 5266 class MathMinMaxInstr : public TemplateDefinition<2> {
5046 public: 5267 public:
5047 MathMinMaxInstr(MethodRecognizer::Kind op_kind, 5268 MathMinMaxInstr(MethodRecognizer::Kind op_kind,
5048 Value* left_value, 5269 Value* left_value,
5049 Value* right_value, 5270 Value* right_value,
5050 intptr_t deopt_id, 5271 intptr_t deopt_id,
5051 intptr_t result_cid) 5272 intptr_t result_cid)
5052 : op_kind_(op_kind), result_cid_(result_cid) { 5273 : op_kind_(op_kind), result_cid_(result_cid) {
5053 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid)); 5274 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid));
(...skipping 3355 matching lines...) Expand 10 before | Expand all | Expand 10 after
8409 Isolate* isolate, bool opt) const { \ 8630 Isolate* isolate, bool opt) const { \
8410 UNIMPLEMENTED(); \ 8631 UNIMPLEMENTED(); \
8411 return NULL; \ 8632 return NULL; \
8412 } \ 8633 } \
8413 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8634 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
8414 8635
8415 8636
8416 } // namespace dart 8637 } // namespace dart
8417 8638
8418 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8639 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698