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

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: byte-order assert & context-var 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 23 matching lines...) Expand all
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) \
493 M(Box) \ 496 M(Box) \
494 M(Unbox) \ 497 M(Unbox) \
495 M(BoxInt64) \ 498 M(BoxInt64) \
496 M(UnboxInt64) \ 499 M(UnboxInt64) \
500 M(CaseInsensitiveCompareUC16) \
497 M(BinaryMintOp) \ 501 M(BinaryMintOp) \
498 M(ShiftMintOp) \ 502 M(ShiftMintOp) \
499 M(UnaryMintOp) \ 503 M(UnaryMintOp) \
500 M(CheckArrayBound) \ 504 M(CheckArrayBound) \
501 M(Constraint) \ 505 M(Constraint) \
502 M(StringToCharCode) \ 506 M(StringToCharCode) \
503 M(StringFromCharCode) \ 507 M(StringFromCharCode) \
504 M(StringInterpolate) \ 508 M(StringInterpolate) \
505 M(InvokeMathCFunction) \ 509 M(InvokeMathCFunction) \
506 M(MergedMath) \ 510 M(MergedMath) \
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 return const_cast<BlockEntryInstr*>(this); 1155 return const_cast<BlockEntryInstr*>(this);
1152 } 1156 }
1153 1157
1154 // Helper to mutate the graph during inlining. This block should be 1158 // Helper to mutate the graph during inlining. This block should be
1155 // replaced with new_block as a predecessor of all of this block's 1159 // replaced with new_block as a predecessor of all of this block's
1156 // successors. 1160 // successors.
1157 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); 1161 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block);
1158 1162
1159 void set_block_id(intptr_t block_id) { block_id_ = block_id; } 1163 void set_block_id(intptr_t block_id) { block_id_ = block_id; }
1160 1164
1165 intptr_t offset() const { return offset_; }
1166 void set_offset(intptr_t offset) { offset_ = offset; }
1167
1161 // For all instruction in this block: Remove all inputs (including in the 1168 // For all instruction in this block: Remove all inputs (including in the
1162 // environment) from their definition's use lists for all instructions. 1169 // environment) from their definition's use lists for all instructions.
1163 void ClearAllInstructions(); 1170 void ClearAllInstructions();
1164 1171
1165 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry) 1172 DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
1166 1173
1167 protected: 1174 protected:
1168 BlockEntryInstr(intptr_t block_id, intptr_t try_index) 1175 BlockEntryInstr(intptr_t block_id, intptr_t try_index)
1169 : Instruction(Isolate::Current()->GetNextDeoptId()), 1176 : Instruction(Isolate::Current()->GetNextDeoptId()),
1170 block_id_(block_id), 1177 block_id_(block_id),
1171 try_index_(try_index), 1178 try_index_(try_index),
1172 preorder_number_(-1), 1179 preorder_number_(-1),
1173 postorder_number_(-1), 1180 postorder_number_(-1),
1174 dominator_(NULL), 1181 dominator_(NULL),
1175 dominated_blocks_(1), 1182 dominated_blocks_(1),
1176 last_instruction_(NULL), 1183 last_instruction_(NULL),
1184 offset_(-1),
1177 parallel_move_(NULL), 1185 parallel_move_(NULL),
1178 loop_info_(NULL) { 1186 loop_info_(NULL) {
1179 } 1187 }
1180 1188
1181 private: 1189 private:
1182 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } 1190 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
1183 1191
1184 virtual void ClearPredecessors() = 0; 1192 virtual void ClearPredecessors() = 0;
1185 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; 1193 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
1186 1194
1187 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 1195 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
1188 1196
1189 intptr_t block_id_; 1197 intptr_t block_id_;
1190 const intptr_t try_index_; 1198 const intptr_t try_index_;
1191 intptr_t preorder_number_; 1199 intptr_t preorder_number_;
1192 intptr_t postorder_number_; 1200 intptr_t postorder_number_;
1193 // Starting and ending lifetime positions for this block. Used by 1201 // Starting and ending lifetime positions for this block. Used by
1194 // the linear scan register allocator. 1202 // the linear scan register allocator.
1195 intptr_t start_pos_; 1203 intptr_t start_pos_;
1196 intptr_t end_pos_; 1204 intptr_t end_pos_;
1197 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 1205 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1198 // TODO(fschneider): Optimize the case of one child to save space. 1206 // TODO(fschneider): Optimize the case of one child to save space.
1199 GrowableArray<BlockEntryInstr*> dominated_blocks_; 1207 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1200 Instruction* last_instruction_; 1208 Instruction* last_instruction_;
1201 1209
1210 // Offset of this block from the start of the emitted code.
1211 intptr_t offset_;
1212
1202 // Parallel move that will be used by linear scan register allocator to 1213 // Parallel move that will be used by linear scan register allocator to
1203 // connect live ranges at the start of the block. 1214 // connect live ranges at the start of the block.
1204 ParallelMoveInstr* parallel_move_; 1215 ParallelMoveInstr* parallel_move_;
1205 1216
1206 // Bit vector containg loop blocks for a loop header indexed by block 1217 // Bit vector containg loop blocks for a loop header indexed by block
1207 // preorder number. 1218 // preorder number.
1208 BitVector* loop_info_; 1219 BitVector* loop_info_;
1209 1220
1210 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 1221 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1211 }; 1222 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 UNREACHABLE(); 1283 UNREACHABLE();
1273 return NULL; 1284 return NULL;
1274 } 1285 }
1275 virtual intptr_t SuccessorCount() const; 1286 virtual intptr_t SuccessorCount() const;
1276 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1287 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1277 1288
1278 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); } 1289 void AddCatchEntry(CatchBlockEntryInstr* entry) { catch_entries_.Add(entry); }
1279 1290
1280 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1291 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1281 1292
1293 void AddIndirectEntry(IndirectEntryInstr* entry) {
Ivan Posva 2014/11/10 08:16:23 It is very unclear what these entries are used for
zerny-google 2014/11/10 09:10:42 As far as I understand, the graph entry is the mai
1294 indirect_entries_.Add(entry);
1295 }
1296
1282 GrowableArray<Definition*>* initial_definitions() { 1297 GrowableArray<Definition*>* initial_definitions() {
1283 return &initial_definitions_; 1298 return &initial_definitions_;
1284 } 1299 }
1285 ConstantInstr* constant_null(); 1300 ConstantInstr* constant_null();
1286 1301
1287 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1302 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1288 1303
1289 intptr_t entry_count() const { return entry_count_; } 1304 intptr_t entry_count() const { return entry_count_; }
1290 void set_entry_count(intptr_t count) { entry_count_ = count; } 1305 void set_entry_count(intptr_t count) { entry_count_ = count; }
1291 1306
(...skipping 14 matching lines...) Expand all
1306 TargetEntryInstr* normal_entry() const { return normal_entry_; } 1321 TargetEntryInstr* normal_entry() const { return normal_entry_; }
1307 1322
1308 const ParsedFunction& parsed_function() const { 1323 const ParsedFunction& parsed_function() const {
1309 return *parsed_function_; 1324 return *parsed_function_;
1310 } 1325 }
1311 1326
1312 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { 1327 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
1313 return catch_entries_; 1328 return catch_entries_;
1314 } 1329 }
1315 1330
1331 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const {
1332 return indirect_entries_;
1333 }
1334
1316 virtual void PrintTo(BufferFormatter* f) const; 1335 virtual void PrintTo(BufferFormatter* f) const;
1317 1336
1318 private: 1337 private:
1319 virtual void ClearPredecessors() {} 1338 virtual void ClearPredecessors() {}
1320 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1339 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1321 1340
1322 const ParsedFunction* parsed_function_; 1341 const ParsedFunction* parsed_function_;
1323 TargetEntryInstr* normal_entry_; 1342 TargetEntryInstr* normal_entry_;
1324 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1343 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1344 // Indirect targets are blocks reachable only through indirect gotos.
1345 GrowableArray<IndirectEntryInstr*> indirect_entries_;
1325 GrowableArray<Definition*> initial_definitions_; 1346 GrowableArray<Definition*> initial_definitions_;
1326 const intptr_t osr_id_; 1347 const intptr_t osr_id_;
1327 intptr_t entry_count_; 1348 intptr_t entry_count_;
1328 intptr_t spill_slot_count_; 1349 intptr_t spill_slot_count_;
1329 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1350 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1330 1351
1331 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1352 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1332 }; 1353 };
1333 1354
1334 1355
(...skipping 25 matching lines...) Expand all
1360 virtual void PrintTo(BufferFormatter* f) const; 1381 virtual void PrintTo(BufferFormatter* f) const;
1361 1382
1362 virtual EffectSet Effects() const { return EffectSet::None(); } 1383 virtual EffectSet Effects() const { return EffectSet::None(); }
1363 virtual EffectSet Dependencies() const { return EffectSet::None(); } 1384 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1364 1385
1365 private: 1386 private:
1366 // Classes that have access to predecessors_ when inlining. 1387 // Classes that have access to predecessors_ when inlining.
1367 friend class BlockEntryInstr; 1388 friend class BlockEntryInstr;
1368 friend class InlineExitCollector; 1389 friend class InlineExitCollector;
1369 friend class PolymorphicInliner; 1390 friend class PolymorphicInliner;
1391 friend class IndirectEntryInstr; // Access in il_printer.cc.
1370 1392
1371 // Direct access to phis_ in order to resize it due to phi elimination. 1393 // Direct access to phis_ in order to resize it due to phi elimination.
1372 friend class ConstantPropagator; 1394 friend class ConstantPropagator;
1373 friend class DeadCodeElimination; 1395 friend class DeadCodeElimination;
1374 1396
1375 virtual void ClearPredecessors() { predecessors_.Clear(); } 1397 virtual void ClearPredecessors() { predecessors_.Clear(); }
1376 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1398 virtual void AddPredecessor(BlockEntryInstr* predecessor);
1377 1399
1378 GrowableArray<BlockEntryInstr*> predecessors_; 1400 GrowableArray<BlockEntryInstr*> predecessors_;
1379 ZoneGrowableArray<PhiInstr*>* phis_; 1401 ZoneGrowableArray<PhiInstr*>* phis_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 predecessor_ = predecessor; 1460 predecessor_ = predecessor;
1439 } 1461 }
1440 1462
1441 BlockEntryInstr* predecessor_; 1463 BlockEntryInstr* predecessor_;
1442 double edge_weight_; 1464 double edge_weight_;
1443 1465
1444 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1466 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1445 }; 1467 };
1446 1468
1447 1469
1470 class IndirectEntryInstr : public JoinEntryInstr {
1471 public:
1472 IndirectEntryInstr(intptr_t block_id,
1473 intptr_t indirect_id,
1474 intptr_t try_index)
1475 : JoinEntryInstr(block_id, try_index),
1476 indirect_id_(indirect_id) { }
1477
1478 DECLARE_INSTRUCTION(IndirectEntry)
1479
1480 virtual void PrintTo(BufferFormatter* f) const;
1481
1482 intptr_t indirect_id() const { return indirect_id_; }
1483
1484 private:
1485 const intptr_t indirect_id_;
1486 };
1487
1488
1448 class CatchBlockEntryInstr : public BlockEntryInstr { 1489 class CatchBlockEntryInstr : public BlockEntryInstr {
1449 public: 1490 public:
1450 CatchBlockEntryInstr(intptr_t block_id, 1491 CatchBlockEntryInstr(intptr_t block_id,
1451 intptr_t try_index, 1492 intptr_t try_index,
1452 const Array& handler_types, 1493 const Array& handler_types,
1453 intptr_t catch_try_index, 1494 intptr_t catch_try_index,
1454 const LocalVariable& exception_var, 1495 const LocalVariable& exception_var,
1455 const LocalVariable& stacktrace_var, 1496 const LocalVariable& stacktrace_var,
1456 bool needs_stacktrace) 1497 bool needs_stacktrace)
1457 : BlockEntryInstr(block_id, try_index), 1498 : BlockEntryInstr(block_id, try_index),
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
2136 private: 2177 private:
2137 JoinEntryInstr* successor_; 2178 JoinEntryInstr* successor_;
2138 double edge_weight_; 2179 double edge_weight_;
2139 2180
2140 // Parallel move that will be used by linear scan register allocator to 2181 // Parallel move that will be used by linear scan register allocator to
2141 // connect live ranges at the end of the block and resolve phis. 2182 // connect live ranges at the end of the block and resolve phis.
2142 ParallelMoveInstr* parallel_move_; 2183 ParallelMoveInstr* parallel_move_;
2143 }; 2184 };
2144 2185
2145 2186
2187 // As a high level description, an indirect goto takes the indirect_id of an
2188 // indirect entry as a parameter, and jumps to that location.
2189 //
2190 // In more detail: in order to preserve split-edge form, an intermediate target
2191 // entry consisting of a goto to the final indirect entry is inserted on
Ivan Posva 2014/11/10 08:16:23 This comment is unclear. What is "final" in this c
zerny-google 2014/11/10 09:10:42 I'll update the comment to be more clear. What th
2192 // each possible indirect goto -> indirect entry edge. These target entries are
2193 // accessible through successors_.
2194 //
2195 // Byte offsets of all possible indirect targets are stored in the offsets_
2196 // array. The desired offset is looked up while the generated code is executing,
2197 // and passed to IndirectGoto as an input.
2198 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> {
2199 public:
2200 IndirectGotoInstr(GrowableObjectArray* offsets,
2201 Value* offset_from_start)
2202 : offsets_(*offsets) {
2203 SetInputAt(0, offset_from_start);
2204 }
2205
2206 DECLARE_INSTRUCTION(IndirectGoto)
2207
2208 virtual intptr_t ArgumentCount() const { return 0; }
2209
2210 void AddSuccessor(TargetEntryInstr* successor) {
2211 ASSERT(successor->next()->IsGoto());
2212 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
2213 successors_.Add(successor);
2214 }
2215
2216 virtual intptr_t SuccessorCount() const { return successors_.length(); }
2217 virtual TargetEntryInstr* SuccessorAt(intptr_t index) const {
2218 ASSERT(index < SuccessorCount());
2219 return successors_[index];
2220 }
2221
2222 virtual bool CanDeoptimize() const { return false; }
2223 virtual bool CanBecomeDeoptimizationTarget() const { return false; }
2224
2225 virtual EffectSet Effects() const { return EffectSet::None(); }
2226
2227 virtual void PrintTo(BufferFormatter* f) const;
2228
2229 const GrowableObjectArray& offsets() const { return offsets_; }
2230 void SetOffsetCount(Isolate* isolate, intptr_t count) {
2231 if (offsets_.Capacity() < count) {
2232 offsets_.Grow(count, Heap::kOld);
2233 }
2234 if (offsets_.Length() < count) {
2235 offsets_.SetLength(count);
2236 }
2237 }
2238 void SetOffsetAt(Isolate* isolate, intptr_t index, intptr_t offset) {
2239 offsets_.SetAt(index, Smi::ZoneHandle(isolate, Smi::New(offset)));
2240 }
2241
2242 private:
2243 GrowableArray<TargetEntryInstr*> successors_;
Ivan Posva 2014/11/10 08:16:23 How many of these successors and corresponding off
zerny-google 2014/11/10 09:10:42 One for each possible target. The number of target
2244 GrowableObjectArray& offsets_;
2245 };
2246
2247
2146 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { 2248 class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> {
2147 public: 2249 public:
2148 Value* left() const { return inputs_[0]; } 2250 Value* left() const { return inputs_[0]; }
2149 Value* right() const { return inputs_[1]; } 2251 Value* right() const { return inputs_[1]; }
2150 2252
2151 virtual intptr_t token_pos() const { return token_pos_; } 2253 virtual intptr_t token_pos() const { return token_pos_; }
2152 Token::Kind kind() const { return kind_; } 2254 Token::Kind kind() const { return kind_; }
2153 2255
2154 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; 2256 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2155 2257
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3605 3707
3606 private: 3708 private:
3607 const intptr_t index_scale_; 3709 const intptr_t index_scale_;
3608 const intptr_t class_id_; 3710 const intptr_t class_id_;
3609 const intptr_t token_pos_; 3711 const intptr_t token_pos_;
3610 3712
3611 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3713 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3612 }; 3714 };
3613 3715
3614 3716
3717 // Loads the specified number of code units from the given string, packing
3718 // multiple code units into a single datatype. In essence, this is a specialized
3719 // version of LoadIndexedInstr which accepts only string targets and can load
3720 // multiple elements at once. The result datatype differs depending on the
3721 // string type, element count, and architecture; if possible, the result is
3722 // packed into a Smi, falling back to a Mint otherwise.
3723 // TODO(zerny): Add support for loading into UnboxedInt32x4.
3724 class LoadCodeUnitsInstr : public TemplateDefinition<2, NoThrow> {
3725 public:
3726 LoadCodeUnitsInstr(Value* str,
3727 Value* index,
3728 intptr_t element_count,
3729 intptr_t class_id,
3730 intptr_t token_pos)
3731 : class_id_(class_id),
3732 token_pos_(token_pos),
3733 element_count_(element_count) {
3734 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
3735 ASSERT(class_id == kOneByteStringCid || class_id == kTwoByteStringCid);
3736 SetInputAt(0, str);
3737 SetInputAt(1, index);
3738 }
3739
3740 intptr_t token_pos() const { return token_pos_; }
3741
3742 DECLARE_INSTRUCTION(LoadCodeUnits)
3743 virtual CompileType ComputeType() const;
3744
3745 bool IsExternal() const {
3746 return array()->definition()->representation() == kUntagged;
3747 }
3748
3749 Value* array() const { return inputs_[0]; }
3750 Value* index() const { return inputs_[1]; }
3751 intptr_t index_scale() const { return Instance::ElementSizeFor(class_id_); }
3752 intptr_t class_id() const { return class_id_; }
3753 intptr_t element_count() const { return element_count_; }
3754
3755 bool can_pack_into_smi() const {
3756 return element_count() <= kSmiBits / (index_scale() * kBitsPerByte);
3757 }
3758
3759 virtual bool CanDeoptimize() const { return false; }
3760
3761 virtual Representation representation() const;
3762 virtual void InferRange(RangeAnalysis* analysis, Range* range);
3763
3764 virtual EffectSet Effects() const { return EffectSet::None(); }
3765
3766 private:
3767 const intptr_t class_id_;
3768 const intptr_t token_pos_;
3769 const intptr_t element_count_;
3770
3771 DISALLOW_COPY_AND_ASSIGN(LoadCodeUnitsInstr);
3772 };
3773
3774
3615 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { 3775 class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
3616 public: 3776 public:
3617 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3777 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3618 ASSERT(char_code != NULL); 3778 ASSERT(char_code != NULL);
3619 ASSERT(char_code->definition()->IsLoadIndexed()); 3779 ASSERT(char_code->definition()->IsLoadIndexed());
3620 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() == 3780 ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
3621 kOneByteStringCid); 3781 kOneByteStringCid);
3622 SetInputAt(0, char_code); 3782 SetInputAt(0, char_code);
3623 } 3783 }
3624 3784
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after
4780 4940
4781 static const char* KindToCString(MathUnaryKind kind); 4941 static const char* KindToCString(MathUnaryKind kind);
4782 4942
4783 private: 4943 private:
4784 const MathUnaryKind kind_; 4944 const MathUnaryKind kind_;
4785 4945
4786 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr); 4946 DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr);
4787 }; 4947 };
4788 4948
4789 4949
4950 // Calls into the runtime and performs a case-insensitive comparison of the
4951 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at
4952 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length].
4953 //
4954 // TODO(zerny): Remove this once (if) functions inherited from unibrow
4955 // are moved to dart code.
4956 class CaseInsensitiveCompareUC16Instr
4957 : public TemplateDefinition<4, NoThrow, Pure> {
4958 public:
4959 CaseInsensitiveCompareUC16Instr(
4960 Value* str,
4961 Value* lhs_index,
4962 Value* rhs_index,
4963 Value* length,
4964 intptr_t cid)
4965 : cid_(cid) {
4966 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid);
4967 ASSERT(index_scale() == 2);
4968 SetInputAt(0, str);
4969 SetInputAt(1, lhs_index);
4970 SetInputAt(2, rhs_index);
4971 SetInputAt(3, length);
4972 }
4973
4974 Value* str() const { return inputs_[0]; }
4975 Value* lhs_index() const { return inputs_[1]; }
4976 Value* rhs_index() const { return inputs_[2]; }
4977 Value* length() const { return inputs_[3]; }
4978
4979 const RuntimeEntry& TargetFunction() const;
4980 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; }
4981 intptr_t class_id() const { return cid_; }
4982 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); }
4983
4984 virtual bool CanDeoptimize() const { return false; }
4985
4986 virtual Representation representation() const {
4987 return kTagged;
4988 }
4989
4990 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16)
4991 virtual CompileType ComputeType() const;
4992
4993 virtual bool AttributesEqual(Instruction* other) const {
4994 return other->AsCaseInsensitiveCompareUC16()->cid_ == cid_;
4995 }
4996
4997 private:
4998 const intptr_t cid_;
4999
5000 DISALLOW_COPY_AND_ASSIGN(CaseInsensitiveCompareUC16Instr);
5001 };
5002
5003
4790 // Represents Math's static min and max functions. 5004 // Represents Math's static min and max functions.
4791 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> { 5005 class MathMinMaxInstr : public TemplateDefinition<2, NoThrow, Pure> {
4792 public: 5006 public:
4793 MathMinMaxInstr(MethodRecognizer::Kind op_kind, 5007 MathMinMaxInstr(MethodRecognizer::Kind op_kind,
4794 Value* left_value, 5008 Value* left_value,
4795 Value* right_value, 5009 Value* right_value,
4796 intptr_t deopt_id, 5010 intptr_t deopt_id,
4797 intptr_t result_cid) 5011 intptr_t result_cid)
4798 : TemplateDefinition(deopt_id), 5012 : TemplateDefinition(deopt_id),
4799 op_kind_(op_kind), 5013 op_kind_(op_kind),
(...skipping 2968 matching lines...) Expand 10 before | Expand all | Expand 10 after
7768 Isolate* isolate, bool opt) const { \ 7982 Isolate* isolate, bool opt) const { \
7769 UNIMPLEMENTED(); \ 7983 UNIMPLEMENTED(); \
7770 return NULL; \ 7984 return NULL; \
7771 } \ 7985 } \
7772 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 7986 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
7773 7987
7774 7988
7775 } // namespace dart 7989 } // namespace dart
7776 7990
7777 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 7991 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698