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

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, enable tests, remove *CodeUnitsAt 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(ClosureCall) \ 442 M(ClosureCall) \
441 M(InstanceCall) \ 443 M(InstanceCall) \
442 M(PolymorphicInstanceCall) \ 444 M(PolymorphicInstanceCall) \
443 M(StaticCall) \ 445 M(StaticCall) \
444 M(LoadLocal) \ 446 M(LoadLocal) \
445 M(PushTemp) \ 447 M(PushTemp) \
446 M(DropTemps) \ 448 M(DropTemps) \
447 M(StoreLocal) \ 449 M(StoreLocal) \
448 M(StrictCompare) \ 450 M(StrictCompare) \
449 M(EqualityCompare) \ 451 M(EqualityCompare) \
450 M(RelationalOp) \ 452 M(RelationalOp) \
451 M(NativeCall) \ 453 M(NativeCall) \
452 M(DebugStepCheck) \ 454 M(DebugStepCheck) \
453 M(LoadIndexed) \ 455 M(LoadIndexed) \
456 M(LoadCodeUnits) \
454 M(StoreIndexed) \ 457 M(StoreIndexed) \
455 M(StoreInstanceField) \ 458 M(StoreInstanceField) \
456 M(InitStaticField) \ 459 M(InitStaticField) \
457 M(LoadStaticField) \ 460 M(LoadStaticField) \
458 M(StoreStaticField) \ 461 M(StoreStaticField) \
459 M(BooleanNegate) \ 462 M(BooleanNegate) \
460 M(InstanceOf) \ 463 M(InstanceOf) \
461 M(CreateArray) \ 464 M(CreateArray) \
462 M(AllocateObject) \ 465 M(AllocateObject) \
463 M(LoadField) \ 466 M(LoadField) \
(...skipping 19 matching lines...) Expand all
483 M(FloatToDouble) \ 486 M(FloatToDouble) \
484 M(CheckClass) \ 487 M(CheckClass) \
485 M(CheckClassId) \ 488 M(CheckClassId) \
486 M(CheckSmi) \ 489 M(CheckSmi) \
487 M(Constant) \ 490 M(Constant) \
488 M(UnboxedConstant) \ 491 M(UnboxedConstant) \
489 M(CheckEitherNonSmi) \ 492 M(CheckEitherNonSmi) \
490 M(BinaryDoubleOp) \ 493 M(BinaryDoubleOp) \
491 M(MathUnary) \ 494 M(MathUnary) \
492 M(MathMinMax) \ 495 M(MathMinMax) \
496 M(CaseInsensitiveCompareUC16) \
493 M(UnboxDouble) \ 497 M(UnboxDouble) \
494 M(BoxDouble) \ 498 M(BoxDouble) \
495 M(BoxFloat32x4) \ 499 M(BoxFloat32x4) \
496 M(UnboxFloat32x4) \ 500 M(UnboxFloat32x4) \
497 M(BoxInt32x4) \ 501 M(BoxInt32x4) \
498 M(UnboxInt32x4) \ 502 M(UnboxInt32x4) \
499 M(UnboxInteger) \ 503 M(UnboxInteger) \
500 M(BoxInteger) \ 504 M(BoxInteger) \
501 M(BinaryMintOp) \ 505 M(BinaryMintOp) \
502 M(ShiftMintOp) \ 506 M(ShiftMintOp) \
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 return const_cast<BlockEntryInstr*>(this); 1161 return const_cast<BlockEntryInstr*>(this);
1158 } 1162 }
1159 1163
1160 // Helper to mutate the graph during inlining. This block should be 1164 // Helper to mutate the graph during inlining. This block should be
1161 // replaced with new_block as a predecessor of all of this block's 1165 // replaced with new_block as a predecessor of all of this block's
1162 // successors. 1166 // successors.
1163 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); 1167 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block);
1164 1168
1165 void set_block_id(intptr_t block_id) { block_id_ = block_id; } 1169 void set_block_id(intptr_t block_id) { block_id_ = block_id; }
1166 1170
1171 intptr_t offset() const { return offset_; }
1172 void set_offset(intptr_t offset) { offset_ = offset; }
1173
1167 // For all instruction in this block: Remove all inputs (including in the 1174 // For all instruction in this block: Remove all inputs (including in the
1168 // environment) from their definition's use lists for all instructions. 1175 // environment) from their definition's use lists for all instructions.
1169 void ClearAllInstructions(); 1176 void ClearAllInstructions();
1170 1177
1171 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) 1178 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
1172 1179
1173 protected: 1180 protected:
1174 BlockEntryInstr(intptr_t block_id, intptr_t try_index) 1181 BlockEntryInstr(intptr_t block_id, intptr_t try_index)
1175 : Instruction(Isolate::Current()->GetNextDeoptId()), 1182 : Instruction(Isolate::Current()->GetNextDeoptId()),
1176 block_id_(block_id), 1183 block_id_(block_id),
1177 try_index_(try_index), 1184 try_index_(try_index),
1178 preorder_number_(-1), 1185 preorder_number_(-1),
1179 postorder_number_(-1), 1186 postorder_number_(-1),
1180 dominator_(NULL), 1187 dominator_(NULL),
1181 dominated_blocks_(1), 1188 dominated_blocks_(1),
1182 last_instruction_(NULL), 1189 last_instruction_(NULL),
1190 offset_(-1),
1183 parallel_move_(NULL), 1191 parallel_move_(NULL),
1184 loop_info_(NULL) { 1192 loop_info_(NULL) {
1185 } 1193 }
1186 1194
1187 private: 1195 private:
1188 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1196 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1189 1197
1190 virtual void ClearPredecessors() = 0; 1198 virtual void ClearPredecessors() = 0;
1191 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; 1199 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
1192 1200
1193 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 1201 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
1194 1202
1195 intptr_t block_id_; 1203 intptr_t block_id_;
1196 const intptr_t try_index_; 1204 const intptr_t try_index_;
1197 intptr_t preorder_number_; 1205 intptr_t preorder_number_;
1198 intptr_t postorder_number_; 1206 intptr_t postorder_number_;
1199 // Starting and ending lifetime positions for this block. Used by 1207 // Starting and ending lifetime positions for this block. Used by
1200 // the linear scan register allocator. 1208 // the linear scan register allocator.
1201 intptr_t start_pos_; 1209 intptr_t start_pos_;
1202 intptr_t end_pos_; 1210 intptr_t end_pos_;
1203 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 1211 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1204 // TODO(fschneider): Optimize the case of one child to save space. 1212 // TODO(fschneider): Optimize the case of one child to save space.
1205 GrowableArray<BlockEntryInstr*> dominated_blocks_; 1213 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1206 Instruction* last_instruction_; 1214 Instruction* last_instruction_;
1207 1215
1216 // Offset of this block from the start of the emitted code.
1217 intptr_t offset_;
1218
1208 // Parallel move that will be used by linear scan register allocator to 1219 // Parallel move that will be used by linear scan register allocator to
1209 // connect live ranges at the start of the block. 1220 // connect live ranges at the start of the block.
1210 ParallelMoveInstr* parallel_move_; 1221 ParallelMoveInstr* parallel_move_;
1211 1222
1212 // Bit vector containg loop blocks for a loop header indexed by block 1223 // Bit vector containg loop blocks for a loop header indexed by block
1213 // preorder number. 1224 // preorder number.
1214 BitVector* loop_info_; 1225 BitVector* loop_info_;
1215 1226
1216 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 1227 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1217 }; 1228 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 UNREACHABLE(); 1289 UNREACHABLE();
1279 return NULL; 1290 return NULL;
1280 } 1291 }
1281 virtual intptr_t SuccessorCount() const; 1292 virtual intptr_t SuccessorCount() const;
1282 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1293 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1283 1294
1284 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } 1295 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
1285 1296
1286 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1297 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1287 1298
1299 void AddIndirectEntry(IndirectEntryInstr* entry) {
1300 indirect_entries_.Add(entry);
1301 }
1302
1288 GrowableArray<Definition*>* initial_definitions() { 1303 GrowableArray<Definition*>* initial_definitions() {
1289 return &initial_definitions_; 1304 return &initial_definitions_;
1290 } 1305 }
1291 ConstantInstr* constant_null(); 1306 ConstantInstr* constant_null();
1292 1307
1293 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1308 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1294 1309
1295 intptr_t entry_count() const { return entry_count_; } 1310 intptr_t entry_count() const { return entry_count_; }
1296 void set_entry_count(intptr_t count) { entry_count_ = count; } 1311 void set_entry_count(intptr_t count) { entry_count_ = count; }
1297 1312
(...skipping 14 matching lines...) Expand all
1312 TargetEntryInstr* normal_entry() const { return normal_entry_; } 1327 TargetEntryInstr* normal_entry() const { return normal_entry_; }
1313 1328
1314 const ParsedFunction& parsed_function() const { 1329 const ParsedFunction& parsed_function() const {
1315 return *parsed_function_; 1330 return *parsed_function_;
1316 } 1331 }
1317 1332
1318 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { 1333 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
1319 return catch_entries_; 1334 return catch_entries_;
1320 } 1335 }
1321 1336
1337 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const {
1338 return indirect_entries_;
1339 }
1340
1322 virtual void PrintTo(BufferFormatter* f) const; 1341 virtual void PrintTo(BufferFormatter* f) const;
1323 1342
1324 private: 1343 private:
1325 virtual void ClearPredecessors() {} 1344 virtual void ClearPredecessors() {}
1326 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1345 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1327 1346
1328 const ParsedFunction* parsed_function_; 1347 const ParsedFunction* parsed_function_;
1329 TargetEntryInstr* normal_entry_; 1348 TargetEntryInstr* normal_entry_;
1330 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1349 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1350 // Indirect targets are blocks reachable only through indirect gotos.
1351 GrowableArray<IndirectEntryInstr*> indirect_entries_;
1331 GrowableArray<Definition*> initial_definitions_; 1352 GrowableArray<Definition*> initial_definitions_;
1332 const intptr_t osr_id_; 1353 const intptr_t osr_id_;
1333 intptr_t entry_count_; 1354 intptr_t entry_count_;
1334 intptr_t spill_slot_count_; 1355 intptr_t spill_slot_count_;
1335 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1356 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1336 1357
1337 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1358 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1338 }; 1359 };
1339 1360
1340 1361
(...skipping 25 matching lines...) Expand all
1366 virtual void PrintTo(BufferFormatter* f) const; 1387 virtual void PrintTo(BufferFormatter* f) const;
1367 1388
1368 virtual EffectSet Effects() const { return EffectSet::None(); } 1389 virtual EffectSet Effects() const { return EffectSet::None(); }
1369 virtual EffectSet Dependencies() const { return EffectSet::None(); } 1390 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1370 1391
1371 private: 1392 private:
1372 // Classes that have access to predecessors_ when inlining. 1393 // Classes that have access to predecessors_ when inlining.
1373 friend class BlockEntryInstr; 1394 friend class BlockEntryInstr;
1374 friend class InlineExitCollector; 1395 friend class InlineExitCollector;
1375 friend class PolymorphicInliner; 1396 friend class PolymorphicInliner;
1397 friend class IndirectEntryInstr; // Access in il_printer.cc.
1376 1398
1377 // Direct access to phis_ in order to resize it due to phi elimination. 1399 // Direct access to phis_ in order to resize it due to phi elimination.
1378 friend class ConstantPropagator; 1400 friend class ConstantPropagator;
1379 friend class DeadCodeElimination; 1401 friend class DeadCodeElimination;
1380 1402
1381 virtual void ClearPredecessors() { predecessors_.Clear(); } 1403 virtual void ClearPredecessors() { predecessors_.Clear(); }
1382 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1404 virtual void AddPredecessor(BlockEntryInstr* predecessor);
1383 1405
1384 GrowableArray<BlockEntryInstr*> predecessors_; 1406 GrowableArray<BlockEntryInstr*> predecessors_;
1385 ZoneGrowableArray<PhiInstr*>* phis_; 1407 ZoneGrowableArray<PhiInstr*>* phis_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 predecessor_ = predecessor; 1466 predecessor_ = predecessor;
1445 } 1467 }
1446 1468
1447 BlockEntryInstr* predecessor_; 1469 BlockEntryInstr* predecessor_;
1448 double edge_weight_; 1470 double edge_weight_;
1449 1471
1450 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1472 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1451 }; 1473 };
1452 1474
1453 1475
1476 class IndirectEntryInstr : public JoinEntryInstr {
1477 public:
1478 IndirectEntryInstr(intptr_t block_id,
1479 intptr_t indirect_id,
1480 intptr_t try_index)
1481 : JoinEntryInstr(block_id, try_index),
1482 indirect_id_(indirect_id) { }
1483
1484 DECLARE_INSTRUCTION(IndirectEntry)
1485
1486 virtual void PrintTo(BufferFormatter* f) const;
1487
1488 intptr_t indirect_id() const { return indirect_id_; }
1489
1490 private:
1491 const intptr_t indirect_id_;
1492 };
1493
1494
1454 class CatchBlockEntryInstr : public BlockEntryInstr { 1495 class CatchBlockEntryInstr : public BlockEntryInstr {
1455 public: 1496 public:
1456 CatchBlockEntryInstr(intptr_t block_id, 1497 CatchBlockEntryInstr(intptr_t block_id,
1457 intptr_t try_index, 1498 intptr_t try_index,
1458 const Array& handler_types, 1499 const Array& handler_types,
1459 intptr_t catch_try_index, 1500 intptr_t catch_try_index,
1460 const LocalVariable& exception_var, 1501 const LocalVariable& exception_var,
1461 const LocalVariable& stacktrace_var, 1502 const LocalVariable& stacktrace_var,
1462 bool needs_stacktrace) 1503 bool needs_stacktrace)
1463 : BlockEntryInstr(block_id, try_index), 1504 : BlockEntryInstr(block_id, try_index),
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
2149 private: 2190 private:
2150 JoinEntryInstr* successor_; 2191 JoinEntryInstr* successor_;
2151 double edge_weight_; 2192 double edge_weight_;
2152 2193
2153 // Parallel move that will be used by linear scan register allocator to 2194 // Parallel move that will be used by linear scan register allocator to
2154 // connect live ranges at the end of the block and resolve phis. 2195 // connect live ranges at the end of the block and resolve phis.
2155 ParallelMoveInstr* parallel_move_; 2196 ParallelMoveInstr* parallel_move_;
2156 }; 2197 };
2157 2198
2158 2199
2200 // As a high level description, an indirect goto takes the indirect_id of an
2201 // indirect entry as a parameter, and jumps to that location.
2202 //
2203 // In more detail: in order to preserve split-edge form, an intermediate target
2204 // entry consisting of a goto to the final indirect entry is inserted on
2205 // each possible indirect goto -> indirect entry edge. These target entries are
2206 // accessible through successors_.
2207 //
2208 // Byte offsets of all possible indirect targets are stored in the offsets_
2209 // array. The desired offset is looked up while the generated code is executing,
2210 // and passed to IndirectGoto as an input.
2211 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> {
2212 public:
2213 IndirectGotoInstr(GrowableObjectArray* offsets,
2214 Value* offset_from_start)
2215 : offsets_(*offsets) {
2216 SetInputAt(0, offset_from_start);
2217 }
2218
2219 DECLARE_INSTRUCTION(IndirectGoto)
2220
2221 virtual intptr_t ArgumentCount() const { return 0; }
2222
2223 void AddSuccessor(TargetEntryInstr* successor) {
2224 ASSERT(successor->next()->IsGoto());
2225 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
2226 successors_.Add(successor);
2227 }
2228
2229 virtual intptr_t SuccessorCount() const { return successors_.length(); }
2230 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const {
2231 ASSERT(index < SuccessorCount());
2232 return successors_[index];
2233 }
2234
2235 virtual bool CanDeoptimize() const { return false; }
2236 virtual bool CanBecomeDeoptimizationTarget() const { return false; }
2237
2238 virtual EffectSet Effects() const { return EffectSet::None(); }
2239
2240 virtual void PrintTo(BufferFormatter* f) const;
2241
2242 const GrowableObjectArray& offsets() const { return offsets_; }
2243 void SetOffsetCount(Isolate* isolate, intptr_t count) {
2244 if (offsets_.Capacity() < count) {
2245 offsets_.Grow(count, Heap::kOld);
2246 }
2247 if (offsets_.Length() < count) {
2248 offsets_.SetLength(count);
2249 }
2250 }
2251 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) {
2252 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset)));
2253 }
2254
2255 private:
2256 GrowableArray<TargetEntryInstr*> successors_;
2257 GrowableObjectArray& offsets_;
2258 };
2259
2260
2159 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { 2261 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> {
2160 public: 2262 public:
2161 Value* left() const { return inputs_[0]; } 2263 Value* left() const { return inputs_[0]; }
2162 Value* right() const { return inputs_[1]; } 2264 Value* right() const { return inputs_[1]; }
2163 2265
2164 virtual intptr_t token_pos() const { return token_pos_; } 2266 virtual intptr_t token_pos() const { return token_pos_; }
2165 Token::Kind kind() const { return kind_; } 2267 Token::Kind kind() const { return kind_; }
2166 2268
2167 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; 2269 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2168 2270
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3618 3720
3619 private: 3721 private:
3620 const intptr_t index_scale_; 3722 const intptr_t index_scale_;
3621 const intptr_t class_id_; 3723 const intptr_t class_id_;
3622 const intptr_t token_pos_; 3724 const intptr_t token_pos_;
3623 3725
3624 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3726 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3625 }; 3727 };
3626 3728
3627 3729
3730 // Loads the specified number of code units from the given string, packing
3731 // multiple code units into a single datatype. In essence, this is a specialized
3732 // version of LoadIndexedInstr which accepts only string targets and can load
3733 // multiple elements at once. The result datatype differs depending on the
3734 // string type, element count, and architecture; if possible, the result is
3735 // packed into a Smi, falling back to a Mint otherwise.
3736 // TODO(zerny): Add support for loading into UnboxedInt32x4.
3737 class LoadCodeUnitsInstr : public TemplateDefinition<2, NoThrow> {
3738 public:
3739 LoadCodeUnitsInstr(Value* str,
3740 Value* index,
3741 intptr_t element_count,
3742 intptr_t class_id,
3743 intptr_t token_pos)
3744 : class_id_(class_id),
3745 token_pos_(token_pos),
3746 element_count_(element_count) {
3747 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
3748 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid);
3749 SetInputAt(0, str);
3750 SetInputAt(1, index);
3751 }
3752
3753 intptr_t token_pos() const { return token_pos_; }
3754
3755 DECLARE_INSTRUCTION(LoadCodeUnits)
3756 virtual CompileType ComputeType() const;
3757
3758 bool IsExternal() const {
3759 return array()->definition()->representation() == kUntagged;
3760 }
3761
3762 Value* array() const { return inputs_[0]; }
3763 Value* index() const { return inputs_[1]; }
3764 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); }
3765 intptr_t class_id() const { return class_id_; }
3766 intptr_t element_count() const { return element_count_; }
3767
3768 bool can_pack_into_smi() const {
3769 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte);
3770 }
3771
3772 virtual bool CanDeoptimize() const { return false; }
3773
3774 virtual Representation representation() const;
3775 virtual void InferRange(RangeAnalysis* analysis, Range* range);
3776
3777 virtual EffectSet Effects() const { return EffectSet::None(); }
3778
3779 private:
3780 const intptr_t class_id_;
3781 const intptr_t token_pos_;
3782 const intptr_t element_count_;
3783
3784 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr);
3785 };
3786
3787
3628 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { 3788 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
3629 public: 3789 public:
3630 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3790 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3631 ASSERT(char_code != NULL); 3791 ASSERT(char_code != NULL);
3632 ASSERT(char_code->definition()->IsLoadIndexed()); 3792 ASSERT(char_code->definition()->IsLoadIndexed());
3633 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == 3793 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
3634 kOneByteStringCid); 3794 kOneByteStringCid);
3635 SetInputAt(0, char_code); 3795 SetInputAt(0, char_code);
3636 } 3796 }
3637 3797
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4756 4916
4757 static const char* KindToCString(MathUnaryKind kind); 4917 static const char* KindToCString(MathUnaryKind kind);
4758 4918
4759 private: 4919 private:
4760 const MathUnaryKind kind_; 4920 const MathUnaryKind kind_;
4761 4921
4762 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); 4922 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr);
4763 }; 4923 };
4764 4924
4765 4925
4926 // Calls into the runtime and performs a case-insensitive comparison of the
4927 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at
4928 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length].
4929 //
4930 // TODO(zerny): Remove this once (if) functions inherited from unibrow
4931 // are moved to dart code.
4932 class CaseInsensitiveCompareUC16Instr
4933 : public TemplateDefinition<4, NoThrow, Pure> {
4934 public:
4935 CaseInsensitiveCompareUC16Instr(
4936 Value* str,
4937 Value* lhs_index,
4938 Value* rhs_index,
4939 Value* length,
4940 intptr_t cid)
4941 : cid_(cid) {
4942 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid);
4943 ASSERT(index_scale() == 2);
4944 SetInputAt(0, str);
4945 SetInputAt(1, lhs_index);
4946 SetInputAt(2, rhs_index);
4947 SetInputAt(3, length);
4948 }
4949
4950 Value* str() const { return inputs_[0]; }
4951 Value* lhs_index() const { return inputs_[1]; }
4952 Value* rhs_index() const { return inputs_[2]; }
4953 Value* length() const { return inputs_[3]; }
4954
4955 const RuntimeEntry& TargetFunction() const;
4956 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; }
4957 intptr_t class_id() const { return cid_; }
4958 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); }
4959
4960 virtual bool CanDeoptimize() const { return false; }
4961
4962 virtual Representation representation() const {
4963 return kTagged;
4964 }
4965
4966 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16)
4967 virtual CompileType ComputeType() const;
4968
4969 virtual bool AttributesEqual(Instruction* other) const {
4970 return other->AsCaseInsensitiveCompareUC16()->cid_ == cid_;
4971 }
4972
4973 private:
4974 const intptr_t cid_;
4975
4976 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr);
4977 };
4978
4979
4766 // Represents Math's static min and max functions. 4980 // Represents Math's static min and max functions.
4767 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> { 4981 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> {
4768 public: 4982 public:
4769 MathMinMaxInstr(MethodRecognizer::Kind op_kind, 4983 MathMinMaxInstr(MethodRecognizer::Kind op_kind,
4770 Value* left_value, 4984 Value* left_value,
4771 Value* right_value, 4985 Value* right_value,
4772 intptr_t deopt_id, 4986 intptr_t deopt_id,
4773 intptr_t result_cid) 4987 intptr_t result_cid)
4774 : TemplateDefinition(deopt_id), 4988 : TemplateDefinition(deopt_id),
4775 op_kind_(op_kind), 4989 op_kind_(op_kind),
(...skipping 3117 matching lines...) Expand 10 before | Expand all | Expand 10 after
7893 Isolate* isolate, bool opt) const { \ 8107 Isolate* isolate, bool opt) const { \
7894 UNIMPLEMENTED(); \ 8108 UNIMPLEMENTED(); \
7895 return NULL; \ 8109 return NULL; \
7896 } \ 8110 } \
7897 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8111 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
7898 8112
7899 8113
7900 } // namespace dart 8114 } // namespace dart
7901 8115
7902 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8116 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698