Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[compiler] Add relocatable pointer constants for wasm memory references.
Browse files Browse the repository at this point in the history
Add relocatable pointers for wasm memory references that need to be updated when wasm GrowMemory is used. Code generator changes to accept relocatable constants as immediates.

[email protected], [email protected], [email protected]

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

Cr-Commit-Position: refs/heads/master@{#35182}
  • Loading branch information
dtig authored and Commit bot committed Apr 1, 2016
1 parent 84492bb commit eb5fe0d
Show file tree
Hide file tree
Showing 28 changed files with 360 additions and 60 deletions.
6 changes: 5 additions & 1 deletion src/compiler/arm/code-generator-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,11 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
switch (src.type()) {
case Constant::kInt32:
__ mov(dst, Operand(src.ToInt32()));
if (src.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) {
__ mov(dst, Operand(src.ToInt32(), src.rmode()));
} else {
__ mov(dst, Operand(src.ToInt32()));
}
break;
case Constant::kInt64:
UNREACHABLE();
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/arm64/code-generator-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,11 @@ class Arm64OperandConverter final : public InstructionOperandConverter {
case Constant::kInt32:
return Operand(constant.ToInt32());
case Constant::kInt64:
return Operand(constant.ToInt64());
if (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) {
return Operand(constant.ToInt64(), constant.rmode());
} else {
return Operand(constant.ToInt64());
}
case Constant::kFloat32:
return Operand(
isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/common-node-cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ void CommonNodeCache::GetCachedNodes(ZoneVector<Node*>* nodes) {
external_constants_.GetCachedNodes(nodes);
number_constants_.GetCachedNodes(nodes);
heap_constants_.GetCachedNodes(nodes);
relocatable_int32_constants_.GetCachedNodes(nodes);
relocatable_int64_constants_.GetCachedNodes(nodes);
}

} // namespace compiler
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/common-node-cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ class CommonNodeCache final {

Node** FindHeapConstant(Handle<HeapObject> value);

Node** FindRelocatableInt32Constant(int32_t value) {
return relocatable_int32_constants_.Find(zone(), value);
}

Node** FindRelocatableInt64Constant(int64_t value) {
return relocatable_int64_constants_.Find(zone(), value);
}

// Return all nodes from the cache.
void GetCachedNodes(ZoneVector<Node*>* nodes);

Expand All @@ -65,6 +73,8 @@ class CommonNodeCache final {
IntPtrNodeCache external_constants_;
Int64NodeCache number_constants_;
IntPtrNodeCache heap_constants_;
Int32NodeCache relocatable_int32_constants_;
Int64NodeCache relocatable_int64_constants_;
Zone* const zone_;

DISALLOW_COPY_AND_ASSIGN(CommonNodeCache);
Expand Down
36 changes: 36 additions & 0 deletions src/compiler/common-operator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,25 @@ std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
return os;
}

bool operator==(RelocatablePtrConstantInfo const& lhs,
RelocatablePtrConstantInfo const& rhs) {
return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value();
}

bool operator!=(RelocatablePtrConstantInfo const& lhs,
RelocatablePtrConstantInfo const& rhs) {
return !(lhs == rhs);
}

size_t hash_value(RelocatablePtrConstantInfo const& p) {
return base::hash_combine(p.value(), p.rmode());
}

std::ostream& operator<<(std::ostream& os,
RelocatablePtrConstantInfo const& p) {
return os << p.value() << "|" << p.rmode();
}

#define CACHED_OP_LIST(V) \
V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
V(DeoptimizeIf, Operator::kFoldable, 2, 1, 1, 0, 0, 1) \
Expand Down Expand Up @@ -668,6 +687,23 @@ const Operator* CommonOperatorBuilder::HeapConstant(
value); // parameter
}

const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
int32_t value, RelocInfo::Mode rmode) {
return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
IrOpcode::kRelocatableInt32Constant, Operator::kPure, // opcode
"RelocatableInt32Constant", // name
0, 0, 0, 1, 0, 0, // counts
RelocatablePtrConstantInfo(value, rmode)); // parameter
}

const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
int64_t value, RelocInfo::Mode rmode) {
return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode
"RelocatableInt64Constant", // name
0, 0, 0, 1, 0, 0, // counts
RelocatablePtrConstantInfo(value, rmode)); // parameter
}

