Add support for adding an external and a tagged pointer

This will be used to compute the base pointer of the new unified
representation for both on-heap and external typed arrays. The idea is
that either the external or the tagged pointer is 0 (although in
practice, if the tagged pointer is non-0, the external pointer will
contain the offset from the start of the on-heap typed array to the data
in the on-heap typed array).

The HAdd is marked as depending on new-space promotion, as the tagged
pointer might move during GC, and so the result of the addition needs to
be recomputed.

BUG=v8:3996
R=jarin@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1244693002

Cr-Commit-Position: refs/heads/master@{#29760}
This commit is contained in:
jochen 2015-07-20 08:17:53 -07:00 committed by Commit bot
parent df2d1ef979
commit 4e263bc581
10 changed files with 69 additions and 19 deletions

View File

@ -1675,8 +1675,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
return result;
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());

View File

@ -901,8 +901,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
return result;
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterOrConstantAtStart(instr->right());

View File

@ -1432,6 +1432,17 @@ HValue* HBitwise::Canonicalize() {
}
// static
HInstruction* HAdd::New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right, Strength strength,
ExternalAddType external_add_type) {
// For everything else, you should use the other factory method without
// ExternalAddType.
DCHECK_EQ(external_add_type, AddOfExternalAndTagged);
return new (zone) HAdd(context, left, right, strength, external_add_type);
}
Representation HAdd::RepresentationFromInputs() {
Representation left_rep = left()->representation();
if (left_rep.IsExternal()) {
@ -1445,7 +1456,11 @@ Representation HAdd::RequiredInputRepresentation(int index) {
if (index == 2) {
Representation left_rep = left()->representation();
if (left_rep.IsExternal()) {
return Representation::Integer32();
if (external_add_type_ == AddOfExternalAndTagged) {
return Representation::Tagged();
} else {
return Representation::Integer32();
}
}
}
return HArithmeticBinaryOperation::RequiredInputRepresentation(index);

View File

@ -4830,11 +4830,21 @@ class HPower final : public HTemplateInstruction<2> {
};
enum ExternalAddType {
AddOfExternalAndTagged,
AddOfExternalAndInt32,
NoExternalAdd
};
class HAdd final : public HArithmeticBinaryOperation {
public:
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right,
Strength strength = Strength::WEAK);
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
HValue* left, HValue* right, Strength strength,
ExternalAddType external_add_type);
// Add is only commutative if two integer values are added and not if two
// tagged values are added (because it might be a String concatenation).
@ -4877,6 +4887,14 @@ class HAdd final : public HArithmeticBinaryOperation {
Representation RequiredInputRepresentation(int index) override;
bool IsConsistentExternalRepresentation() {
return left()->representation().IsExternal() &&
((external_add_type_ == AddOfExternalAndInt32 &&
right()->representation().IsInteger32()) ||
(external_add_type_ == AddOfExternalAndTagged &&
right()->representation().IsTagged()));
}
DECLARE_CONCRETE_INSTRUCTION(Add)
protected:
@ -4885,10 +4903,35 @@ class HAdd final : public HArithmeticBinaryOperation {
Range* InferRange(Zone* zone) override;
private:
HAdd(HValue* context, HValue* left, HValue* right, Strength strength)
: HArithmeticBinaryOperation(context, left, right, strength) {
HAdd(HValue* context, HValue* left, HValue* right, Strength strength,
ExternalAddType external_add_type = NoExternalAdd)
: HArithmeticBinaryOperation(context, left, right, strength),
external_add_type_(external_add_type) {
SetFlag(kCanOverflow);
switch (external_add_type_) {
case AddOfExternalAndTagged:
DCHECK(left->representation().IsExternal());
DCHECK(right->representation().IsTagged());
SetDependsOnFlag(kNewSpacePromotion);
break;
case NoExternalAdd:
// This is a bit of a hack: The call to this constructor is generated
// by a macro that also supports sub and mul, so it doesn't pass in
// a value for external_add_type but uses the default.
if (left->representation().IsExternal()) {
external_add_type_ = AddOfExternalAndInt32;
}
break;
case AddOfExternalAndInt32:
// See comment above.
UNREACHABLE();
break;
}
}
ExternalAddType external_add_type_;
};

View File

@ -1629,8 +1629,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::ADD, instr);
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
bool use_lea = LAddI::UseLea(instr);
LOperand* left = UseRegisterAtStart(instr->left());

View File

@ -1622,8 +1622,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
return result;
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());

View File

@ -1630,8 +1630,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
return result;
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterOrConstantAtStart(instr->right());

View File

@ -1645,8 +1645,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
return result;
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());

View File

@ -1619,8 +1619,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
}
return result;
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
bool use_lea = LAddI::UseLea(instr);
LOperand* left = UseRegisterAtStart(instr->left());

View File

@ -1639,8 +1639,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::ADD, instr);
} else if (instr->representation().IsExternal()) {
DCHECK(instr->left()->representation().IsExternal());
DCHECK(instr->right()->representation().IsInteger32());
DCHECK(instr->IsConsistentExternalRepresentation());
DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
bool use_lea = LAddI::UseLea(instr);
LOperand* left = UseRegisterAtStart(instr->left());