Revision: 15936
Author: [email protected]
Date: Mon Jul 29 06:56:51 2013
Log: This adds generic support for ExternalReferences in Hydrogen (and
Lithium), as required for AddIncrementCounter.
[email protected], [email protected]
Review URL: https://codereview.chromium.org/19562003
http://code.google.com/p/v8/source/detail?r=15936
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/assembler.h
/branches/bleeding_edge/src/hydrogen-instructions.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/mips/lithium-mips.cc
/branches/bleeding_edge/src/mips/lithium-mips.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.h
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Mon Jul 29 02:12:16 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Mon Jul 29 06:56:51 2013
@@ -2095,6 +2095,8 @@
return DefineAsRegister(new(zone()) LConstantI);
} else if (r.IsDouble()) {
return DefineAsRegister(new(zone()) LConstantD);
+ } else if (r.IsExternal()) {
+ return DefineAsRegister(new(zone()) LConstantE);
} else if (r.IsTagged()) {
return DefineAsRegister(new(zone()) LConstantT);
} else {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Mon Jul 29 06:56:51 2013
@@ -79,6 +79,7 @@
V(CmpMapAndBranch) \
V(CmpT) \
V(ConstantD) \
+ V(ConstantE) \
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
@@ -1232,6 +1233,17 @@
};
+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+ DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+ ExternalReference value() const {
+ return hydrogen()->ExternalReferenceValue();
+ }
+};
+
+
class LConstantT: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Jul 29
02:12:16 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Jul 29
06:56:51 2013
@@ -1820,6 +1820,11 @@
double v = instr->value();
__ Vmov(result, v, scratch0());
}
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+ __ mov(ToRegister(instr->result()), Operand(instr->value()));
+}
void LCodeGen::DoConstantT(LConstantT* instr) {
@@ -3002,6 +3007,13 @@
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
Register object = ToRegister(instr->object());
+
+ if (access.IsExternalMemory()) {
+ Register result = ToRegister(instr->result());
+ __ ldr(result, MemOperand(object, offset));
+ return;
+ }
+
if (instr->hydrogen()->representation().IsDouble()) {
DwVfpRegister result = ToDoubleRegister(instr->result());
__ vldr(result, FieldMemOperand(object, offset));
@@ -4181,10 +4193,15 @@
Register object = ToRegister(instr->object());
Register scratch = scratch0();
-
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
+ if (access.IsExternalMemory()) {
+ Register value = ToRegister(instr->value());
+ __ str(value, MemOperand(object, offset));
+ return;
+ }
+
Handle<Map> transition = instr->transition();
if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
=======================================
--- /branches/bleeding_edge/src/assembler.h Thu Jul 18 01:12:01 2013
+++ /branches/bleeding_edge/src/assembler.h Mon Jul 29 06:56:51 2013
@@ -683,6 +683,8 @@
static void TearDownMathExpData();
typedef void* ExternalReferenceRedirector(void* original, Type type);
+
+ ExternalReference() : address_(NULL) {}
ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
@@ -829,7 +831,7 @@
static ExternalReference cpu_features();
- Address address() const {return reinterpret_cast<Address>(address_);}
+ Address address() const { return reinterpret_cast<Address>(address_); }
#ifdef ENABLE_DEBUGGER_SUPPORT
// Function Debug::Break()
@@ -868,6 +870,14 @@
static ExternalReference stress_deopt_count(Isolate* isolate);
+ bool operator==(const ExternalReference& other) const {
+ return address_ == other.address_;
+ }
+
+ bool operator!=(const ExternalReference& other) const {
+ return !(*this == other);
+ }
+
private:
explicit ExternalReference(void* address)
: address_(address) {}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Jul 29
05:35:43 2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Jul 29
06:56:51 2013
@@ -448,6 +448,7 @@
// Note: The c1visualizer syntax for locals allows only a sequence of the
// following characters: A-Za-z0-9_-|:
switch (type_) {
+ case kNone: return "none";
case kTagged: return "tagged";
case kTaggedPrimitive: return "primitive";
case kTaggedNumber: return "number";
@@ -2644,6 +2645,7 @@
has_smi_value_(false),
has_int32_value_(false),
has_double_value_(false),
+ has_external_reference_value_(false),
is_internalized_string_(false),
is_not_in_new_space_(true),
is_cell_(false),
@@ -2679,15 +2681,16 @@
bool is_not_in_new_space,
bool is_cell,
bool boolean_value)
- : handle_(handle),
- unique_id_(unique_id),
- has_smi_value_(false),
- has_int32_value_(false),
- has_double_value_(false),
- is_internalized_string_(is_internalize_string),
- is_not_in_new_space_(is_not_in_new_space),
- is_cell_(is_cell),
- boolean_value_(boolean_value) {
+ : handle_(handle),
+ unique_id_(unique_id),
+ has_smi_value_(false),
+ has_int32_value_(false),
+ has_double_value_(false),
+ has_external_reference_value_(false),
+ is_internalized_string_(is_internalize_string),
+ is_not_in_new_space_(is_not_in_new_space),
+ is_cell_(is_cell),
+ boolean_value_(boolean_value) {
ASSERT(!handle.is_null());
ASSERT(!type.IsTaggedNumber());
set_type(type);
@@ -2699,17 +2702,18 @@
Representation r,
bool is_not_in_new_space,
Handle<Object> optional_handle)
- : handle_(optional_handle),
- unique_id_(),
- has_smi_value_(Smi::IsValid(integer_value)),
- has_int32_value_(true),
- has_double_value_(true),
- is_internalized_string_(false),
- is_not_in_new_space_(is_not_in_new_space),
- is_cell_(false),
- boolean_value_(integer_value != 0),
- int32_value_(integer_value),
- double_value_(FastI2D(integer_value)) {
+ : handle_(optional_handle),
+ unique_id_(),
+ has_smi_value_(Smi::IsValid(integer_value)),
+ has_int32_value_(true),
+ has_double_value_(true),
+ has_external_reference_value_(false),
+ is_internalized_string_(false),
+ is_not_in_new_space_(is_not_in_new_space),
+ is_cell_(false),
+ boolean_value_(integer_value != 0),
+ int32_value_(integer_value),
+ double_value_(FastI2D(integer_value)) {
set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber());
Initialize(r);
}
@@ -2719,20 +2723,36 @@
Representation r,
bool is_not_in_new_space,
Handle<Object> optional_handle)
- : handle_(optional_handle),
- unique_id_(),
- has_int32_value_(IsInteger32(double_value)),
- has_double_value_(true),
- is_internalized_string_(false),
- is_not_in_new_space_(is_not_in_new_space),
- is_cell_(false),
- boolean_value_(double_value != 0 && !std::isnan(double_value)),
- int32_value_(DoubleToInt32(double_value)),
- double_value_(double_value) {
+ : handle_(optional_handle),
+ unique_id_(),
+ has_int32_value_(IsInteger32(double_value)),
+ has_double_value_(true),
+ has_external_reference_value_(false),
+ is_internalized_string_(false),
+ is_not_in_new_space_(is_not_in_new_space),
+ is_cell_(false),
+ boolean_value_(double_value != 0 && !std::isnan(double_value)),
+ int32_value_(DoubleToInt32(double_value)),
+ double_value_(double_value) {
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber());
Initialize(r);
}
+
+
+HConstant::HConstant(ExternalReference reference)
+ : has_smi_value_(false),
+ has_int32_value_(false),
+ has_double_value_(false),
+ has_external_reference_value_(true),
+ is_internalized_string_(false),
+ is_not_in_new_space_(true),
+ is_cell_(false),
+ boolean_value_(true),
+ external_reference_value_(reference) {
+ set_type(HType::None());
+ Initialize(Representation::External());
+}
void HConstant::Initialize(Representation r) {
@@ -2743,6 +2763,8 @@
r = Representation::Integer32();
} else if (has_double_value_) {
r = Representation::Double();
+ } else if (has_external_reference_value_) {
+ r = Representation::External();
} else {
r = Representation::Tagged();
}
@@ -2767,12 +2789,16 @@
if (r.IsSmi() && !has_smi_value_) return NULL;
if (r.IsInteger32() && !has_int32_value_) return NULL;
if (r.IsDouble() && !has_double_value_) return NULL;
+ if (r.IsExternal() && !has_external_reference_value_) return NULL;
if (has_int32_value_) {
return new(zone) HConstant(int32_value_, r, is_not_in_new_space_,
handle_);
}
if (has_double_value_) {
return new(zone) HConstant(double_value_, r, is_not_in_new_space_,
handle_);
}
+ if (has_external_reference_value_) {
+ return new(zone) HConstant(external_reference_value_);
+ }
ASSERT(!handle_.is_null());
return new(zone) HConstant(handle_,
unique_id_,
@@ -2825,6 +2851,9 @@
stream->Add("%d ", int32_value_);
} else if (has_double_value_) {
stream->Add("%f ", FmtElm(double_value_));
+ } else if (has_external_reference_value_) {
+ stream->Add("%p ", reinterpret_cast<void*>(
+ external_reference_value_.address()));
} else {
handle()->ShortPrint(stream);
}
@@ -4505,6 +4534,10 @@
instr->SetGVNFlag(is_store
? kChangesMaps : kDependsOnMaps);
break;
+ case kExternalMemory:
+ instr->SetGVNFlag(is_store
+ ? kChangesExternalMemory : kDependsOnExternalMemory);
+ break;
}
}
@@ -4531,6 +4564,9 @@
if (!name_.is_null())
stream->Add(*String::cast(*name_)->ToCString());
stream->Add("[backing-store]");
break;
+ case kExternalMemory:
+ stream->Add("[external-memory]");
+ break;
}
stream->Add("@%d", offset());
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jul 29 05:35:43
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jul 29 06:56:51
2013
@@ -211,7 +211,7 @@
V(GlobalVars) \
V(InobjectFields) \
V(OsrEntries) \
- V(SpecializedArrayElements)
+ V(ExternalMemory)
#define DECLARE_ABSTRACT_INSTRUCTION(type) \
@@ -350,6 +350,7 @@
class HType {
public:
+ static HType None() { return HType(kNone); }
static HType Tagged() { return HType(kTagged); }
static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
static HType TaggedNumber() { return HType(kTaggedNumber); }
@@ -447,6 +448,7 @@
private:
enum Type {
+ kNone = 0x0, // 0000 0000 0000 0000
kTagged = 0x1, // 0000 0000 0000 0001
kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
kTaggedNumber = 0xd, // 0000 0000 0000 1101
@@ -2692,6 +2694,10 @@
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
+
+ virtual HType CalculateInferredType() {
+ return HType::None();
+ }
DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
@@ -3478,6 +3484,7 @@
bool is_not_in_new_space,
bool is_cell,
bool boolean_value);
+ explicit HConstant(ExternalReference reference);
Handle<Object> handle() {
if (handle_.is_null()) {
@@ -3542,6 +3549,7 @@
if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
if (HasInteger32Value()) return Representation::Integer32();
if (HasNumberValue()) return Representation::Double();
+ if (HasExternalReferenceValue()) return Representation::External();
return Representation::Tagged();
}
@@ -3592,6 +3600,13 @@
bool HasInternalizedStringValue() const {
return HasStringValue() && is_internalized_string_;
}
+
+ bool HasExternalReferenceValue() const {
+ return has_external_reference_value_;
+ }
+ ExternalReference ExternalReferenceValue() const {
+ return external_reference_value_;
+ }
bool BooleanValue() const { return boolean_value_; }
@@ -3600,6 +3615,8 @@
return static_cast<intptr_t>(int32_value_);
} else if (has_double_value_) {
return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
+ } else if (has_external_reference_value_) {
+ return
reinterpret_cast<intptr_t>(external_reference_value_.address());
} else {
ASSERT(!handle_.is_null());
return unique_id_.Hashcode();
@@ -3607,14 +3624,15 @@
}
virtual void FinalizeUniqueValueId() {
- if (!has_double_value_) {
+ if (!has_double_value_ && !has_external_reference_value_) {
ASSERT(!handle_.is_null());
unique_id_ = UniqueValueId(handle_);
}
}
bool UniqueValueIdsMatch(UniqueValueId other) {
- return !has_double_value_ && unique_id_ == other;
+ return !has_double_value_ && !has_external_reference_value_ &&
+ unique_id_ == other;
}
#ifdef DEBUG
@@ -3635,6 +3653,10 @@
return other_constant->has_double_value_ &&
BitCast<int64_t>(double_value_) ==
BitCast<int64_t>(other_constant->double_value_);
+ } else if (has_external_reference_value_) {
+ return other_constant->has_external_reference_value_ &&
+ external_reference_value_ ==
+ other_constant->external_reference_value_;
} else {
ASSERT(!handle_.is_null());
return !other_constant->handle_.is_null() &&
@@ -3662,12 +3684,14 @@
bool has_smi_value_ : 1;
bool has_int32_value_ : 1;
bool has_double_value_ : 1;
+ bool has_external_reference_value_ : 1;
bool is_internalized_string_ : 1; // TODO(yangguo): make this part of
HType.
bool is_not_in_new_space_ : 1;
bool is_cell_ : 1;
bool boolean_value_ : 1;
int32_t int32_value_;
double double_value_;
+ ExternalReference external_reference_value_;
};
@@ -5564,7 +5588,11 @@
class HObjectAccess {
public:
inline bool IsInobject() const {
- return portion() != kBackingStore;
+ return portion() != kBackingStore && portion() != kExternalMemory;
+ }
+
+ inline bool IsExternalMemory() const {
+ return portion() == kExternalMemory;
}
inline int offset() const {
@@ -5639,6 +5667,10 @@
static HObjectAccess ForAllocationMementoSite() {
return HObjectAccess(kInobject,
AllocationMemento::kAllocationSiteOffset);
}
+
+ static HObjectAccess ForCounter() {
+ return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
+ }
// Create an access to an offset in a fixed array header.
static HObjectAccess ForFixedArrayHeader(int offset);
@@ -5678,7 +5710,8 @@
kElementsPointer, // elements pointer
kBackingStore, // some field in the backing store
kDouble, // some double field
- kInobject // some other in-object field
+ kInobject, // some other in-object field
+ kExternalMemory // some field in external memory
};
HObjectAccess(Portion portion, int offset,
@@ -5756,7 +5789,9 @@
if (representation.IsSmi()) {
set_type(HType::Smi());
set_representation(representation);
- } else if (representation.IsDouble()) {
+ } else if (representation.IsDouble() ||
+ representation.IsExternal() ||
+ representation.IsInteger32()) {
set_representation(representation);
} else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
@@ -5782,6 +5817,10 @@
virtual bool HasEscapingOperandAt(int index) { return false; }
virtual Representation RequiredInputRepresentation(int index) {
+ if (index == 0 && access().IsExternalMemory()) {
+ // object must be external in case of external memory access
+ return Representation::External();
+ }
return Representation::Tagged();
}
virtual void PrintDataTo(StringStream* stream);
@@ -5955,7 +5994,7 @@
set_representation(Representation::Integer32());
}
- SetGVNFlag(kDependsOnSpecializedArrayElements);
+ SetGVNFlag(kDependsOnExternalMemory);
// Native code could change the specialized array.
SetGVNFlag(kDependsOnCalls);
}
@@ -6112,9 +6151,13 @@
virtual bool HasEscapingOperandAt(int index) { return index == 1; }
virtual Representation RequiredInputRepresentation(int index) {
- if (index == 1 && field_representation().IsDouble()) {
- return field_representation();
- } else if (index == 1 && field_representation().IsSmi()) {
+ if (index == 0 && access().IsExternalMemory()) {
+ // object must be external in case of external memory access
+ return Representation::External();
+ } else if (index == 1 &&
+ (field_representation().IsDouble() ||
+ field_representation().IsSmi() ||
+ field_representation().IsInteger32())) {
return field_representation();
}
return Representation::Tagged();
@@ -6152,6 +6195,7 @@
if (IsSkipWriteBarrier()) return false;
if (field_representation().IsDouble()) return false;
if (field_representation().IsSmi()) return false;
+ if (field_representation().IsInteger32()) return false;
return StoringValueNeedsWriteBarrier(value()) &&
ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
}
@@ -6232,7 +6276,7 @@
SetGVNFlag(kDependsOnNewSpacePromotion);
}
if (is_external()) {
- SetGVNFlag(kChangesSpecializedArrayElements);
+ SetGVNFlag(kChangesExternalMemory);
SetFlag(kAllowUndefinedAsNaN);
} else if (IsFastDoubleElementsKind(elements_kind)) {
SetGVNFlag(kChangesDoubleArrayElements);
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Jul 29 04:50:39 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Mon Jul 29 06:56:51 2013
@@ -984,6 +984,19 @@
}
return instr;
}
+
+
+void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
+ HValue* context) {
+ if (FLAG_native_code_counters && counter->Enabled()) {
+ HValue* reference = Add<HConstant>(ExternalReference(counter));
+ HValue* old_value = AddLoad(reference, HObjectAccess::ForCounter(),
NULL);
+ HValue* new_value = AddInstruction(
+ HAdd::New(zone(), context, old_value, graph()->GetConstant1()));
+ new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
+ AddStore(reference, HObjectAccess::ForCounter(), new_value);
+ }
+}
HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Thu Jul 25 07:11:53 2013
+++ /branches/bleeding_edge/src/hydrogen.h Mon Jul 29 06:56:51 2013
@@ -1133,6 +1133,9 @@
void FinishExitWithHardDeoptimization(HBasicBlock* continuation);
+ void AddIncrementCounter(StatsCounter* counter,
+ HValue* context);
+
class IfBuilder {
public:
explicit IfBuilder(HGraphBuilder* builder,
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Jul 29
02:12:16 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Jul 29
06:56:51 2013
@@ -683,6 +683,13 @@
ASSERT(constant->HasDoubleValue());
return constant->DoubleValue();
}
+
+
+ExternalReference LCodeGen::ToExternalReference(LConstantOperand* op)
const {
+ HConstant* constant = chunk_->LookupConstant(op);
+ ASSERT(constant->HasExternalReferenceValue());
+ return constant->ExternalReferenceValue();
+}
bool LCodeGen::IsInteger32(LConstantOperand* op) const {
@@ -1851,6 +1858,11 @@
}
}
}
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+ __ lea(ToRegister(instr->result()),
Operand::StaticVariable(instr->value()));
+}
void LCodeGen::DoConstantT(LConstantT* instr) {
@@ -3049,6 +3061,19 @@
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
+
+ if (access.IsExternalMemory()) {
+ Register result = ToRegister(instr->result());
+ if (instr->object()->IsConstantOperand()) {
+ ExternalReference external_reference = ToExternalReference(
+ LConstantOperand::cast(instr->object()));
+ __ mov(result, MemOperand::StaticVariable(external_reference));
+ } else {
+ __ mov(result, MemOperand(ToRegister(instr->object()), offset));
+ }
+ return;
+ }
+
Register object = ToRegister(instr->object());
if (FLAG_track_double_fields &&
instr->hydrogen()->representation().IsDouble()) {
@@ -4328,10 +4353,25 @@
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
Representation representation = instr->representation();
- Register object = ToRegister(instr->object());
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
+ if (access.IsExternalMemory()) {
+ MemOperand operand = instr->object()->IsConstantOperand()
+ ? MemOperand::StaticVariable(
+ ToExternalReference(LConstantOperand::cast(instr->object())))
+ : MemOperand(ToRegister(instr->object()), offset);
+ if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
+ __ mov(operand, Immediate(ToInteger32(operand_value)));
+ } else {
+ Register value = ToRegister(instr->value());
+ __ mov(operand, value);
+ }
+ return;
+ }
+
+ Register object = ToRegister(instr->object());
Handle<Map> transition = instr->transition();
if (FLAG_track_fields && representation.IsSmi()) {
@@ -4396,8 +4436,7 @@
Register write_register = object;
if (!access.IsInobject()) {
write_register = ToRegister(instr->temp());
- __ mov(write_register,
- FieldOperand(object, JSObject::kPropertiesOffset));
+ __ mov(write_register, FieldOperand(object,
JSObject::kPropertiesOffset));
}
if (instr->value()->IsConstantOperand()) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Thu Jul 25
04:53:38 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Jul 29
06:56:51 2013
@@ -297,6 +297,7 @@
X87Register ToX87Register(int index) const;
int ToRepresentation(LConstantOperand* op, const Representation& r)
const;
int32_t ToInteger32(LConstantOperand* op) const;
+ ExternalReference ToExternalReference(LConstantOperand* op) const;
Operand BuildFastArrayOperand(LOperand* elements_pointer,
LOperand* key,
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Jul 29 02:12:16
2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Jul 29 06:56:51
2013
@@ -2146,6 +2146,8 @@
bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
LOperand* temp = value_is_zero ? NULL : TempRegister();
return DefineAsRegister(new(zone()) LConstantD(temp));
+ } else if (r.IsExternal()) {
+ return DefineAsRegister(new(zone()) LConstantE);
} else if (r.IsTagged()) {
return DefineAsRegister(new(zone()) LConstantT);
} else {
@@ -2222,7 +2224,10 @@
LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
- LOperand* obj = UseRegisterAtStart(instr->object());
+ LOperand* obj = (instr->access().IsExternalMemory() &&
+ instr->access().offset() == 0)
+ ? UseRegisterOrConstantAtStart(instr->object())
+ : UseRegisterAtStart(instr->object());
return DefineAsRegister(new(zone()) LLoadNamedField(obj));
}
@@ -2436,6 +2441,8 @@
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
bool is_in_object = instr->access().IsInobject();
+ bool is_external_location = instr->access().IsExternalMemory() &&
+ instr->access().offset() == 0;
bool needs_write_barrier = instr->NeedsWriteBarrier();
bool needs_write_barrier_for_map = !instr->transition().is_null() &&
instr->NeedsWriteBarrierForMap();
@@ -2445,6 +2452,11 @@
obj = is_in_object
? UseRegister(instr->object())
: UseTempRegister(instr->object());
+ } else if (is_external_location) {
+ ASSERT(!is_in_object);
+ ASSERT(!needs_write_barrier);
+ ASSERT(!needs_write_barrier_for_map);
+ obj = UseRegisterOrConstant(instr->object());
} else {
obj = needs_write_barrier_for_map
? UseRegister(instr->object())
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Mon Jul 29 06:56:51 2013
@@ -80,6 +80,7 @@
V(CmpMapAndBranch) \
V(CmpT) \
V(ConstantD) \
+ V(ConstantE) \
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
@@ -1208,6 +1209,17 @@
};
+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+ DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+ ExternalReference value() const {
+ return hydrogen()->ExternalReferenceValue();
+ }
+};
+
+
class LConstantT: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon Jul 29
02:12:16 2013
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon Jul 29
06:56:51 2013
@@ -1656,6 +1656,11 @@
double v = instr->value();
__ Move(result, v);
}
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+ __ li(ToRegister(instr->result()), Operand(instr->value()));
+}
void LCodeGen::DoConstantT(LConstantT* instr) {
@@ -2878,6 +2883,13 @@
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
Register object = ToRegister(instr->object());
+
+ if (access.IsExternalMemory()) {
+ Register result = ToRegister(instr->result());
+ __ lw(result, MemOperand(object, offset));
+ return;
+ }
+
if (instr->hydrogen()->representation().IsDouble()) {
DoubleRegister result = ToDoubleRegister(instr->result());
__ ldc1(result, FieldMemOperand(object, offset));
@@ -4115,6 +4127,12 @@
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
+ if (access.IsExternalMemory()) {
+ Register value = ToRegister(instr->value());
+ __ sw(value, MemOperand(object, offset));
+ return;
+ }
+
Handle<Map> transition = instr->transition();
if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Mon Jul 29 02:12:16
2013
+++ /branches/bleeding_edge/src/mips/lithium-mips.cc Mon Jul 29 06:56:51
2013
@@ -2017,6 +2017,8 @@
return DefineAsRegister(new(zone()) LConstantI);
} else if (r.IsDouble()) {
return DefineAsRegister(new(zone()) LConstantD);
+ } else if (r.IsExternal()) {
+ return DefineAsRegister(new(zone()) LConstantE);
} else if (r.IsTagged()) {
return DefineAsRegister(new(zone()) LConstantT);
} else {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/mips/lithium-mips.h Mon Jul 29 06:56:51 2013
@@ -79,6 +79,7 @@
V(CmpMapAndBranch) \
V(CmpT) \
V(ConstantD) \
+ V(ConstantE) \
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
@@ -1210,6 +1211,17 @@
};
+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+ DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+ ExternalReference value() const {
+ return hydrogen()->ExternalReferenceValue();
+ }
+};
+
+
class LConstantT: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Jul 29
02:12:16 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Jul 29
06:56:51 2013
@@ -427,6 +427,13 @@
ASSERT(constant->HasDoubleValue());
return constant->DoubleValue();
}
+
+
+ExternalReference LCodeGen::ToExternalReference(LConstantOperand* op)
const {
+ HConstant* constant = chunk_->LookupConstant(op);
+ ASSERT(constant->HasExternalReferenceValue());
+ return constant->ExternalReferenceValue();
+}
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
@@ -1522,6 +1529,11 @@
}
}
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+ __ LoadAddress(ToRegister(instr->result()), instr->value());
+}
+
void LCodeGen::DoConstantT(LConstantT* instr) {
Handle<Object> value = instr->value();
@@ -2689,6 +2701,19 @@
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
+
+ if (access.IsExternalMemory()) {
+ Register result = ToRegister(instr->result());
+ if (instr->object()->IsConstantOperand()) {
+ ASSERT(result.is(rax));
+ __
load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
+ } else {
+ Register object = ToRegister(instr->object());
+ __ movq(result, MemOperand(object, offset));
+ }
+ return;
+ }
+
Register object = ToRegister(instr->object());
if (FLAG_track_double_fields &&
instr->hydrogen()->representation().IsDouble()) {
@@ -3926,11 +3951,23 @@
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
Representation representation = instr->representation();
- Register object = ToRegister(instr->object());
-
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
+ if (access.IsExternalMemory()) {
+ Register value = ToRegister(instr->value());
+ if (instr->object()->IsConstantOperand()) {
+ ASSERT(value.is(rax));
+ LConstantOperand* object = LConstantOperand::cast(instr->object());
+ __ store_rax(ToExternalReference(object));
+ } else {
+ Register object = ToRegister(instr->object());
+ __ movq(MemOperand(object, offset), value);
+ }
+ return;
+ }
+
+ Register object = ToRegister(instr->object());
Handle<Map> transition = instr->transition();
if (FLAG_track_fields && representation.IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Thu Jul 25
04:53:38 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Mon Jul 29
06:56:51 2013
@@ -106,6 +106,7 @@
int32_t ToInteger32(LConstantOperand* op) const;
Smi* ToSmi(LConstantOperand* op) const;
double ToDouble(LConstantOperand* op) const;
+ ExternalReference ToExternalReference(LConstantOperand* op) const;
bool IsTaggedConstant(LConstantOperand* op) const;
Handle<Object> ToHandle(LConstantOperand* op) const;
Operand ToOperand(LOperand* op) const;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Mon Jul 29 02:12:16 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Mon Jul 29 06:56:51 2013
@@ -1997,6 +1997,8 @@
} else if (r.IsDouble()) {
LOperand* temp = TempRegister();
return DefineAsRegister(new(zone()) LConstantD(temp));
+ } else if (r.IsExternal()) {
+ return DefineAsRegister(new(zone()) LConstantE);
} else if (r.IsTagged()) {
return DefineAsRegister(new(zone()) LConstantT);
} else {
@@ -2074,6 +2076,10 @@
LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
+ if (instr->access().IsExternalMemory() && instr->access().offset() == 0)
{
+ LOperand* obj = UseRegisterOrConstantAtStart(instr->object());
+ return DefineFixed(new(zone()) LLoadNamedField(obj), rax);
+ }
LOperand* obj = UseRegisterAtStart(instr->object());
return DefineAsRegister(new(zone()) LLoadNamedField(obj));
}
@@ -2249,6 +2255,8 @@
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
bool is_in_object = instr->access().IsInobject();
+ bool is_external_location = instr->access().IsExternalMemory() &&
+ instr->access().offset() == 0;
bool needs_write_barrier = instr->NeedsWriteBarrier();
bool needs_write_barrier_for_map = !instr->transition().is_null() &&
instr->NeedsWriteBarrierForMap();
@@ -2258,6 +2266,11 @@
obj = is_in_object
? UseRegister(instr->object())
: UseTempRegister(instr->object());
+ } else if (is_external_location) {
+ ASSERT(!is_in_object);
+ ASSERT(!needs_write_barrier);
+ ASSERT(!needs_write_barrier_for_map);
+ obj = UseRegisterOrConstant(instr->object());
} else {
obj = needs_write_barrier_for_map
? UseRegister(instr->object())
@@ -2271,6 +2284,8 @@
LOperand* val;
if (needs_write_barrier) {
val = UseTempRegister(instr->value());
+ } else if (is_external_location) {
+ val = UseFixed(instr->value(), rax);
} else if (can_be_constant) {
val = UseRegisterOrConstant(instr->value());
} else if (FLAG_track_fields && instr->field_representation().IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Mon Jul 29 06:56:51 2013
@@ -79,6 +79,7 @@
V(CmpMapAndBranch) \
V(CmpT) \
V(ConstantD) \
+ V(ConstantE) \
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
@@ -1166,6 +1167,17 @@
};
+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+ DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+ ExternalReference value() const {
+ return hydrogen()->ExternalReferenceValue();
+ }
+};
+
+
class LConstantT: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.