Revision f230a1cf deps/v8/src/hydrogen-instructions.h
deps/v8/src/hydrogen-instructions.h | ||
---|---|---|
36 | 36 |
#include "deoptimizer.h" |
37 | 37 |
#include "small-pointer-list.h" |
38 | 38 |
#include "string-stream.h" |
39 |
#include "unique.h" |
|
39 | 40 |
#include "v8conversions.h" |
40 | 41 |
#include "v8utils.h" |
41 | 42 |
#include "zone.h" |
... | ... | |
63 | 64 |
|
64 | 65 |
|
65 | 66 |
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ |
67 |
V(AbnormalExit) \ |
|
66 | 68 |
V(AccessArgumentsAt) \ |
67 | 69 |
V(Add) \ |
68 | 70 |
V(Allocate) \ |
... | ... | |
124 | 126 |
V(InnerAllocatedObject) \ |
125 | 127 |
V(InstanceOf) \ |
126 | 128 |
V(InstanceOfKnownGlobal) \ |
127 |
V(InstanceSize) \ |
|
128 | 129 |
V(InvokeFunction) \ |
129 | 130 |
V(IsConstructCallAndBranch) \ |
130 | 131 |
V(IsObjectAndBranch) \ |
131 |
V(IsNumberAndBranch) \ |
|
132 | 132 |
V(IsStringAndBranch) \ |
133 | 133 |
V(IsSmiAndBranch) \ |
134 | 134 |
V(IsUndetectableAndBranch) \ |
... | ... | |
143 | 143 |
V(LoadKeyedGeneric) \ |
144 | 144 |
V(LoadNamedField) \ |
145 | 145 |
V(LoadNamedGeneric) \ |
146 |
V(LoadRoot) \ |
|
146 | 147 |
V(MapEnumLength) \ |
147 | 148 |
V(MathFloorOfDiv) \ |
148 | 149 |
V(MathMinMax) \ |
... | ... | |
305 | 306 |
}; |
306 | 307 |
|
307 | 308 |
|
308 |
class UniqueValueId V8_FINAL { |
|
309 |
public: |
|
310 |
UniqueValueId() : raw_address_(NULL) { } |
|
311 |
|
|
312 |
explicit UniqueValueId(Handle<Object> handle) { |
|
313 |
ASSERT(!AllowHeapAllocation::IsAllowed()); |
|
314 |
static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1); |
|
315 |
if (handle.is_null()) { |
|
316 |
raw_address_ = kEmptyHandleSentinel; |
|
317 |
} else { |
|
318 |
raw_address_ = reinterpret_cast<Address>(*handle); |
|
319 |
ASSERT_NE(kEmptyHandleSentinel, raw_address_); |
|
320 |
} |
|
321 |
ASSERT(IsInitialized()); |
|
322 |
} |
|
323 |
|
|
324 |
bool IsInitialized() const { return raw_address_ != NULL; } |
|
325 |
|
|
326 |
bool operator==(const UniqueValueId& other) const { |
|
327 |
ASSERT(IsInitialized() && other.IsInitialized()); |
|
328 |
return raw_address_ == other.raw_address_; |
|
329 |
} |
|
330 |
|
|
331 |
bool operator!=(const UniqueValueId& other) const { |
|
332 |
ASSERT(IsInitialized() && other.IsInitialized()); |
|
333 |
return raw_address_ != other.raw_address_; |
|
334 |
} |
|
335 |
|
|
336 |
intptr_t Hashcode() const { |
|
337 |
ASSERT(IsInitialized()); |
|
338 |
return reinterpret_cast<intptr_t>(raw_address_); |
|
339 |
} |
|
340 |
|
|
341 |
#define IMMOVABLE_UNIQUE_VALUE_ID(name) \ |
|
342 |
static UniqueValueId name(Heap* heap) { return UniqueValueId(heap->name()); } |
|
343 |
|
|
344 |
IMMOVABLE_UNIQUE_VALUE_ID(free_space_map) |
|
345 |
IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value) |
|
346 |
IMMOVABLE_UNIQUE_VALUE_ID(nan_value) |
|
347 |
IMMOVABLE_UNIQUE_VALUE_ID(undefined_value) |
|
348 |
IMMOVABLE_UNIQUE_VALUE_ID(null_value) |
|
349 |
IMMOVABLE_UNIQUE_VALUE_ID(true_value) |
|
350 |
IMMOVABLE_UNIQUE_VALUE_ID(false_value) |
|
351 |
IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value) |
|
352 |
IMMOVABLE_UNIQUE_VALUE_ID(empty_string) |
|
353 |
|
|
354 |
#undef IMMOVABLE_UNIQUE_VALUE_ID |
|
355 |
|
|
356 |
private: |
|
357 |
Address raw_address_; |
|
358 |
|
|
359 |
explicit UniqueValueId(Object* object) { |
|
360 |
raw_address_ = reinterpret_cast<Address>(object); |
|
361 |
ASSERT(IsInitialized()); |
|
362 |
} |
|
363 |
}; |
|
364 |
|
|
365 |
|
|
366 | 309 |
class HType V8_FINAL { |
367 | 310 |
public: |
368 | 311 |
static HType None() { return HType(kNone); } |
... | ... | |
695 | 638 |
flags_(0) {} |
696 | 639 |
virtual ~HValue() {} |
697 | 640 |
|
641 |
virtual int position() const { return RelocInfo::kNoPosition; } |
|
642 |
|
|
698 | 643 |
HBasicBlock* block() const { return block_; } |
699 | 644 |
void SetBlock(HBasicBlock* block); |
700 | 645 |
int LoopWeight() const; |
... | ... | |
777 | 722 |
return index == kNoRedefinedOperand ? NULL : OperandAt(index); |
778 | 723 |
} |
779 | 724 |
|
725 |
bool CanReplaceWithDummyUses(); |
|
726 |
|
|
727 |
virtual int argument_delta() const { return 0; } |
|
728 |
|
|
780 | 729 |
// A purely informative definition is an idef that will not emit code and |
781 | 730 |
// should therefore be removed from the graph in the RestoreActualValues |
782 | 731 |
// phase (so that live ranges will be shorter). |
783 | 732 |
virtual bool IsPurelyInformativeDefinition() { return false; } |
784 | 733 |
|
785 |
// This method must always return the original HValue SSA definition |
|
786 |
// (regardless of any iDef of this value).
|
|
734 |
// This method must always return the original HValue SSA definition,
|
|
735 |
// regardless of any chain of iDefs of this value.
|
|
787 | 736 |
HValue* ActualValue() { |
788 |
int index = RedefinedOperandIndex(); |
|
789 |
return index == kNoRedefinedOperand ? this : OperandAt(index); |
|
737 |
HValue* value = this; |
|
738 |
int index; |
|
739 |
while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) { |
|
740 |
value = value->OperandAt(index); |
|
741 |
} |
|
742 |
return value; |
|
790 | 743 |
} |
791 | 744 |
|
792 | 745 |
bool IsInteger32Constant(); |
... | ... | |
815 | 768 |
void SetFlag(Flag f) { flags_ |= (1 << f); } |
816 | 769 |
void ClearFlag(Flag f) { flags_ &= ~(1 << f); } |
817 | 770 |
bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } |
771 |
void CopyFlag(Flag f, HValue* other) { |
|
772 |
if (other->CheckFlag(f)) SetFlag(f); |
|
773 |
} |
|
818 | 774 |
|
819 | 775 |
// Returns true if the flag specified is set for all uses, false otherwise. |
820 | 776 |
bool CheckUsesForFlag(Flag f) const; |
... | ... | |
898 | 854 |
virtual intptr_t Hashcode(); |
899 | 855 |
|
900 | 856 |
// Compute unique ids upfront that is safe wrt GC and concurrent compilation. |
901 |
virtual void FinalizeUniqueValueId() { }
|
|
857 |
virtual void FinalizeUniqueness() { }
|
|
902 | 858 |
|
903 | 859 |
// Printing support. |
904 | 860 |
virtual void PrintTo(StringStream* stream) = 0; |
... | ... | |
1104 | 1060 |
return new(zone) I(p1, p2, p3, p4, p5); \ |
1105 | 1061 |
} |
1106 | 1062 |
|
1063 |
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I) \ |
|
1064 |
static I* New(Zone* zone, HValue* context) { \ |
|
1065 |
return new(zone) I(context); \ |
|
1066 |
} |
|
1067 |
|
|
1068 |
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(I, P1) \ |
|
1069 |
static I* New(Zone* zone, HValue* context, P1 p1) { \ |
|
1070 |
return new(zone) I(context, p1); \ |
|
1071 |
} |
|
1072 |
|
|
1073 |
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(I, P1, P2) \ |
|
1074 |
static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) { \ |
|
1075 |
return new(zone) I(context, p1, p2); \ |
|
1076 |
} |
|
1077 |
|
|
1078 |
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(I, P1, P2, P3) \ |
|
1079 |
static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) { \ |
|
1080 |
return new(zone) I(context, p1, p2, p3); \ |
|
1081 |
} |
|
1082 |
|
|
1083 |
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(I, P1, P2, P3, P4) \ |
|
1084 |
static I* New(Zone* zone, \ |
|
1085 |
HValue* context, \ |
|
1086 |
P1 p1, \ |
|
1087 |
P2 p2, \ |
|
1088 |
P3 p3, \ |
|
1089 |
P4 p4) { \ |
|
1090 |
return new(zone) I(context, p1, p2, p3, p4); \ |
|
1091 |
} |
|
1092 |
|
|
1093 |
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(I, P1, P2, P3, P4, P5) \ |
|
1094 |
static I* New(Zone* zone, \ |
|
1095 |
HValue* context, \ |
|
1096 |
P1 p1, \ |
|
1097 |
P2 p2, \ |
|
1098 |
P3 p3, \ |
|
1099 |
P4 p4, \ |
|
1100 |
P5 p5) { \ |
|
1101 |
return new(zone) I(context, p1, p2, p3, p4, p5); \ |
|
1102 |
} |
|
1103 |
|
|
1107 | 1104 |
|
1108 | 1105 |
class HInstruction : public HValue { |
1109 | 1106 |
public: |
... | ... | |
1119 | 1116 |
void InsertAfter(HInstruction* previous); |
1120 | 1117 |
|
1121 | 1118 |
// The position is a write-once variable. |
1122 |
int position() const { return position_; }
|
|
1119 |
virtual int position() const V8_OVERRIDE { return position_; }
|
|
1123 | 1120 |
bool has_position() const { return position_ != RelocInfo::kNoPosition; } |
1124 | 1121 |
void set_position(int position) { |
1125 | 1122 |
ASSERT(!has_position()); |
... | ... | |
1194 | 1191 |
|
1195 | 1192 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
1196 | 1193 |
|
1194 |
virtual bool KnownSuccessorBlock(HBasicBlock** block) { |
|
1195 |
*block = NULL; |
|
1196 |
return false; |
|
1197 |
} |
|
1198 |
|
|
1197 | 1199 |
HBasicBlock* FirstSuccessor() { |
1198 | 1200 |
return SuccessorCount() > 0 ? SuccessorAt(0) : NULL; |
1199 | 1201 |
} |
... | ... | |
1201 | 1203 |
return SuccessorCount() > 1 ? SuccessorAt(1) : NULL; |
1202 | 1204 |
} |
1203 | 1205 |
|
1206 |
void Not() { |
|
1207 |
HBasicBlock* swap = SuccessorAt(0); |
|
1208 |
SetSuccessorAt(0, SuccessorAt(1)); |
|
1209 |
SetSuccessorAt(1, swap); |
|
1210 |
} |
|
1211 |
|
|
1204 | 1212 |
DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction) |
1205 | 1213 |
}; |
1206 | 1214 |
|
... | ... | |
1277 | 1285 |
}; |
1278 | 1286 |
|
1279 | 1287 |
|
1280 |
class HDeoptimize V8_FINAL : public HTemplateInstruction<0> { |
|
1288 |
// Inserts an int3/stop break instruction for debugging purposes. |
|
1289 |
class HDebugBreak V8_FINAL : public HTemplateInstruction<0> { |
|
1281 | 1290 |
public: |
1282 |
DECLARE_INSTRUCTION_FACTORY_P2(HDeoptimize, const char*, |
|
1283 |
Deoptimizer::BailoutType); |
|
1291 |
DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak); |
|
1284 | 1292 |
|
1285 | 1293 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1286 | 1294 |
return Representation::None(); |
1287 | 1295 |
} |
1288 | 1296 |
|
1289 |
const char* reason() const { return reason_; } |
|
1290 |
Deoptimizer::BailoutType type() { return type_; } |
|
1291 |
|
|
1292 |
DECLARE_CONCRETE_INSTRUCTION(Deoptimize) |
|
1293 |
|
|
1294 |
private: |
|
1295 |
explicit HDeoptimize(const char* reason, Deoptimizer::BailoutType type) |
|
1296 |
: reason_(reason), type_(type) {} |
|
1297 |
|
|
1298 |
const char* reason_; |
|
1299 |
Deoptimizer::BailoutType type_; |
|
1297 |
DECLARE_CONCRETE_INSTRUCTION(DebugBreak) |
|
1300 | 1298 |
}; |
1301 | 1299 |
|
1302 | 1300 |
|
1303 |
// Inserts an int3/stop break instruction for debugging purposes. |
|
1304 |
class HDebugBreak V8_FINAL : public HTemplateInstruction<0> { |
|
1301 |
class HGoto V8_FINAL : public HTemplateControlInstruction<1, 0> { |
|
1305 | 1302 |
public: |
1303 |
explicit HGoto(HBasicBlock* target) { |
|
1304 |
SetSuccessorAt(0, target); |
|
1305 |
} |
|
1306 |
|
|
1307 |
virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { |
|
1308 |
*block = FirstSuccessor(); |
|
1309 |
return true; |
|
1310 |
} |
|
1311 |
|
|
1306 | 1312 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1307 | 1313 |
return Representation::None(); |
1308 | 1314 |
} |
1309 | 1315 |
|
1310 |
DECLARE_CONCRETE_INSTRUCTION(DebugBreak) |
|
1316 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
|
1317 |
|
|
1318 |
DECLARE_CONCRETE_INSTRUCTION(Goto) |
|
1311 | 1319 |
}; |
1312 | 1320 |
|
1313 | 1321 |
|
1314 |
class HGoto V8_FINAL : public HTemplateControlInstruction<1, 0> {
|
|
1322 |
class HDeoptimize V8_FINAL : public HTemplateControlInstruction<1, 0> {
|
|
1315 | 1323 |
public: |
1316 |
explicit HGoto(HBasicBlock* target) { |
|
1317 |
SetSuccessorAt(0, target); |
|
1324 |
static HInstruction* New(Zone* zone, |
|
1325 |
HValue* context, |
|
1326 |
const char* reason, |
|
1327 |
Deoptimizer::BailoutType type, |
|
1328 |
HBasicBlock* unreachable_continuation) { |
|
1329 |
return new(zone) HDeoptimize(reason, type, unreachable_continuation); |
|
1330 |
} |
|
1331 |
|
|
1332 |
virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { |
|
1333 |
*block = NULL; |
|
1334 |
return true; |
|
1318 | 1335 |
} |
1319 | 1336 |
|
1320 | 1337 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1321 | 1338 |
return Representation::None(); |
1322 | 1339 |
} |
1323 | 1340 |
|
1324 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
|
1341 |
const char* reason() const { return reason_; } |
|
1342 |
Deoptimizer::BailoutType type() { return type_; } |
|
1325 | 1343 |
|
1326 |
DECLARE_CONCRETE_INSTRUCTION(Goto) |
|
1344 |
DECLARE_CONCRETE_INSTRUCTION(Deoptimize) |
|
1345 |
|
|
1346 |
private: |
|
1347 |
explicit HDeoptimize(const char* reason, |
|
1348 |
Deoptimizer::BailoutType type, |
|
1349 |
HBasicBlock* unreachable_continuation) |
|
1350 |
: reason_(reason), type_(type) { |
|
1351 |
SetSuccessorAt(0, unreachable_continuation); |
|
1352 |
} |
|
1353 |
|
|
1354 |
const char* reason_; |
|
1355 |
Deoptimizer::BailoutType type_; |
|
1327 | 1356 |
}; |
1328 | 1357 |
|
1329 | 1358 |
|
... | ... | |
1345 | 1374 |
|
1346 | 1375 |
class HBranch V8_FINAL : public HUnaryControlInstruction { |
1347 | 1376 |
public: |
1348 |
HBranch(HValue* value, |
|
1349 |
ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), |
|
1350 |
HBasicBlock* true_target = NULL, |
|
1351 |
HBasicBlock* false_target = NULL) |
|
1352 |
: HUnaryControlInstruction(value, true_target, false_target), |
|
1353 |
expected_input_types_(expected_input_types) { |
|
1354 |
SetFlag(kAllowUndefinedAsNaN); |
|
1355 |
} |
|
1377 |
DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*); |
|
1378 |
DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, |
|
1379 |
ToBooleanStub::Types); |
|
1380 |
DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, |
|
1381 |
ToBooleanStub::Types, |
|
1382 |
HBasicBlock*, HBasicBlock*); |
|
1356 | 1383 |
|
1357 | 1384 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1358 | 1385 |
return Representation::None(); |
1359 | 1386 |
} |
1360 | 1387 |
virtual Representation observed_input_representation(int index) V8_OVERRIDE; |
1361 | 1388 |
|
1389 |
virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE; |
|
1390 |
|
|
1362 | 1391 |
ToBooleanStub::Types expected_input_types() const { |
1363 | 1392 |
return expected_input_types_; |
1364 | 1393 |
} |
... | ... | |
1366 | 1395 |
DECLARE_CONCRETE_INSTRUCTION(Branch) |
1367 | 1396 |
|
1368 | 1397 |
private: |
1398 |
HBranch(HValue* value, |
|
1399 |
ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), |
|
1400 |
HBasicBlock* true_target = NULL, |
|
1401 |
HBasicBlock* false_target = NULL) |
|
1402 |
: HUnaryControlInstruction(value, true_target, false_target), |
|
1403 |
expected_input_types_(expected_input_types) { |
|
1404 |
SetFlag(kAllowUndefinedAsNaN); |
|
1405 |
} |
|
1406 |
|
|
1369 | 1407 |
ToBooleanStub::Types expected_input_types_; |
1370 | 1408 |
}; |
1371 | 1409 |
|
1372 | 1410 |
|
1373 | 1411 |
class HCompareMap V8_FINAL : public HUnaryControlInstruction { |
1374 | 1412 |
public: |
1375 |
HCompareMap(HValue* value, |
|
1376 |
Handle<Map> map, |
|
1377 |
HBasicBlock* true_target = NULL, |
|
1378 |
HBasicBlock* false_target = NULL) |
|
1379 |
: HUnaryControlInstruction(value, true_target, false_target), |
|
1380 |
map_(map) { |
|
1381 |
ASSERT(!map.is_null()); |
|
1382 |
} |
|
1413 |
DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); |
|
1414 |
DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, |
|
1415 |
HBasicBlock*, HBasicBlock*); |
|
1383 | 1416 |
|
1384 | 1417 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
1385 | 1418 |
|
1386 |
Handle<Map> map() const { return map_; }
|
|
1419 |
Unique<Map> map() const { return map_; }
|
|
1387 | 1420 |
|
1388 | 1421 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1389 | 1422 |
return Representation::Tagged(); |
... | ... | |
1395 | 1428 |
virtual int RedefinedOperandIndex() { return 0; } |
1396 | 1429 |
|
1397 | 1430 |
private: |
1398 |
Handle<Map> map_; |
|
1431 |
HCompareMap(HValue* value, |
|
1432 |
Handle<Map> map, |
|
1433 |
HBasicBlock* true_target = NULL, |
|
1434 |
HBasicBlock* false_target = NULL) |
|
1435 |
: HUnaryControlInstruction(value, true_target, false_target), |
|
1436 |
map_(Unique<Map>(map)) { |
|
1437 |
ASSERT(!map.is_null()); |
|
1438 |
} |
|
1439 |
|
|
1440 |
Unique<Map> map_; |
|
1399 | 1441 |
}; |
1400 | 1442 |
|
1401 | 1443 |
|
... | ... | |
1426 | 1468 |
|
1427 | 1469 |
class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> { |
1428 | 1470 |
public: |
1429 |
static HInstruction* New(Zone* zone, |
|
1430 |
HValue* context, |
|
1431 |
HValue* value, |
|
1432 |
HValue* parameter_count) { |
|
1433 |
return new(zone) HReturn(value, context, parameter_count); |
|
1434 |
} |
|
1435 |
|
|
1436 |
static HInstruction* New(Zone* zone, |
|
1437 |
HValue* context, |
|
1438 |
HValue* value) { |
|
1439 |
return new(zone) HReturn(value, context, 0); |
|
1440 |
} |
|
1471 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*); |
|
1472 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*); |
|
1441 | 1473 |
|
1442 | 1474 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1443 | 1475 |
return Representation::Tagged(); |
... | ... | |
1452 | 1484 |
DECLARE_CONCRETE_INSTRUCTION(Return) |
1453 | 1485 |
|
1454 | 1486 |
private: |
1455 |
HReturn(HValue* value, HValue* context, HValue* parameter_count) {
|
|
1487 |
HReturn(HValue* context, HValue* value, HValue* parameter_count = 0) {
|
|
1456 | 1488 |
SetOperandAt(0, value); |
1457 | 1489 |
SetOperandAt(1, context); |
1458 | 1490 |
SetOperandAt(2, parameter_count); |
... | ... | |
1460 | 1492 |
}; |
1461 | 1493 |
|
1462 | 1494 |
|
1495 |
class HAbnormalExit V8_FINAL : public HTemplateControlInstruction<0, 0> { |
|
1496 |
public: |
|
1497 |
DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit); |
|
1498 |
|
|
1499 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
|
1500 |
return Representation::None(); |
|
1501 |
} |
|
1502 |
|
|
1503 |
DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) |
|
1504 |
private: |
|
1505 |
HAbnormalExit() {} |
|
1506 |
}; |
|
1507 |
|
|
1508 |
|
|
1463 | 1509 |
class HUnaryOperation : public HTemplateInstruction<1> { |
1464 | 1510 |
public: |
1465 | 1511 |
HUnaryOperation(HValue* value, HType type = HType::Tagged()) |
... | ... | |
1478 | 1524 |
|
1479 | 1525 |
class HThrow V8_FINAL : public HTemplateInstruction<2> { |
1480 | 1526 |
public: |
1481 |
static HThrow* New(Zone* zone, |
|
1482 |
HValue* context, |
|
1483 |
HValue* value) { |
|
1484 |
return new(zone) HThrow(context, value); |
|
1485 |
} |
|
1527 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HThrow, HValue*); |
|
1486 | 1528 |
|
1487 | 1529 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1488 | 1530 |
return Representation::Tagged(); |
... | ... | |
1738 | 1780 |
public: |
1739 | 1781 |
enum Kind { BIND, LOOKUP }; |
1740 | 1782 |
|
1741 |
HEnvironmentMarker(Kind kind, int index) |
|
1742 |
: kind_(kind), index_(index), next_simulate_(NULL) { } |
|
1783 |
DECLARE_INSTRUCTION_FACTORY_P2(HEnvironmentMarker, Kind, int); |
|
1743 | 1784 |
|
1744 | 1785 |
Kind kind() { return kind_; } |
1745 | 1786 |
int index() { return index_; } |
... | ... | |
1766 | 1807 |
DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker); |
1767 | 1808 |
|
1768 | 1809 |
private: |
1810 |
HEnvironmentMarker(Kind kind, int index) |
|
1811 |
: kind_(kind), index_(index), next_simulate_(NULL) { } |
|
1812 |
|
|
1769 | 1813 |
Kind kind_; |
1770 | 1814 |
int index_; |
1771 | 1815 |
HSimulate* next_simulate_; |
... | ... | |
1783 | 1827 |
kBackwardsBranch |
1784 | 1828 |
}; |
1785 | 1829 |
|
1786 |
DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type);
|
|
1830 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HStackCheck, Type);
|
|
1787 | 1831 |
|
1788 | 1832 |
HValue* context() { return OperandAt(0); } |
1789 | 1833 |
|
... | ... | |
1898 | 1942 |
|
1899 | 1943 |
class HLeaveInlined V8_FINAL : public HTemplateInstruction<0> { |
1900 | 1944 |
public: |
1901 |
HLeaveInlined() { } |
|
1945 |
HLeaveInlined(HEnterInlined* entry, |
|
1946 |
int drop_count) |
|
1947 |
: entry_(entry), |
|
1948 |
drop_count_(drop_count) { } |
|
1902 | 1949 |
|
1903 | 1950 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1904 | 1951 |
return Representation::None(); |
1905 | 1952 |
} |
1906 | 1953 |
|
1954 |
virtual int argument_delta() const V8_OVERRIDE { |
|
1955 |
return entry_->arguments_pushed() ? -drop_count_ : 0; |
|
1956 |
} |
|
1957 |
|
|
1907 | 1958 |
DECLARE_CONCRETE_INSTRUCTION(LeaveInlined) |
1959 |
|
|
1960 |
private: |
|
1961 |
HEnterInlined* entry_; |
|
1962 |
int drop_count_; |
|
1908 | 1963 |
}; |
1909 | 1964 |
|
1910 | 1965 |
|
... | ... | |
1916 | 1971 |
return Representation::Tagged(); |
1917 | 1972 |
} |
1918 | 1973 |
|
1974 |
virtual int argument_delta() const V8_OVERRIDE { return 1; } |
|
1919 | 1975 |
HValue* argument() { return OperandAt(0); } |
1920 | 1976 |
|
1921 | 1977 |
DECLARE_CONCRETE_INSTRUCTION(PushArgument) |
... | ... | |
1929 | 1985 |
|
1930 | 1986 |
class HThisFunction V8_FINAL : public HTemplateInstruction<0> { |
1931 | 1987 |
public: |
1932 |
HThisFunction() { |
|
1933 |
set_representation(Representation::Tagged()); |
|
1934 |
SetFlag(kUseGVN); |
|
1935 |
} |
|
1988 |
DECLARE_INSTRUCTION_FACTORY_P0(HThisFunction); |
|
1936 | 1989 |
|
1937 | 1990 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1938 | 1991 |
return Representation::None(); |
... | ... | |
1944 | 1997 |
virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
1945 | 1998 |
|
1946 | 1999 |
private: |
2000 |
HThisFunction() { |
|
2001 |
set_representation(Representation::Tagged()); |
|
2002 |
SetFlag(kUseGVN); |
|
2003 |
} |
|
2004 |
|
|
1947 | 2005 |
virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
1948 | 2006 |
}; |
1949 | 2007 |
|
... | ... | |
1973 | 2031 |
|
1974 | 2032 |
class HDeclareGlobals V8_FINAL : public HUnaryOperation { |
1975 | 2033 |
public: |
1976 |
HDeclareGlobals(HValue* context, |
|
1977 |
Handle<FixedArray> pairs, |
|
1978 |
int flags) |
|
1979 |
: HUnaryOperation(context), |
|
1980 |
pairs_(pairs), |
|
1981 |
flags_(flags) { |
|
1982 |
set_representation(Representation::Tagged()); |
|
1983 |
SetAllSideEffects(); |
|
1984 |
} |
|
1985 |
|
|
1986 |
static HDeclareGlobals* New(Zone* zone, |
|
1987 |
HValue* context, |
|
1988 |
Handle<FixedArray> pairs, |
|
1989 |
int flags) { |
|
1990 |
return new(zone) HDeclareGlobals(context, pairs, flags); |
|
1991 |
} |
|
2034 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HDeclareGlobals, |
|
2035 |
Handle<FixedArray>, |
|
2036 |
int); |
|
1992 | 2037 |
|
1993 | 2038 |
HValue* context() { return OperandAt(0); } |
1994 | 2039 |
Handle<FixedArray> pairs() const { return pairs_; } |
... | ... | |
2001 | 2046 |
} |
2002 | 2047 |
|
2003 | 2048 |
private: |
2049 |
HDeclareGlobals(HValue* context, |
|
2050 |
Handle<FixedArray> pairs, |
|
2051 |
int flags) |
|
2052 |
: HUnaryOperation(context), |
|
2053 |
pairs_(pairs), |
|
2054 |
flags_(flags) { |
|
2055 |
set_representation(Representation::Tagged()); |
|
2056 |
SetAllSideEffects(); |
|
2057 |
} |
|
2058 |
|
|
2004 | 2059 |
Handle<FixedArray> pairs_; |
2005 | 2060 |
int flags_; |
2006 | 2061 |
}; |
... | ... | |
2008 | 2063 |
|
2009 | 2064 |
class HGlobalObject V8_FINAL : public HUnaryOperation { |
2010 | 2065 |
public: |
2011 |
explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { |
|
2012 |
set_representation(Representation::Tagged()); |
|
2013 |
SetFlag(kUseGVN); |
|
2014 |
} |
|
2015 |
|
|
2016 |
static HGlobalObject* New(Zone* zone, HValue* context) { |
|
2017 |
return new(zone) HGlobalObject(context); |
|
2018 |
} |
|
2066 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(HGlobalObject); |
|
2019 | 2067 |
|
2020 | 2068 |
DECLARE_CONCRETE_INSTRUCTION(GlobalObject) |
2021 | 2069 |
|
... | ... | |
2027 | 2075 |
virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
2028 | 2076 |
|
2029 | 2077 |
private: |
2078 |
explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { |
|
2079 |
set_representation(Representation::Tagged()); |
|
2080 |
SetFlag(kUseGVN); |
|
2081 |
} |
|
2082 |
|
|
2030 | 2083 |
virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
2031 | 2084 |
}; |
2032 | 2085 |
|
... | ... | |
2068 | 2121 |
return HType::Tagged(); |
2069 | 2122 |
} |
2070 | 2123 |
|
2071 |
virtual int argument_count() const { return argument_count_; } |
|
2124 |
virtual int argument_count() const { |
|
2125 |
return argument_count_; |
|
2126 |
} |
|
2127 |
|
|
2128 |
virtual int argument_delta() const V8_OVERRIDE { |
|
2129 |
return -argument_count(); |
|
2130 |
} |
|
2072 | 2131 |
|
2073 | 2132 |
virtual bool IsCall() V8_FINAL V8_OVERRIDE { return true; } |
2074 | 2133 |
|
... | ... | |
2117 | 2176 |
|
2118 | 2177 |
class HInvokeFunction V8_FINAL : public HBinaryCall { |
2119 | 2178 |
public: |
2120 |
HInvokeFunction(HValue* context, HValue* function, int argument_count) |
|
2121 |
: HBinaryCall(context, function, argument_count) { |
|
2122 |
} |
|
2123 |
|
|
2124 |
static HInvokeFunction* New(Zone* zone, |
|
2125 |
HValue* context, |
|
2126 |
HValue* function, |
|
2127 |
int argument_count) { |
|
2128 |
return new(zone) HInvokeFunction(context, function, argument_count); |
|
2129 |
} |
|
2179 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int); |
|
2130 | 2180 |
|
2131 | 2181 |
HInvokeFunction(HValue* context, |
2132 | 2182 |
HValue* function, |
... | ... | |
2155 | 2205 |
DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) |
2156 | 2206 |
|
2157 | 2207 |
private: |
2208 |
HInvokeFunction(HValue* context, HValue* function, int argument_count) |
|
2209 |
: HBinaryCall(context, function, argument_count) { |
|
2210 |
} |
|
2211 |
|
|
2158 | 2212 |
Handle<JSFunction> known_function_; |
2159 | 2213 |
int formal_parameter_count_; |
2160 | 2214 |
}; |
... | ... | |
2162 | 2216 |
|
2163 | 2217 |
class HCallConstantFunction V8_FINAL : public HCall<0> { |
2164 | 2218 |
public: |
2165 |
HCallConstantFunction(Handle<JSFunction> function, int argument_count) |
|
2166 |
: HCall<0>(argument_count), |
|
2167 |
function_(function), |
|
2168 |
formal_parameter_count_(function->shared()->formal_parameter_count()) {} |
|
2219 |
DECLARE_INSTRUCTION_FACTORY_P2(HCallConstantFunction, |
|
2220 |
Handle<JSFunction>, |
|
2221 |
int); |
|
2169 | 2222 |
|
2170 | 2223 |
Handle<JSFunction> function() const { return function_; } |
2171 | 2224 |
int formal_parameter_count() const { return formal_parameter_count_; } |
... | ... | |
2184 | 2237 |
DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction) |
2185 | 2238 |
|
2186 | 2239 |
private: |
2240 |
HCallConstantFunction(Handle<JSFunction> function, int argument_count) |
|
2241 |
: HCall<0>(argument_count), |
|
2242 |
function_(function), |
|
2243 |
formal_parameter_count_(function->shared()->formal_parameter_count()) {} |
|
2244 |
|
|
2187 | 2245 |
Handle<JSFunction> function_; |
2188 | 2246 |
int formal_parameter_count_; |
2189 | 2247 |
}; |
... | ... | |
2191 | 2249 |
|
2192 | 2250 |
class HCallKeyed V8_FINAL : public HBinaryCall { |
2193 | 2251 |
public: |
2194 |
HCallKeyed(HValue* context, HValue* key, int argument_count) |
|
2195 |
: HBinaryCall(context, key, argument_count) { |
|
2196 |
} |
|
2252 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallKeyed, HValue*, int); |
|
2197 | 2253 |
|
2198 | 2254 |
HValue* context() { return first(); } |
2199 | 2255 |
HValue* key() { return second(); } |
2200 | 2256 |
|
2201 | 2257 |
DECLARE_CONCRETE_INSTRUCTION(CallKeyed) |
2258 |
|
|
2259 |
private: |
|
2260 |
HCallKeyed(HValue* context, HValue* key, int argument_count) |
|
2261 |
: HBinaryCall(context, key, argument_count) { |
|
2262 |
} |
|
2202 | 2263 |
}; |
2203 | 2264 |
|
2204 | 2265 |
|
2205 | 2266 |
class HCallNamed V8_FINAL : public HUnaryCall { |
2206 | 2267 |
public: |
2207 |
HCallNamed(HValue* context, Handle<String> name, int argument_count) |
|
2208 |
: HUnaryCall(context, argument_count), name_(name) { |
|
2209 |
} |
|
2268 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNamed, Handle<String>, int); |
|
2210 | 2269 |
|
2211 | 2270 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2212 | 2271 |
|
... | ... | |
2216 | 2275 |
DECLARE_CONCRETE_INSTRUCTION(CallNamed) |
2217 | 2276 |
|
2218 | 2277 |
private: |
2278 |
HCallNamed(HValue* context, Handle<String> name, int argument_count) |
|
2279 |
: HUnaryCall(context, argument_count), name_(name) { |
|
2280 |
} |
|
2281 |
|
|
2219 | 2282 |
Handle<String> name_; |
2220 | 2283 |
}; |
2221 | 2284 |
|
2222 | 2285 |
|
2223 | 2286 |
class HCallFunction V8_FINAL : public HBinaryCall { |
2224 | 2287 |
public: |
2225 |
HCallFunction(HValue* context, HValue* function, int argument_count) |
|
2226 |
: HBinaryCall(context, function, argument_count) { |
|
2227 |
} |
|
2228 |
|
|
2229 |
static HCallFunction* New(Zone* zone, |
|
2230 |
HValue* context, |
|
2231 |
HValue* function, |
|
2232 |
int argument_count) { |
|
2233 |
return new(zone) HCallFunction(context, function, argument_count); |
|
2234 |
} |
|
2288 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallFunction, HValue*, int); |
|
2235 | 2289 |
|
2236 | 2290 |
HValue* context() { return first(); } |
2237 | 2291 |
HValue* function() { return second(); } |
2238 | 2292 |
|
2239 | 2293 |
DECLARE_CONCRETE_INSTRUCTION(CallFunction) |
2294 |
|
|
2295 |
private: |
|
2296 |
HCallFunction(HValue* context, HValue* function, int argument_count) |
|
2297 |
: HBinaryCall(context, function, argument_count) { |
|
2298 |
} |
|
2240 | 2299 |
}; |
2241 | 2300 |
|
2242 | 2301 |
|
2243 | 2302 |
class HCallGlobal V8_FINAL : public HUnaryCall { |
2244 | 2303 |
public: |
2245 |
HCallGlobal(HValue* context, Handle<String> name, int argument_count) |
|
2246 |
: HUnaryCall(context, argument_count), name_(name) { |
|
2247 |
} |
|
2248 |
|
|
2249 |
static HCallGlobal* New(Zone* zone, |
|
2250 |
HValue* context, |
|
2251 |
Handle<String> name, |
|
2252 |
int argument_count) { |
|
2253 |
return new(zone) HCallGlobal(context, name, argument_count); |
|
2254 |
} |
|
2304 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallGlobal, Handle<String>, int); |
|
2255 | 2305 |
|
2256 | 2306 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2257 | 2307 |
|
... | ... | |
2261 | 2311 |
DECLARE_CONCRETE_INSTRUCTION(CallGlobal) |
2262 | 2312 |
|
2263 | 2313 |
private: |
2314 |
HCallGlobal(HValue* context, Handle<String> name, int argument_count) |
|
2315 |
: HUnaryCall(context, argument_count), name_(name) { |
|
2316 |
} |
|
2317 |
|
|
2264 | 2318 |
Handle<String> name_; |
2265 | 2319 |
}; |
2266 | 2320 |
|
2267 | 2321 |
|
2268 | 2322 |
class HCallKnownGlobal V8_FINAL : public HCall<0> { |
2269 | 2323 |
public: |
2270 |
HCallKnownGlobal(Handle<JSFunction> target, int argument_count) |
|
2271 |
: HCall<0>(argument_count), |
|
2272 |
target_(target), |
|
2273 |
formal_parameter_count_(target->shared()->formal_parameter_count()) { } |
|
2324 |
DECLARE_INSTRUCTION_FACTORY_P2(HCallKnownGlobal, Handle<JSFunction>, int); |
|
2274 | 2325 |
|
2275 | 2326 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2276 | 2327 |
|
... | ... | |
2284 | 2335 |
DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal) |
2285 | 2336 |
|
2286 | 2337 |
private: |
2338 |
HCallKnownGlobal(Handle<JSFunction> target, int argument_count) |
|
2339 |
: HCall<0>(argument_count), |
|
2340 |
target_(target), |
|
2341 |
formal_parameter_count_(target->shared()->formal_parameter_count()) { } |
|
2342 |
|
|
2287 | 2343 |
Handle<JSFunction> target_; |
2288 | 2344 |
int formal_parameter_count_; |
2289 | 2345 |
}; |
... | ... | |
2291 | 2347 |
|
2292 | 2348 |
class HCallNew V8_FINAL : public HBinaryCall { |
2293 | 2349 |
public: |
2294 |
HCallNew(HValue* context, HValue* constructor, int argument_count) |
|
2295 |
: HBinaryCall(context, constructor, argument_count) {} |
|
2350 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int); |
|
2296 | 2351 |
|
2297 | 2352 |
HValue* context() { return first(); } |
2298 | 2353 |
HValue* constructor() { return second(); } |
2299 | 2354 |
|
2300 | 2355 |
DECLARE_CONCRETE_INSTRUCTION(CallNew) |
2356 |
|
|
2357 |
private: |
|
2358 |
HCallNew(HValue* context, HValue* constructor, int argument_count) |
|
2359 |
: HBinaryCall(context, constructor, argument_count) {} |
|
2301 | 2360 |
}; |
2302 | 2361 |
|
2303 | 2362 |
|
2304 | 2363 |
class HCallNewArray V8_FINAL : public HBinaryCall { |
2305 | 2364 |
public: |
2306 |
HCallNewArray(HValue* context, HValue* constructor, int argument_count,
|
|
2307 |
Handle<Cell> type_cell, ElementsKind elements_kind)
|
|
2308 |
: HBinaryCall(context, constructor, argument_count),
|
|
2309 |
elements_kind_(elements_kind),
|
|
2310 |
type_cell_(type_cell) {}
|
|
2365 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray,
|
|
2366 |
HValue*,
|
|
2367 |
int,
|
|
2368 |
Handle<Cell>,
|
|
2369 |
ElementsKind);
|
|
2311 | 2370 |
|
2312 | 2371 |
HValue* context() { return first(); } |
2313 | 2372 |
HValue* constructor() { return second(); } |
... | ... | |
2323 | 2382 |
DECLARE_CONCRETE_INSTRUCTION(CallNewArray) |
2324 | 2383 |
|
2325 | 2384 |
private: |
2385 |
HCallNewArray(HValue* context, HValue* constructor, int argument_count, |
|
2386 |
Handle<Cell> type_cell, ElementsKind elements_kind) |
|
2387 |
: HBinaryCall(context, constructor, argument_count), |
|
2388 |
elements_kind_(elements_kind), |
|
2389 |
type_cell_(type_cell) {} |
|
2390 |
|
|
2326 | 2391 |
ElementsKind elements_kind_; |
2327 | 2392 |
Handle<Cell> type_cell_; |
2328 | 2393 |
}; |
... | ... | |
2330 | 2395 |
|
2331 | 2396 |
class HCallRuntime V8_FINAL : public HCall<1> { |
2332 | 2397 |
public: |
2333 |
static HCallRuntime* New(Zone* zone, |
|
2334 |
HValue* context, |
|
2335 |
Handle<String> name, |
|
2336 |
const Runtime::Function* c_function, |
|
2337 |
int argument_count) { |
|
2338 |
return new(zone) HCallRuntime(context, name, c_function, argument_count); |
|
2339 |
} |
|
2398 |
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCallRuntime, |
|
2399 |
Handle<String>, |
|
2400 |
const Runtime::Function*, |
|
2401 |
int); |
|
2340 | 2402 |
|
2341 | 2403 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2342 | 2404 |
|
2343 | 2405 |
HValue* context() { return OperandAt(0); } |
2344 | 2406 |
const Runtime::Function* function() const { return c_function_; } |
2345 | 2407 |
Handle<String> name() const { return name_; } |
2408 |
SaveFPRegsMode save_doubles() const { return save_doubles_; } |
|
2409 |
void set_save_doubles(SaveFPRegsMode save_doubles) { |
|
2410 |
save_doubles_ = save_doubles; |
|
2411 |
} |
|
2346 | 2412 |
|
2347 | 2413 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
2348 | 2414 |
return Representation::Tagged(); |
... | ... | |
2355 | 2421 |
Handle<String> name, |
2356 | 2422 |
const Runtime::Function* c_function, |
2357 | 2423 |
int argument_count) |
2358 |
: HCall<1>(argument_count), c_function_(c_function), name_(name) { |
|
2424 |
: HCall<1>(argument_count), c_function_(c_function), name_(name), |
|
2425 |
save_doubles_(kDontSaveFPRegs) { |
|
2359 | 2426 |
SetOperandAt(0, context); |
2360 | 2427 |
} |
2361 | 2428 |
|
2362 | 2429 |
const Runtime::Function* c_function_; |
2363 | 2430 |
Handle<String> name_; |
2431 |
SaveFPRegsMode save_doubles_; |
|
2364 | 2432 |
}; |
2365 | 2433 |
|
2366 | 2434 |
|
... | ... | |
2509 | 2577 |
}; |
2510 | 2578 |
|
2511 | 2579 |
|
2580 |
class HLoadRoot V8_FINAL : public HTemplateInstruction<0> { |
|
2581 |
public: |
|
2582 |
DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex); |
|
2583 |
DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType); |
|
2584 |
|
|
2585 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
|
2586 |
return Representation::None(); |
|
2587 |
} |
|
2588 |
|
|
2589 |
Heap::RootListIndex index() const { return index_; } |
|
2590 |
|
|
2591 |
DECLARE_CONCRETE_INSTRUCTION(LoadRoot) |
|
2592 |
|
|
2593 |
protected: |
|
2594 |
virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
|
2595 |
HLoadRoot* b = HLoadRoot::cast(other); |
|
2596 |
return index_ == b->index_; |
|
2597 |
} |
|
2598 |
|
|
2599 |
private: |
|
2600 |
HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged()) |
|
2601 |
: HTemplateInstruction<0>(type), index_(index) { |
|
2602 |
SetFlag(kUseGVN); |
|
2603 |
// TODO(bmeurer): We'll need kDependsOnRoots once we add the |
|
2604 |
// corresponding HStoreRoot instruction. |
|
2605 |
SetGVNFlag(kDependsOnCalls); |
|
2606 |
} |
|
2607 |
|
|
2608 |
virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
|
2609 |
|
|
2610 |
const Heap::RootListIndex index_; |
|
2611 |
}; |
|
2612 |
|
|
2613 |
|
|
2512 | 2614 |
class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation { |
2513 | 2615 |
public: |
2514 | 2616 |
DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*); |
... | ... | |
2553 | 2655 |
for (int i = 0; i < maps->length(); i++) { |
2554 | 2656 |
check_map->Add(maps->at(i), zone); |
2555 | 2657 |
} |
2556 |
check_map->map_set_.Sort(); |
|
2557 | 2658 |
return check_map; |
2558 | 2659 |
} |
2559 | 2660 |
|
... | ... | |
2568 | 2669 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2569 | 2670 |
|
2570 | 2671 |
HValue* value() { return OperandAt(0); } |
2571 |
SmallMapList* map_set() { return &map_set_; } |
|
2572 |
ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; } |
|
2573 | 2672 |
|
2574 |
bool has_migration_target() { |
|
2673 |
Unique<Map> first_map() const { return map_set_.at(0); } |
|
2674 |
UniqueSet<Map> map_set() const { return map_set_; } |
|
2675 |
|
|
2676 |
bool has_migration_target() const { |
|
2575 | 2677 |
return has_migration_target_; |
2576 | 2678 |
} |
2577 | 2679 |
|
2578 |
virtual void FinalizeUniqueValueId() V8_OVERRIDE; |
|
2579 |
|
|
2580 | 2680 |
DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
2581 | 2681 |
|
2582 | 2682 |
protected: |
2583 | 2683 |
virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
2584 |
ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); |
|
2585 |
HCheckMaps* b = HCheckMaps::cast(other); |
|
2586 |
// Relies on the fact that map_set has been sorted before. |
|
2587 |
if (map_unique_ids_.length() != b->map_unique_ids_.length()) { |
|
2588 |
return false; |
|
2589 |
} |
|
2590 |
for (int i = 0; i < map_unique_ids_.length(); i++) { |
|
2591 |
if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { |
|
2592 |
return false; |
|
2593 |
} |
|
2594 |
} |
|
2595 |
return true; |
|
2684 |
return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); |
|
2596 | 2685 |
} |
2597 | 2686 |
|
2598 | 2687 |
virtual int RedefinedOperandIndex() { return 0; } |
2599 | 2688 |
|
2600 | 2689 |
private: |
2601 | 2690 |
void Add(Handle<Map> map, Zone* zone) { |
2602 |
map_set_.Add(map, zone);
|
|
2691 |
map_set_.Add(Unique<Map>(map), zone);
|
|
2603 | 2692 |
if (!has_migration_target_ && map->is_migration_target()) { |
2604 | 2693 |
has_migration_target_ = true; |
2605 | 2694 |
SetGVNFlag(kChangesNewSpacePromotion); |
... | ... | |
2609 | 2698 |
// Clients should use one of the static New* methods above. |
2610 | 2699 |
HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) |
2611 | 2700 |
: HTemplateInstruction<2>(value->type()), |
2612 |
omit_(false), has_migration_target_(false), map_unique_ids_(0, zone) {
|
|
2701 |
omit_(false), has_migration_target_(false) { |
|
2613 | 2702 |
SetOperandAt(0, value); |
2614 | 2703 |
// Use the object value for the dependency if NULL is passed. |
2615 |
// TODO(titzer): do GVN flags already express this dependency? |
|
2616 | 2704 |
SetOperandAt(1, typecheck != NULL ? typecheck : value); |
2617 | 2705 |
set_representation(Representation::Tagged()); |
2618 | 2706 |
SetFlag(kUseGVN); |
... | ... | |
2621 | 2709 |
SetGVNFlag(kDependsOnElementsKind); |
2622 | 2710 |
} |
2623 | 2711 |
|
2624 |
void omit(CompilationInfo* info) { |
|
2625 |
omit_ = true; |
|
2626 |
for (int i = 0; i < map_set_.length(); i++) { |
|
2627 |
Handle<Map> map = map_set_.at(i); |
|
2628 |
if (!map->CanTransition()) continue; |
|
2629 |
map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, |
|
2630 |
info); |
|
2631 |
} |
|
2632 |
} |
|
2633 |
|
|
2634 | 2712 |
bool omit_; |
2635 | 2713 |
bool has_migration_target_; |
2636 |
SmallMapList map_set_; |
|
2637 |
ZoneList<UniqueValueId> map_unique_ids_; |
|
2714 |
UniqueSet<Map> map_set_; |
|
2638 | 2715 |
}; |
2639 | 2716 |
|
2640 | 2717 |
|
2641 | 2718 |
class HCheckValue V8_FINAL : public HUnaryOperation { |
2642 | 2719 |
public: |
2643 | 2720 |
static HCheckValue* New(Zone* zone, HValue* context, |
2644 |
HValue* value, Handle<JSFunction> target) { |
|
2645 |
bool in_new_space = zone->isolate()->heap()->InNewSpace(*target); |
|
2721 |
HValue* value, Handle<JSFunction> func) { |
|
2722 |
bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); |
|
2723 |
// NOTE: We create an uninitialized Unique and initialize it later. |
|
2724 |
// This is because a JSFunction can move due to GC during graph creation. |
|
2725 |
// TODO(titzer): This is a migration crutch. Replace with some kind of |
|
2726 |
// Uniqueness scope later. |
|
2727 |
Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func); |
|
2646 | 2728 |
HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); |
2647 | 2729 |
return check; |
2648 | 2730 |
} |
2649 | 2731 |
static HCheckValue* New(Zone* zone, HValue* context, |
2650 |
HValue* value, Handle<Map> map, UniqueValueId id) { |
|
2651 |
HCheckValue* check = new(zone) HCheckValue(value, map, false); |
|
2652 |
check->object_unique_id_ = id; |
|
2653 |
return check; |
|
2732 |
HValue* value, Unique<HeapObject> target, |
|
2733 |
bool object_in_new_space) { |
|
2734 |
return new(zone) HCheckValue(value, target, object_in_new_space); |
|
2735 |
} |
|
2736 |
|
|
2737 |
virtual void FinalizeUniqueness() V8_OVERRIDE { |
|
2738 |
object_ = Unique<HeapObject>(object_.handle()); |
|
2654 | 2739 |
} |
2655 | 2740 |
|
2656 | 2741 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
... | ... | |
2664 | 2749 |
virtual void Verify() V8_OVERRIDE; |
2665 | 2750 |
#endif |
2666 | 2751 |
|
2667 |
virtual void FinalizeUniqueValueId() V8_OVERRIDE { |
|
2668 |
object_unique_id_ = UniqueValueId(object_); |
|
2669 |
} |
|
2670 |
|
|
2671 |
Handle<HeapObject> object() const { return object_; } |
|
2752 |
Unique<HeapObject> object() const { return object_; } |
|
2672 | 2753 |
bool object_in_new_space() const { return object_in_new_space_; } |
2673 | 2754 |
|
2674 | 2755 |
DECLARE_CONCRETE_INSTRUCTION(CheckValue) |
... | ... | |
2676 | 2757 |
protected: |
2677 | 2758 |
virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
2678 | 2759 |
HCheckValue* b = HCheckValue::cast(other); |
2679 |
return object_unique_id_ == b->object_unique_id_;
|
|
2760 |
return object_ == b->object_;
|
|
2680 | 2761 |
} |
2681 | 2762 |
|
2682 | 2763 |
private: |
2683 |
HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space) |
|
2764 |
HCheckValue(HValue* value, Unique<HeapObject> object, |
|
2765 |
bool object_in_new_space) |
|
2684 | 2766 |
: HUnaryOperation(value, value->type()), |
2685 |
object_(object), object_in_new_space_(in_new_space) { |
|
2767 |
object_(object), |
|
2768 |
object_in_new_space_(object_in_new_space) { |
|
2686 | 2769 |
set_representation(Representation::Tagged()); |
2687 | 2770 |
SetFlag(kUseGVN); |
2688 | 2771 |
} |
2689 | 2772 |
|
2690 |
Handle<HeapObject> object_; |
|
2691 |
UniqueValueId object_unique_id_; |
|
2773 |
Unique<HeapObject> object_; |
|
2692 | 2774 |
bool object_in_new_space_; |
2693 | 2775 |
}; |
2694 | 2776 |
|
2695 | 2777 |
|
2696 | 2778 |
class HCheckInstanceType V8_FINAL : public HUnaryOperation { |
2697 | 2779 |
public: |
2698 |
static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { |
|
2699 |
return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); |
|
2700 |
} |
|
2701 |
static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { |
|
2702 |
return new(zone) HCheckInstanceType(value, IS_JS_ARRAY); |
|
2703 |
} |
|
2704 |
static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) { |
|
2705 |
return new(zone) HCheckInstanceType(value, IS_STRING); |
|
2706 |
} |
|
2707 |
static HCheckInstanceType* NewIsInternalizedString( |
|
2708 |
HValue* value, Zone* zone) { |
|
2709 |
return new(zone) HCheckInstanceType(value, IS_INTERNALIZED_STRING); |
|
2710 |
} |
|
2780 |
enum Check { |
|
2781 |
IS_SPEC_OBJECT, |
|
2782 |
IS_JS_ARRAY, |
|
2783 |
IS_STRING, |
|
2784 |
IS_INTERNALIZED_STRING, |
|
2785 |
LAST_INTERVAL_CHECK = IS_JS_ARRAY |
|
2786 |
}; |
|
2787 |
|
|
2788 |
DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check); |
|
2711 | 2789 |
|
2712 | 2790 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2713 | 2791 |
|
... | ... | |
2735 | 2813 |
virtual int RedefinedOperandIndex() { return 0; } |
2736 | 2814 |
|
2737 | 2815 |
private: |
2738 |
enum Check { |
|
2739 |
IS_SPEC_OBJECT, |
|
2740 |
IS_JS_ARRAY, |
|
2741 |
IS_STRING, |
|
2742 |
IS_INTERNALIZED_STRING, |
|
2743 |
LAST_INTERVAL_CHECK = IS_JS_ARRAY |
|
2744 |
}; |
|
2745 |
|
|
2746 | 2816 |
const char* GetCheckName(); |
2747 | 2817 |
|
2748 | 2818 |
HCheckInstanceType(HValue* value, Check check) |
... | ... | |
2784 | 2854 |
}; |
2785 | 2855 |
|
2786 | 2856 |
|
2787 |
class HIsNumberAndBranch V8_FINAL : public HUnaryControlInstruction { |
|
2788 |
public: |
|
2789 |
explicit HIsNumberAndBranch(HValue* value) |
|
2790 |
: HUnaryControlInstruction(value, NULL, NULL) { |
|
2791 |
SetFlag(kFlexibleRepresentation); |
|
2792 |
} |
|
2793 |
|
|
2794 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
|
2795 |
return Representation::None(); |
|
2796 |
} |
|
2797 |
|
|
2798 |
DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch) |
|
2799 |
}; |
|
2800 |
|
|
2801 |
|
|
2802 | 2857 |
class HCheckHeapObject V8_FINAL : public HUnaryOperation { |
2803 | 2858 |
public: |
2804 | 2859 |
DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); |
... | ... | |
3090 | 3145 |
bool IsReceiver() const { return merged_index_ == 0; } |
3091 | 3146 |
bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } |
3092 | 3147 |
|
3148 |
virtual int position() const V8_OVERRIDE; |
|
3149 |
|
|
3093 | 3150 |
int merged_index() const { return merged_index_; } |
3094 | 3151 |
|
3095 | 3152 |
InductionVariableData* induction_variable_data() { |
... | ... | |
3260 | 3317 |
// Replay effects of this instruction on the given environment. |
3261 | 3318 |
void ReplayEnvironment(HEnvironment* env); |
3262 | 3319 |
|
3320 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
|
3321 |
|
|
3263 | 3322 |
DECLARE_CONCRETE_INSTRUCTION(CapturedObject) |
3264 | 3323 |
|
3265 | 3324 |
private: |
... | ... | |
3273 | 3332 |
DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation); |
3274 | 3333 |
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); |
3275 | 3334 |
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); |
3276 |
DECLARE_INSTRUCTION_FACTORY_P2(HConstant, Handle<Map>, UniqueValueId); |
|
3277 | 3335 |
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); |
3278 | 3336 |
|
3279 | 3337 |
static HConstant* CreateAndInsertAfter(Zone* zone, |
... | ... | |
3298 | 3356 |
return new_constant; |
3299 | 3357 |
} |
3300 | 3358 |
|
3359 |
static HConstant* CreateAndInsertBefore(Zone* zone, |
|
3360 |
Unique<Object> unique, |
|
3361 |
bool is_not_in_new_space, |
|
3362 |
HInstruction* instruction) { |
|
3363 |
HConstant* new_constant = new(zone) HConstant(unique, |
|
3364 |
Representation::Tagged(), HType::Tagged(), false, is_not_in_new_space, |
|
3365 |
false, false); |
|
3366 |
new_constant->InsertBefore(instruction); |
|
3367 |
return new_constant; |
|
3368 |
} |
|
3369 |
|
|
3301 | 3370 |
Handle<Object> handle(Isolate* isolate) { |
3302 |
if (handle_.is_null()) { |
|
3303 |
Factory* factory = isolate->factory(); |
|
3371 |
if (object_.handle().is_null()) { |
|
3304 | 3372 |
// Default arguments to is_not_in_new_space depend on this heap number |
3305 |
// to be tenured so that it's guaranteed not be be located in new space. |
|
3306 |
handle_ = factory->NewNumber(double_value_, TENURED); |
|
3373 |
// to be tenured so that it's guaranteed not to be located in new space. |
|
3374 |
object_ = Unique<Object>::CreateUninitialized( |
|
3375 |
isolate->factory()->NewNumber(double_value_, TENURED)); |
|
3307 | 3376 |
} |
3308 | 3377 |
AllowDeferredHandleDereference smi_check; |
3309 |
ASSERT(has_int32_value_ || !handle_->IsSmi());
|
|
3310 |
return handle_;
|
|
3378 |
ASSERT(has_int32_value_ || !object_.handle()->IsSmi());
|
|
3379 |
return object_.handle();
|
|
3311 | 3380 |
} |
3312 | 3381 |
|
3313 | 3382 |
bool HasMap(Handle<Map> map) { |
... | ... | |
3341 | 3410 |
return false; |
3342 | 3411 |
} |
3343 | 3412 |
|
3344 |
ASSERT(!handle_.is_null());
|
|
3413 |
ASSERT(!object_.handle().is_null());
|
|
3345 | 3414 |
Heap* heap = isolate()->heap(); |
3346 |
ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap)); |
|
3347 |
ASSERT(unique_id_ != UniqueValueId::nan_value(heap)); |
|
3348 |
return unique_id_ == UniqueValueId::undefined_value(heap) || |
|
3349 |
unique_id_ == UniqueValueId::null_value(heap) || |
|
3350 |
unique_id_ == UniqueValueId::true_value(heap) || |
|
3351 |
unique_id_ == UniqueValueId::false_value(heap) || |
|
3352 |
unique_id_ == UniqueValueId::the_hole_value(heap) || |
|
3353 |
unique_id_ == UniqueValueId::empty_string(heap); |
|
3415 |
ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value())); |
|
3416 |
ASSERT(!object_.IsKnownGlobal(heap->nan_value())); |
|
3417 |
return |
|
3418 |
object_.IsKnownGlobal(heap->undefined_value()) || |
|
3419 |
object_.IsKnownGlobal(heap->null_value()) || |
|
3420 |
object_.IsKnownGlobal(heap->true_value()) || |
|
3421 |
object_.IsKnownGlobal(heap->false_value()) || |
|
3422 |
object_.IsKnownGlobal(heap->the_hole_value()) || |
|
3423 |
object_.IsKnownGlobal(heap->empty_string()) || |
|
3424 |
object_.IsKnownGlobal(heap->empty_fixed_array()); |
|
3354 | 3425 |
} |
3355 | 3426 |
|
3356 | 3427 |
bool IsCell() const { |
... | ... | |
3389 | 3460 |
if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) { |
3390 | 3461 |
return true; |
3391 | 3462 |
} |
3392 |
Heap* heap = isolate()->heap(); |
|
3393 |
if (!handle_.is_null() && *handle_ == heap->the_hole_value()) { |
|
3394 |
return true; |
|
3395 |
} |
|
3396 |
return false; |
|
3463 |
return object_.IsKnownGlobal(isolate()->heap()->the_hole_value()); |
|
3397 | 3464 |
} |
3398 | 3465 |
bool HasNumberValue() const { return has_double_value_; } |
3399 | 3466 |
int32_t NumberValueAsInteger32() const { |
... | ... | |
3405 | 3472 |
} |
3406 | 3473 |
bool HasStringValue() const { |
3407 | 3474 |
if (has_double_value_ || has_int32_value_) return false; |
3408 |
ASSERT(!handle_.is_null());
|
|
3475 |
ASSERT(!object_.handle().is_null());
|
|
3409 | 3476 |
return type_.IsString(); |
3410 | 3477 |
} |
3411 | 3478 |
Handle<String> StringValue() const { |
3412 | 3479 |
ASSERT(HasStringValue()); |
3413 |
return Handle<String>::cast(handle_);
|
|
3480 |
return Handle<String>::cast(object_.handle());
|
|
3414 | 3481 |
} |
3415 | 3482 |
bool HasInternalizedStringValue() const { |
3416 | 3483 |
return HasStringValue() && is_internalized_string_; |
... | ... | |
3434 | 3501 |
} else if (has_external_reference_value_) { |
3435 | 3502 |
return reinterpret_cast<intptr_t>(external_reference_value_.address()); |
3436 | 3503 |
} else { |
3437 |
ASSERT(!handle_.is_null());
|
|
3438 |
return unique_id_.Hashcode();
|
|
3504 |
ASSERT(!object_.handle().is_null());
|
|
3505 |
return object_.Hashcode();
|
|
3439 | 3506 |
} |
3440 | 3507 |
} |
3441 | 3508 |
|
3442 |
virtual void FinalizeUniqueValueId() V8_OVERRIDE {
|
|
3509 |
virtual void FinalizeUniqueness() V8_OVERRIDE {
|
|
3443 | 3510 |
if (!has_double_value_ && !has_external_reference_value_) { |
3444 |
ASSERT(!handle_.is_null());
|
|
3445 |
unique_id_ = UniqueValueId(handle_);
|
|
3511 |
ASSERT(!object_.handle().is_null());
|
|
3512 |
object_ = Unique<Object>(object_.handle());
|
|
3446 | 3513 |
} |
3447 | 3514 |
} |
3448 | 3515 |
|
3449 |
bool UniqueValueIdsMatch(UniqueValueId other) { |
|
3450 |
return !has_double_value_ && !has_external_reference_value_ && |
|
3451 |
unique_id_ == other; |
|
3516 |
Unique<Object> GetUnique() const { |
|
3517 |
return object_; |
|
3452 | 3518 |
} |
3453 | 3519 |
|
3454 | 3520 |
#ifdef DEBUG |
... | ... | |
3474 | 3540 |
external_reference_value_ == |
3475 | 3541 |
other_constant->external_reference_value_; |
3476 | 3542 |
} else { |
3477 |
ASSERT(!handle_.is_null()); |
|
3478 |
return !other_constant->handle_.is_null() && |
|
3479 |
unique_id_ == other_constant->unique_id_; |
|
3543 |
if (other_constant->has_int32_value_ || |
|
3544 |
other_constant->has_double_value_ || |
|
3545 |
other_constant->has_external_reference_value_) { |
|
3546 |
return false; |
|
3547 |
} |
|
3548 |
ASSERT(!object_.handle().is_null()); |
|
3549 |
return other_constant->object_ == object_; |
|
3480 | 3550 |
} |
3481 | 3551 |
} |
3482 | 3552 |
|
... | ... | |
3486 | 3556 |
HConstant(int32_t value, |
3487 | 3557 |
Representation r = Representation::None(), |
3488 | 3558 |
bool is_not_in_new_space = true, |
3489 |
Handle<Object> optional_handle = Handle<Object>::null());
|
|
3559 |
Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
|
|
3490 | 3560 |
HConstant(double value, |
3491 | 3561 |
Representation r = Representation::None(), |
3492 | 3562 |
bool is_not_in_new_space = true, |
3493 |
Handle<Object> optional_handle = Handle<Object>::null()); |
|
3494 |
HConstant(Handle<Object> handle, |
|
3495 |
UniqueValueId unique_id, |
|
3563 |
Unique<Object> optional = Unique<Object>(Handle<Object>::null())); |
|
3564 |
HConstant(Unique<Object> unique, |
|
3496 | 3565 |
Representation r, |
3497 | 3566 |
HType type, |
3498 | 3567 |
bool is_internalized_string, |
3499 | 3568 |
bool is_not_in_new_space, |
3500 | 3569 |
bool is_cell, |
3501 | 3570 |
bool boolean_value); |
3502 |
HConstant(Handle<Map> handle, |
|
3503 |
UniqueValueId unique_id); |
|
3571 |
|
|
3504 | 3572 |
explicit HConstant(ExternalReference reference); |
3505 | 3573 |
|
3506 | 3574 |
void Initialize(Representation r); |
3507 | 3575 |
|
3508 | 3576 |
virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
3509 | 3577 |
|
3510 |
// If this is a numerical constant, handle_ either points to to the
|
|
3578 |
// If this is a numerical constant, object_ either points to the
|
|
3511 | 3579 |
// HeapObject the constant originated from or is null. If the |
3512 |
// constant is non-numeric, handle_ always points to a valid
|
|
3580 |
// constant is non-numeric, object_ always points to a valid
|
|
3513 | 3581 |
// constant HeapObject. |
3514 |
Handle<Object> handle_; |
|
3515 |
UniqueValueId unique_id_; |
|
3582 |
Unique<Object> object_; |
|
3516 | 3583 |
|
3517 | 3584 |
// We store the HConstant in the most specific form safely possible. |
3518 | 3585 |
// The two flags, has_int32_value_ and has_double_value_ tell us if |
... | ... | |
3649 | 3716 |
|
3650 | 3717 |
class HApplyArguments V8_FINAL : public HTemplateInstruction<4> { |
3651 | 3718 |
public: |
3652 |
HApplyArguments(HValue* function, |
|
3653 |
HValue* receiver, |
|
3654 |
HValue* length, |
|
3655 |
HValue* elements) { |
|
3656 |
set_representation(Representation::Tagged()); |
|
3657 |
SetOperandAt(0, function); |
|
3658 |
SetOperandAt(1, receiver); |
|
3659 |
SetOperandAt(2, length); |
|
3660 |
SetOperandAt(3, elements); |
|
3661 |
SetAllSideEffects(); |
|
3662 |
} |
|
3719 |
DECLARE_INSTRUCTION_FACTORY_P4(HApplyArguments, HValue*, HValue*, HValue*, |
|
3720 |
HValue*); |
|
3663 | 3721 |
|
3664 | 3722 |
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
3665 | 3723 |
// The length is untagged, all other inputs are tagged. |
... | ... | |
3674 | 3732 |
HValue* elements() { return OperandAt(3); } |
3675 | 3733 |
|
3676 | 3734 |
DECLARE_CONCRETE_INSTRUCTION(ApplyArguments) |
3735 |
|
|
3736 |
private: |
|
3737 |
HApplyArguments(HValue* function, |
|
3738 |
HValue* receiver, |
|
3739 |
HValue* length, |
|
3740 |
HValue* elements) { |
|
3741 |
set_representation(Representation::Tagged()); |
|
3742 |
SetOperandAt(0, function); |
|
3743 |
SetOperandAt(1, receiver); |
|
3744 |
SetOperandAt(2, length); |
|
3745 |
SetOperandAt(3, elements); |
|
3746 |
SetAllSideEffects(); |
|
3747 |
} |
|
3677 | 3748 |
}; |
3678 | 3749 |
|
3679 | 3750 |
|
... | ... | |
3731 | 3802 |
|
3732 | 3803 |
class HAccessArgumentsAt V8_FINAL : public HTemplateInstruction<3> { |
3733 | 3804 |
public: |
3734 |
HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { |
|
3735 |
set_representation(Representation::Tagged()); |
|
3736 |
SetFlag(kUseGVN); |
|
3737 |
SetOperandAt(0, arguments); |
|
3738 |
SetOperandAt(1, length); |
|
3739 |
SetOperandAt(2, index); |
|
3740 |
} |
|
3805 |
DECLARE_INSTRUCTION_FACTORY_P3(HAccessArgumentsAt, HValue*, HValue*, HValue*); |
|
3741 | 3806 |
|
3742 | 3807 |
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
3743 | 3808 |
|
... | ... | |
3754 | 3819 |
|
3755 | 3820 |
DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) |
3756 | 3821 |
|
3822 |
private: |
|
3823 |
HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { |
|
3824 |
set_representation(Representation::Tagged()); |
|
3825 |
SetFlag(kUseGVN); |
|
3826 |
SetOperandAt(0, arguments); |
|
3827 |
SetOperandAt(1, length); |
|
3828 |
SetOperandAt(2, index); |
|
3829 |
} |
|
3830 |
|
|
3757 | 3831 |
virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
3758 | 3832 |
}; |
3759 | 3833 |
|
... | ... | |
3882 | 3956 |
} |
3883 | 3957 |
|
3884 | 3958 |
virtual void RepresentationChanged(Representation to) V8_OVERRIDE { |
3885 |
if (!to.IsTagged()) { |
|
3886 |
ASSERT(to.IsSmiOrInteger32()); |
|
3887 |
ClearAllSideEffects(); |
|
3888 |
SetFlag(kUseGVN); |
|
3889 |
} else { |
|
3959 |
if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); |
|
3960 |
if (to.IsTagged() && |
|
3961 |
(left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { |
|
3890 | 3962 |
SetAllSideEffects(); |
3891 | 3963 |
ClearFlag(kUseGVN); |
3964 |
} else { |
|
3965 |
ClearAllSideEffects(); |
|
3966 |
SetFlag(kUseGVN); |
|
3892 | 3967 |
} |
3893 | 3968 |
} |
3894 | 3969 |
|
... | ... | |
3920 | 3995 |
|
3921 | 3996 |
class HMathFloorOfDiv V8_FINAL : public HBinaryOperation { |
3922 | 3997 |
public: |
3923 |
static HMathFloorOfDiv* New(Zone* zone, |
Also available in: Unified diff