const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
BranchHint hint) {
Expand Down
26 changes: 25 additions & 1 deletion src/compiler/common-operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef V8_COMPILER_COMMON_OPERATOR_H_
#define V8_COMPILER_COMMON_OPERATOR_H_

#include "src/assembler.h"
#include "src/compiler/frame-states.h"
#include "src/machine-type.h"
#include "src/zone-containers.h"
Expand All @@ -13,7 +14,6 @@ namespace v8 {
namespace internal {

// Forward declarations.
class ExternalReference;
class Type;

namespace compiler {
Expand Down Expand Up @@ -114,6 +114,25 @@ std::ostream& operator<<(std::ostream&, ParameterInfo const&);
int ParameterIndexOf(const Operator* const);
const ParameterInfo& ParameterInfoOf(const Operator* const);

class RelocatablePtrConstantInfo final {
public:
RelocatablePtrConstantInfo(intptr_t value, RelocInfo::Mode rmode)
: value_(value), rmode_(rmode) {}

intptr_t value() const { return value_; }
RelocInfo::Mode rmode() const { return rmode_; }

private:
intptr_t value_;
RelocInfo::Mode rmode_;
};

bool operator==(RelocatablePtrConstantInfo const& lhs,
RelocatablePtrConstantInfo const& rhs);
bool operator!=(RelocatablePtrConstantInfo const& lhs,
RelocatablePtrConstantInfo const& rhs);
std::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&);
size_t hash_value(RelocatablePtrConstantInfo const& p);

// Interface for building common operators that can be used at any level of IR,
// including JavaScript, mid-level, and low-level.
Expand Down Expand Up @@ -155,6 +174,11 @@ class CommonOperatorBuilder final : public ZoneObject {
const Operator* NumberConstant(volatile double);
const Operator* HeapConstant(const Handle<HeapObject>&);

const Operator* RelocatableInt32Constant(int32_t value,
RelocInfo::Mode rmode);
const Operator* RelocatableInt64Constant(int64_t value,
RelocInfo::Mode rmode);

const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
const Operator* Phi(MachineRepresentation representation,
int value_input_count);
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/ia32/code-generator-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class IA32OperandConverter : public InstructionOperandConverter {

Immediate ToImmediate(InstructionOperand* operand) {
Constant constant = ToConstant(operand);
if (constant.type() == Constant::kInt32 &&
constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) {
return Immediate(reinterpret_cast<Address>(constant.ToInt32()),
constant.rmode());
}
switch (constant.type()) {
case Constant::kInt32:
return Immediate(constant.ToInt32());
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/ia32/instruction-selector-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class IA32OperandGenerator final : public OperandGenerator {
case IrOpcode::kInt32Constant:
case IrOpcode::kNumberConstant:
case IrOpcode::kExternalConstant:
case IrOpcode::kRelocatableInt32Constant:
case IrOpcode::kRelocatableInt64Constant:
return true;
case IrOpcode::kHeapConstant: {
// Constants in new space cannot be used as immediates in V8 because
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/instruction-selector-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ class OperandGenerator {
return Constant(OpParameter<int64_t>(node));
case IrOpcode::kFloat32Constant:
return Constant(OpParameter<float>(node));
case IrOpcode::kRelocatableInt32Constant:
case IrOpcode::kRelocatableInt64Constant:
return Constant(OpParameter<RelocatablePtrConstantInfo>(node));
case IrOpcode::kFloat64Constant:
case IrOpcode::kNumberConstant:
return Constant(OpParameter<double>(node));
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/instruction-selector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,8 @@ void InstructionSelector::VisitNode(Node* node) {
case IrOpcode::kInt32Constant:
case IrOpcode::kInt64Constant:
case IrOpcode::kExternalConstant:
case IrOpcode::kRelocatableInt32Constant:
case IrOpcode::kRelocatableInt64Constant:
return VisitConstant(node);
case IrOpcode::kFloat32Constant:
return MarkAsFloat32(node), VisitConstant(node);
Expand Down
8 changes: 8 additions & 0 deletions src/compiler/instruction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,14 @@ std::ostream& operator<<(std::ostream& os,

Constant::Constant(int32_t v) : type_(kInt32), value_(v) {}

Constant::Constant(RelocatablePtrConstantInfo info)
#ifdef V8_HOST_ARCH_32_BIT
: type_(kInt32), value_(info.value()), rmode_(info.rmode()) {
}
#else
: type_(kInt64), value_(info.value()), rmode_(info.rmode()) {
}
#endif

std::ostream& operator<<(std::ostream& os, const Constant& constant) {
switch (constant.type()) {
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -947,9 +947,12 @@ class Constant final {
explicit Constant(Handle<HeapObject> obj)
: type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
explicit Constant(RpoNumber rpo) : type_(kRpoNumber), value_(rpo.ToInt()) {}
explicit Constant(RelocatablePtrConstantInfo info);

Type type() const { return type_; }

RelocInfo::Mode rmode() const { return rmode_; }

int32_t ToInt32() const {
DCHECK(type() == kInt32 || type() == kInt64);
const int32_t value = static_cast<int32_t>(value_);
Expand Down Expand Up @@ -992,6 +995,7 @@ class Constant final {
private:
Type type_;
int64_t value_;
RelocInfo::Mode rmode_;
};


Expand Down
22 changes: 22 additions & 0 deletions src/compiler/js-graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,28 @@ Node* JSGraph::Int64Constant(int64_t value) {
return *loc;
}

Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
Node** loc = cache_.FindRelocatableInt32Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
}
return *loc;
}

Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
Node** loc = cache_.FindRelocatableInt64Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
}
return *loc;
}

Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
RelocInfo::Mode rmode) {
return kPointerSize == 8
? RelocatableInt64Constant(value, rmode)
: RelocatableInt32Constant(static_cast<int>(value), rmode);
}

Node* JSGraph::NumberConstant(double value) {
Node** loc = cache_.FindNumberConstant(value);
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/js-graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ class JSGraph : public ZoneObject {
return IntPtrConstant(bit_cast<intptr_t>(value));
}

Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode);
Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode);
Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);

// Creates a Float32Constant node, usually canonicalized.
Node* Float32Constant(float value);

Expand Down
20 changes: 11 additions & 9 deletions src/compiler/opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@
V(End)

// Opcodes for constant operators.
#define CONSTANT_OP_LIST(V) \
V(Int32Constant) \
V(Int64Constant) \
V(Float32Constant) \
V(Float64Constant) \
V(ExternalConstant) \
V(NumberConstant) \
V(HeapConstant)
#define CONSTANT_OP_LIST(V) \
V(Int32Constant) \
V(Int64Constant) \
V(Float32Constant) \
V(Float64Constant) \
V(ExternalConstant) \
V(NumberConstant) \
V(HeapConstant) \
V(RelocatableInt32Constant) \
V(RelocatableInt64Constant)

#define INNER_OP_LIST(V) \
V(Select) \
Expand Down Expand Up @@ -396,7 +398,7 @@ class IrOpcode {

// Returns true if opcode for constant operator.
static bool IsConstantOpcode(Value value) {
return kInt32Constant <= value && value <= kHeapConstant;
return kInt32Constant <= value && value <= kRelocatableInt64Constant;
}

static bool IsPhiOpcode(Value value) {
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/raw-machine-assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ RawMachineAssembler::RawMachineAssembler(Isolate* isolate, Graph* graph,
graph->SetEnd(graph->NewNode(common_.End(0)));
}

Node* RawMachineAssembler::RelocatableIntPtrConstant(intptr_t value,
RelocInfo::Mode rmode) {
return kPointerSize == 8
? RelocatableInt64Constant(value, rmode)
: RelocatableInt32Constant(static_cast<int>(value), rmode);
}

Schedule* RawMachineAssembler::Export() {
// Compute the correct codegen order.
Expand Down
7 changes: 7 additions & 0 deletions src/compiler/raw-machine-assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class RawMachineAssembler {
return kPointerSize == 8 ? Int64Constant(value)
: Int32Constant(static_cast<int>(value));
}
Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
Node* Int32Constant(int32_t value) {
return AddNode(common()->Int32Constant(value));
}
Expand Down Expand Up @@ -104,6 +105,12 @@ class RawMachineAssembler {
Node* ExternalConstant(ExternalReference address) {
return AddNode(common()->ExternalConstant(address));
}
Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
return AddNode(common()->RelocatableInt32Constant(value, rmode));
}
Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
return AddNode(common()->RelocatableInt64Constant(value, rmode));
}

Node* Projection(int index, Node* a) {
return AddNode(common()->Projection(index), a);
Expand Down
8 changes: 8 additions & 0 deletions src/compiler/typer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,14 @@ Type* Typer::Visitor::TypeInt64Constant(Node* node) {
return Type::Internal(); // TODO(rossberg): Add int64 bitset type?
}

// TODO(gdeepti) : Fix this to do something meaningful.
Type* Typer::Visitor::TypeRelocatableInt32Constant(Node* node) {
return Type::Internal();
}

Type* Typer::Visitor::TypeRelocatableInt64Constant(Node* node) {
return Type::Internal();
}

Type* Typer::Visitor::TypeFloat32Constant(Node* node) {
return Type::Intersect(Type::Of(OpParameter<float>(node), zone()),
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/verifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ void Verifier::Visitor::Check(Node* node) {
// Type is a number.
CheckUpperIs(node, Type::Number());
break;
case IrOpcode::kRelocatableInt32Constant:
case IrOpcode::kRelocatableInt64Constant:
CHECK_EQ(0, input_count);
break;
case IrOpcode::kHeapConstant:
// Constants have no inputs.
CHECK_EQ(0, input_count);
Expand Down
10 changes: 6 additions & 4 deletions src/compiler/wasm-compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2314,13 +2314,15 @@ Node* WasmGraphBuilder::MemBuffer(uint32_t offset) {
DCHECK(module_ && module_->instance);
if (offset == 0) {
if (!mem_buffer_) {
mem_buffer_ = jsgraph()->IntPtrConstant(
reinterpret_cast<uintptr_t>(module_->instance->mem_start));
mem_buffer_ = jsgraph()->RelocatableIntPtrConstant(
reinterpret_cast<uintptr_t>(module_->instance->mem_start),
RelocInfo::WASM_MEMORY_REFERENCE);
}
return mem_buffer_;
} else {
return jsgraph()->IntPtrConstant(
reinterpret_cast<uintptr_t>(module_->instance->mem_start + offset));
return jsgraph()->RelocatableIntPtrConstant(
reinterpret_cast<uintptr_t>(module_->instance->mem_start + offset),
RelocInfo::WASM_MEMORY_REFERENCE);
}
}

Expand Down
Loading

0 comments on commit eb5fe0d

Please sign in to comment.