Use Unique<Object> in HConstant and remove UniqueValueId.
BUG= R=verwaest@chromium.org Review URL: https://codereview.chromium.org/24350014 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16911 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
70b8e2d013
commit
cee5773017
@ -2363,8 +2363,7 @@ static bool IsInteger32(double value) {
|
|||||||
|
|
||||||
HConstant::HConstant(Handle<Object> handle, Representation r)
|
HConstant::HConstant(Handle<Object> handle, Representation r)
|
||||||
: HTemplateInstruction<0>(HType::TypeFromValue(handle)),
|
: HTemplateInstruction<0>(HType::TypeFromValue(handle)),
|
||||||
handle_(handle),
|
object_(Unique<Object>::CreateUninitialized(handle)),
|
||||||
unique_id_(),
|
|
||||||
has_smi_value_(false),
|
has_smi_value_(false),
|
||||||
has_int32_value_(false),
|
has_int32_value_(false),
|
||||||
has_double_value_(false),
|
has_double_value_(false),
|
||||||
@ -2373,29 +2372,28 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
|
|||||||
is_not_in_new_space_(true),
|
is_not_in_new_space_(true),
|
||||||
is_cell_(false),
|
is_cell_(false),
|
||||||
boolean_value_(handle->BooleanValue()) {
|
boolean_value_(handle->BooleanValue()) {
|
||||||
if (handle_->IsHeapObject()) {
|
if (handle->IsHeapObject()) {
|
||||||
Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap();
|
Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap();
|
||||||
is_not_in_new_space_ = !heap->InNewSpace(*handle);
|
is_not_in_new_space_ = !heap->InNewSpace(*handle);
|
||||||
}
|
}
|
||||||
if (handle_->IsNumber()) {
|
if (handle->IsNumber()) {
|
||||||
double n = handle_->Number();
|
double n = handle->Number();
|
||||||
has_int32_value_ = IsInteger32(n);
|
has_int32_value_ = IsInteger32(n);
|
||||||
int32_value_ = DoubleToInt32(n);
|
int32_value_ = DoubleToInt32(n);
|
||||||
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
|
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
|
||||||
double_value_ = n;
|
double_value_ = n;
|
||||||
has_double_value_ = true;
|
has_double_value_ = true;
|
||||||
} else {
|
} else {
|
||||||
is_internalized_string_ = handle_->IsInternalizedString();
|
is_internalized_string_ = handle->IsInternalizedString();
|
||||||
}
|
}
|
||||||
|
|
||||||
is_cell_ = !handle_.is_null() &&
|
is_cell_ = !handle.is_null() &&
|
||||||
(handle_->IsCell() || handle_->IsPropertyCell());
|
(handle->IsCell() || handle->IsPropertyCell());
|
||||||
Initialize(r);
|
Initialize(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HConstant::HConstant(Handle<Object> handle,
|
HConstant::HConstant(Unique<Object> unique,
|
||||||
UniqueValueId unique_id,
|
|
||||||
Representation r,
|
Representation r,
|
||||||
HType type,
|
HType type,
|
||||||
bool is_internalize_string,
|
bool is_internalize_string,
|
||||||
@ -2403,8 +2401,7 @@ HConstant::HConstant(Handle<Object> handle,
|
|||||||
bool is_cell,
|
bool is_cell,
|
||||||
bool boolean_value)
|
bool boolean_value)
|
||||||
: HTemplateInstruction<0>(type),
|
: HTemplateInstruction<0>(type),
|
||||||
handle_(handle),
|
object_(unique),
|
||||||
unique_id_(unique_id),
|
|
||||||
has_smi_value_(false),
|
has_smi_value_(false),
|
||||||
has_int32_value_(false),
|
has_int32_value_(false),
|
||||||
has_double_value_(false),
|
has_double_value_(false),
|
||||||
@ -2413,36 +2410,17 @@ HConstant::HConstant(Handle<Object> handle,
|
|||||||
is_not_in_new_space_(is_not_in_new_space),
|
is_not_in_new_space_(is_not_in_new_space),
|
||||||
is_cell_(is_cell),
|
is_cell_(is_cell),
|
||||||
boolean_value_(boolean_value) {
|
boolean_value_(boolean_value) {
|
||||||
ASSERT(!handle.is_null());
|
ASSERT(!unique.handle().is_null());
|
||||||
ASSERT(!type.IsTaggedNumber());
|
ASSERT(!type.IsTaggedNumber());
|
||||||
Initialize(r);
|
Initialize(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HConstant::HConstant(Handle<Map> handle,
|
|
||||||
UniqueValueId unique_id)
|
|
||||||
: HTemplateInstruction<0>(HType::Tagged()),
|
|
||||||
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_(false),
|
|
||||||
is_not_in_new_space_(true),
|
|
||||||
is_cell_(false),
|
|
||||||
boolean_value_(false) {
|
|
||||||
ASSERT(!handle.is_null());
|
|
||||||
Initialize(Representation::Tagged());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HConstant::HConstant(int32_t integer_value,
|
HConstant::HConstant(int32_t integer_value,
|
||||||
Representation r,
|
Representation r,
|
||||||
bool is_not_in_new_space,
|
bool is_not_in_new_space,
|
||||||
Handle<Object> optional_handle)
|
Unique<Object> object)
|
||||||
: handle_(optional_handle),
|
: object_(object),
|
||||||
unique_id_(),
|
|
||||||
has_smi_value_(Smi::IsValid(integer_value)),
|
has_smi_value_(Smi::IsValid(integer_value)),
|
||||||
has_int32_value_(true),
|
has_int32_value_(true),
|
||||||
has_double_value_(true),
|
has_double_value_(true),
|
||||||
@ -2461,9 +2439,8 @@ HConstant::HConstant(int32_t integer_value,
|
|||||||
HConstant::HConstant(double double_value,
|
HConstant::HConstant(double double_value,
|
||||||
Representation r,
|
Representation r,
|
||||||
bool is_not_in_new_space,
|
bool is_not_in_new_space,
|
||||||
Handle<Object> optional_handle)
|
Unique<Object> object)
|
||||||
: handle_(optional_handle),
|
: object_(object),
|
||||||
unique_id_(),
|
|
||||||
has_int32_value_(IsInteger32(double_value)),
|
has_int32_value_(IsInteger32(double_value)),
|
||||||
has_double_value_(true),
|
has_double_value_(true),
|
||||||
has_external_reference_value_(false),
|
has_external_reference_value_(false),
|
||||||
@ -2481,6 +2458,7 @@ HConstant::HConstant(double double_value,
|
|||||||
|
|
||||||
HConstant::HConstant(ExternalReference reference)
|
HConstant::HConstant(ExternalReference reference)
|
||||||
: HTemplateInstruction<0>(HType::None()),
|
: HTemplateInstruction<0>(HType::None()),
|
||||||
|
object_(Unique<Object>(Handle<Object>::null())),
|
||||||
has_smi_value_(false),
|
has_smi_value_(false),
|
||||||
has_int32_value_(false),
|
has_int32_value_(false),
|
||||||
has_double_value_(false),
|
has_double_value_(false),
|
||||||
@ -2494,14 +2472,6 @@ HConstant::HConstant(ExternalReference reference)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void PrepareConstant(Handle<Object> object) {
|
|
||||||
if (!object->IsJSObject()) return;
|
|
||||||
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
|
|
||||||
if (!js_object->map()->is_deprecated()) return;
|
|
||||||
JSObject::TryMigrateInstance(js_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HConstant::Initialize(Representation r) {
|
void HConstant::Initialize(Representation r) {
|
||||||
if (r.IsNone()) {
|
if (r.IsNone()) {
|
||||||
if (has_smi_value_ && SmiValuesAre31Bits()) {
|
if (has_smi_value_ && SmiValuesAre31Bits()) {
|
||||||
@ -2513,7 +2483,14 @@ void HConstant::Initialize(Representation r) {
|
|||||||
} else if (has_external_reference_value_) {
|
} else if (has_external_reference_value_) {
|
||||||
r = Representation::External();
|
r = Representation::External();
|
||||||
} else {
|
} else {
|
||||||
PrepareConstant(handle_);
|
Handle<Object> object = object_.handle();
|
||||||
|
if (object->IsJSObject()) {
|
||||||
|
// Try to eagerly migrate JSObjects that have deprecated maps.
|
||||||
|
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
|
||||||
|
if (js_object->map()->is_deprecated()) {
|
||||||
|
JSObject::TryMigrateInstance(js_object);
|
||||||
|
}
|
||||||
|
}
|
||||||
r = Representation::Tagged();
|
r = Representation::Tagged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2541,17 +2518,16 @@ HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
|
|||||||
if (r.IsDouble() && !has_double_value_) return NULL;
|
if (r.IsDouble() && !has_double_value_) return NULL;
|
||||||
if (r.IsExternal() && !has_external_reference_value_) return NULL;
|
if (r.IsExternal() && !has_external_reference_value_) return NULL;
|
||||||
if (has_int32_value_) {
|
if (has_int32_value_) {
|
||||||
return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_);
|
return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_);
|
||||||
}
|
}
|
||||||
if (has_double_value_) {
|
if (has_double_value_) {
|
||||||
return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_);
|
return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_);
|
||||||
}
|
}
|
||||||
if (has_external_reference_value_) {
|
if (has_external_reference_value_) {
|
||||||
return new(zone) HConstant(external_reference_value_);
|
return new(zone) HConstant(external_reference_value_);
|
||||||
}
|
}
|
||||||
ASSERT(!handle_.is_null());
|
ASSERT(!object_.handle().is_null());
|
||||||
return new(zone) HConstant(handle_,
|
return new(zone) HConstant(object_,
|
||||||
unique_id_,
|
|
||||||
r,
|
r,
|
||||||
type_,
|
type_,
|
||||||
is_internalized_string_,
|
is_internalized_string_,
|
||||||
@ -2567,12 +2543,12 @@ Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) {
|
|||||||
res = new(zone) HConstant(int32_value_,
|
res = new(zone) HConstant(int32_value_,
|
||||||
Representation::Integer32(),
|
Representation::Integer32(),
|
||||||
is_not_in_new_space_,
|
is_not_in_new_space_,
|
||||||
handle_);
|
object_);
|
||||||
} else if (has_double_value_) {
|
} else if (has_double_value_) {
|
||||||
res = new(zone) HConstant(DoubleToInt32(double_value_),
|
res = new(zone) HConstant(DoubleToInt32(double_value_),
|
||||||
Representation::Integer32(),
|
Representation::Integer32(),
|
||||||
is_not_in_new_space_,
|
is_not_in_new_space_,
|
||||||
handle_);
|
object_);
|
||||||
}
|
}
|
||||||
return Maybe<HConstant*>(res != NULL, res);
|
return Maybe<HConstant*>(res != NULL, res);
|
||||||
}
|
}
|
||||||
@ -3439,8 +3415,8 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
|
|||||||
HConstant* filler_map = HConstant::New(
|
HConstant* filler_map = HConstant::New(
|
||||||
zone,
|
zone,
|
||||||
context(),
|
context(),
|
||||||
isolate()->factory()->free_space_map(),
|
isolate()->factory()->free_space_map());
|
||||||
UniqueValueId::free_space_map(isolate()->heap()));
|
filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready
|
||||||
filler_map->InsertAfter(free_space_instr);
|
filler_map->InsertAfter(free_space_instr);
|
||||||
HInstruction* store_map = HStoreNamedField::New(zone, context(),
|
HInstruction* store_map = HStoreNamedField::New(zone, context(),
|
||||||
free_space_instr, HObjectAccess::ForMap(), filler_map);
|
free_space_instr, HObjectAccess::ForMap(), filler_map);
|
||||||
|
@ -306,65 +306,6 @@ class Range V8_FINAL : public ZoneObject {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class UniqueValueId V8_FINAL {
|
|
||||||
public:
|
|
||||||
UniqueValueId() : raw_address_(NULL) { }
|
|
||||||
|
|
||||||
explicit UniqueValueId(Handle<Object> handle) {
|
|
||||||
ASSERT(!AllowHeapAllocation::IsAllowed());
|
|
||||||
static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1);
|
|
||||||
if (handle.is_null()) {
|
|
||||||
raw_address_ = kEmptyHandleSentinel;
|
|
||||||
} else {
|
|
||||||
raw_address_ = reinterpret_cast<Address>(*handle);
|
|
||||||
ASSERT_NE(kEmptyHandleSentinel, raw_address_);
|
|
||||||
}
|
|
||||||
ASSERT(IsInitialized());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsInitialized() const { return raw_address_ != NULL; }
|
|
||||||
|
|
||||||
bool operator==(const UniqueValueId& other) const {
|
|
||||||
ASSERT(IsInitialized() && other.IsInitialized());
|
|
||||||
return raw_address_ == other.raw_address_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const UniqueValueId& other) const {
|
|
||||||
ASSERT(IsInitialized() && other.IsInitialized());
|
|
||||||
return raw_address_ != other.raw_address_;
|
|
||||||
}
|
|
||||||
|
|
||||||
intptr_t Hashcode() const {
|
|
||||||
ASSERT(IsInitialized());
|
|
||||||
return reinterpret_cast<intptr_t>(raw_address_);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define IMMOVABLE_UNIQUE_VALUE_ID(name) \
|
|
||||||
static UniqueValueId name(Heap* heap) { return UniqueValueId(heap->name()); }
|
|
||||||
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(free_space_map)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(nan_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(undefined_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(null_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(true_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(false_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(empty_string)
|
|
||||||
IMMOVABLE_UNIQUE_VALUE_ID(empty_fixed_array)
|
|
||||||
|
|
||||||
#undef IMMOVABLE_UNIQUE_VALUE_ID
|
|
||||||
|
|
||||||
private:
|
|
||||||
Address raw_address_;
|
|
||||||
|
|
||||||
explicit UniqueValueId(Object* object) {
|
|
||||||
raw_address_ = reinterpret_cast<Address>(object);
|
|
||||||
ASSERT(IsInitialized());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class HType V8_FINAL {
|
class HType V8_FINAL {
|
||||||
public:
|
public:
|
||||||
static HType None() { return HType(kNone); }
|
static HType None() { return HType(kNone); }
|
||||||
@ -904,7 +845,7 @@ class HValue : public ZoneObject {
|
|||||||
virtual intptr_t Hashcode();
|
virtual intptr_t Hashcode();
|
||||||
|
|
||||||
// Compute unique ids upfront that is safe wrt GC and concurrent compilation.
|
// Compute unique ids upfront that is safe wrt GC and concurrent compilation.
|
||||||
virtual void FinalizeUniqueValueId() { }
|
virtual void FinalizeUniqueness() { }
|
||||||
|
|
||||||
// Printing support.
|
// Printing support.
|
||||||
virtual void PrintTo(StringStream* stream) = 0;
|
virtual void PrintTo(StringStream* stream) = 0;
|
||||||
@ -2691,7 +2632,7 @@ class HCheckValue V8_FINAL : public HUnaryOperation {
|
|||||||
return new(zone) HCheckValue(value, target, object_in_new_space);
|
return new(zone) HCheckValue(value, target, object_in_new_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void FinalizeUniqueValueId() V8_OVERRIDE {
|
virtual void FinalizeUniqueness() V8_OVERRIDE {
|
||||||
object_ = Unique<HeapObject>(object_.handle());
|
object_ = Unique<HeapObject>(object_.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3297,7 +3238,6 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
|
DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
|
||||||
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
|
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
|
||||||
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
|
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
|
||||||
DECLARE_INSTRUCTION_FACTORY_P2(HConstant, Handle<Map>, UniqueValueId);
|
|
||||||
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
|
DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
|
||||||
|
|
||||||
static HConstant* CreateAndInsertAfter(Zone* zone,
|
static HConstant* CreateAndInsertAfter(Zone* zone,
|
||||||
@ -3323,15 +3263,15 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> handle(Isolate* isolate) {
|
Handle<Object> handle(Isolate* isolate) {
|
||||||
if (handle_.is_null()) {
|
if (object_.handle().is_null()) {
|
||||||
Factory* factory = isolate->factory();
|
|
||||||
// Default arguments to is_not_in_new_space depend on this heap number
|
// Default arguments to is_not_in_new_space depend on this heap number
|
||||||
// to be tenured so that it's guaranteed not be be located in new space.
|
// to be tenured so that it's guaranteed not to be located in new space.
|
||||||
handle_ = factory->NewNumber(double_value_, TENURED);
|
object_ = Unique<Object>::CreateUninitialized(
|
||||||
|
isolate->factory()->NewNumber(double_value_, TENURED));
|
||||||
}
|
}
|
||||||
AllowDeferredHandleDereference smi_check;
|
AllowDeferredHandleDereference smi_check;
|
||||||
ASSERT(has_int32_value_ || !handle_->IsSmi());
|
ASSERT(has_int32_value_ || !object_.handle()->IsSmi());
|
||||||
return handle_;
|
return object_.handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasMap(Handle<Map> map) {
|
bool HasMap(Handle<Map> map) {
|
||||||
@ -3365,17 +3305,18 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!handle_.is_null());
|
ASSERT(!object_.handle().is_null());
|
||||||
Heap* heap = isolate()->heap();
|
Heap* heap = isolate()->heap();
|
||||||
ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap));
|
ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value()));
|
||||||
ASSERT(unique_id_ != UniqueValueId::nan_value(heap));
|
ASSERT(!object_.IsKnownGlobal(heap->nan_value()));
|
||||||
return unique_id_ == UniqueValueId::undefined_value(heap) ||
|
return
|
||||||
unique_id_ == UniqueValueId::null_value(heap) ||
|
object_.IsKnownGlobal(heap->undefined_value()) ||
|
||||||
unique_id_ == UniqueValueId::true_value(heap) ||
|
object_.IsKnownGlobal(heap->null_value()) ||
|
||||||
unique_id_ == UniqueValueId::false_value(heap) ||
|
object_.IsKnownGlobal(heap->true_value()) ||
|
||||||
unique_id_ == UniqueValueId::the_hole_value(heap) ||
|
object_.IsKnownGlobal(heap->false_value()) ||
|
||||||
unique_id_ == UniqueValueId::empty_string(heap) ||
|
object_.IsKnownGlobal(heap->the_hole_value()) ||
|
||||||
unique_id_ == UniqueValueId::empty_fixed_array(heap);
|
object_.IsKnownGlobal(heap->empty_string()) ||
|
||||||
|
object_.IsKnownGlobal(heap->empty_fixed_array());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCell() const {
|
bool IsCell() const {
|
||||||
@ -3414,11 +3355,7 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) {
|
if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Heap* heap = isolate()->heap();
|
return object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
|
||||||
if (!handle_.is_null() && *handle_ == heap->the_hole_value()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
bool HasNumberValue() const { return has_double_value_; }
|
bool HasNumberValue() const { return has_double_value_; }
|
||||||
int32_t NumberValueAsInteger32() const {
|
int32_t NumberValueAsInteger32() const {
|
||||||
@ -3430,12 +3367,12 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
}
|
}
|
||||||
bool HasStringValue() const {
|
bool HasStringValue() const {
|
||||||
if (has_double_value_ || has_int32_value_) return false;
|
if (has_double_value_ || has_int32_value_) return false;
|
||||||
ASSERT(!handle_.is_null());
|
ASSERT(!object_.handle().is_null());
|
||||||
return type_.IsString();
|
return type_.IsString();
|
||||||
}
|
}
|
||||||
Handle<String> StringValue() const {
|
Handle<String> StringValue() const {
|
||||||
ASSERT(HasStringValue());
|
ASSERT(HasStringValue());
|
||||||
return Handle<String>::cast(handle_);
|
return Handle<String>::cast(object_.handle());
|
||||||
}
|
}
|
||||||
bool HasInternalizedStringValue() const {
|
bool HasInternalizedStringValue() const {
|
||||||
return HasStringValue() && is_internalized_string_;
|
return HasStringValue() && is_internalized_string_;
|
||||||
@ -3459,27 +3396,20 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
} else if (has_external_reference_value_) {
|
} else if (has_external_reference_value_) {
|
||||||
return reinterpret_cast<intptr_t>(external_reference_value_.address());
|
return reinterpret_cast<intptr_t>(external_reference_value_.address());
|
||||||
} else {
|
} else {
|
||||||
ASSERT(!handle_.is_null());
|
ASSERT(!object_.handle().is_null());
|
||||||
return unique_id_.Hashcode();
|
return object_.Hashcode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void FinalizeUniqueValueId() V8_OVERRIDE {
|
virtual void FinalizeUniqueness() V8_OVERRIDE {
|
||||||
if (!has_double_value_ && !has_external_reference_value_) {
|
if (!has_double_value_ && !has_external_reference_value_) {
|
||||||
ASSERT(!handle_.is_null());
|
ASSERT(!object_.handle().is_null());
|
||||||
unique_id_ = UniqueValueId(handle_);
|
object_ = Unique<Object>(object_.handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UniqueValueIdsMatch(UniqueValueId other) {
|
|
||||||
return !has_double_value_ && !has_external_reference_value_ &&
|
|
||||||
unique_id_ == other;
|
|
||||||
}
|
|
||||||
|
|
||||||
Unique<Object> GetUnique() const {
|
Unique<Object> GetUnique() const {
|
||||||
// TODO(titzer): store a Unique<HeapObject> inside the HConstant.
|
return object_;
|
||||||
Address raw_address = reinterpret_cast<Address>(unique_id_.Hashcode());
|
|
||||||
return Unique<Object>(raw_address, handle_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -3505,9 +3435,8 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
external_reference_value_ ==
|
external_reference_value_ ==
|
||||||
other_constant->external_reference_value_;
|
other_constant->external_reference_value_;
|
||||||
} else {
|
} else {
|
||||||
ASSERT(!handle_.is_null());
|
ASSERT(!object_.handle().is_null());
|
||||||
return !other_constant->handle_.is_null() &&
|
return other_constant->object_ == object_;
|
||||||
unique_id_ == other_constant->unique_id_;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3517,33 +3446,30 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
HConstant(int32_t value,
|
HConstant(int32_t value,
|
||||||
Representation r = Representation::None(),
|
Representation r = Representation::None(),
|
||||||
bool is_not_in_new_space = true,
|
bool is_not_in_new_space = true,
|
||||||
Handle<Object> optional_handle = Handle<Object>::null());
|
Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
|
||||||
HConstant(double value,
|
HConstant(double value,
|
||||||
Representation r = Representation::None(),
|
Representation r = Representation::None(),
|
||||||
bool is_not_in_new_space = true,
|
bool is_not_in_new_space = true,
|
||||||
Handle<Object> optional_handle = Handle<Object>::null());
|
Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
|
||||||
HConstant(Handle<Object> handle,
|
HConstant(Unique<Object> unique,
|
||||||
UniqueValueId unique_id,
|
|
||||||
Representation r,
|
Representation r,
|
||||||
HType type,
|
HType type,
|
||||||
bool is_internalized_string,
|
bool is_internalized_string,
|
||||||
bool is_not_in_new_space,
|
bool is_not_in_new_space,
|
||||||
bool is_cell,
|
bool is_cell,
|
||||||
bool boolean_value);
|
bool boolean_value);
|
||||||
HConstant(Handle<Map> handle,
|
|
||||||
UniqueValueId unique_id);
|
|
||||||
explicit HConstant(ExternalReference reference);
|
explicit HConstant(ExternalReference reference);
|
||||||
|
|
||||||
void Initialize(Representation r);
|
void Initialize(Representation r);
|
||||||
|
|
||||||
virtual bool IsDeletable() const V8_OVERRIDE { return true; }
|
virtual bool IsDeletable() const V8_OVERRIDE { return true; }
|
||||||
|
|
||||||
// If this is a numerical constant, handle_ either points to to the
|
// If this is a numerical constant, object_ either points to the
|
||||||
// HeapObject the constant originated from or is null. If the
|
// HeapObject the constant originated from or is null. If the
|
||||||
// constant is non-numeric, handle_ always points to a valid
|
// constant is non-numeric, object_ always points to a valid
|
||||||
// constant HeapObject.
|
// constant HeapObject.
|
||||||
Handle<Object> handle_;
|
Unique<Object> object_;
|
||||||
UniqueValueId unique_id_;
|
|
||||||
|
|
||||||
// We store the HConstant in the most specific form safely possible.
|
// We store the HConstant in the most specific form safely possible.
|
||||||
// The two flags, has_int32_value_ and has_double_value_ tell us if
|
// The two flags, has_int32_value_ and has_double_value_ tell us if
|
||||||
@ -5137,7 +5063,7 @@ class HLoadGlobalCell V8_FINAL : public HTemplateInstruction<0> {
|
|||||||
return cell_.Hashcode();
|
return cell_.Hashcode();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void FinalizeUniqueValueId() V8_OVERRIDE {
|
virtual void FinalizeUniqueness() V8_OVERRIDE {
|
||||||
cell_ = Unique<Cell>(cell_.handle());
|
cell_ = Unique<Cell>(cell_.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5435,7 +5361,7 @@ class HStoreGlobalCell V8_FINAL : public HUnaryOperation {
|
|||||||
return StoringValueNeedsWriteBarrier(value());
|
return StoringValueNeedsWriteBarrier(value());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void FinalizeUniqueValueId() V8_OVERRIDE {
|
virtual void FinalizeUniqueness() V8_OVERRIDE {
|
||||||
cell_ = Unique<PropertyCell>(cell_.handle());
|
cell_ = Unique<PropertyCell>(cell_.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,8 +649,7 @@ HConstant* HGraph::GetConstantMinus1() {
|
|||||||
HConstant* HGraph::GetConstant##Name() { \
|
HConstant* HGraph::GetConstant##Name() { \
|
||||||
if (!constant_##name##_.is_set()) { \
|
if (!constant_##name##_.is_set()) { \
|
||||||
HConstant* constant = new(zone()) HConstant( \
|
HConstant* constant = new(zone()) HConstant( \
|
||||||
isolate()->factory()->name##_value(), \
|
Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
|
||||||
UniqueValueId::name##_value(isolate()->heap()), \
|
|
||||||
Representation::Tagged(), \
|
Representation::Tagged(), \
|
||||||
htype, \
|
htype, \
|
||||||
false, \
|
false, \
|
||||||
@ -1039,7 +1038,7 @@ HGraph* HGraphBuilder::CreateGraph() {
|
|||||||
CompilationPhase phase("H_Block building", info_);
|
CompilationPhase phase("H_Block building", info_);
|
||||||
set_current_block(graph()->entry_block());
|
set_current_block(graph()->entry_block());
|
||||||
if (!BuildGraph()) return NULL;
|
if (!BuildGraph()) return NULL;
|
||||||
graph()->FinalizeUniqueValueIds();
|
graph()->FinalizeUniqueness();
|
||||||
return graph_;
|
return graph_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2293,12 +2292,12 @@ HBasicBlock* HGraph::CreateBasicBlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HGraph::FinalizeUniqueValueIds() {
|
void HGraph::FinalizeUniqueness() {
|
||||||
DisallowHeapAllocation no_gc;
|
DisallowHeapAllocation no_gc;
|
||||||
ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
|
ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
|
||||||
for (int i = 0; i < blocks()->length(); ++i) {
|
for (int i = 0; i < blocks()->length(); ++i) {
|
||||||
for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
|
for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
|
||||||
it.Current()->FinalizeUniqueValueId();
|
it.Current()->FinalizeUniqueness();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ class HGraph V8_FINAL : public ZoneObject {
|
|||||||
HBasicBlock* entry_block() const { return entry_block_; }
|
HBasicBlock* entry_block() const { return entry_block_; }
|
||||||
HEnvironment* start_environment() const { return start_environment_; }
|
HEnvironment* start_environment() const { return start_environment_; }
|
||||||
|
|
||||||
void FinalizeUniqueValueIds();
|
void FinalizeUniqueness();
|
||||||
bool ProcessArgumentsObject();
|
bool ProcessArgumentsObject();
|
||||||
void OrderBlocks();
|
void OrderBlocks();
|
||||||
void AssignDominators();
|
void AssignDominators();
|
||||||
|
18
src/unique.h
18
src/unique.h
@ -54,7 +54,7 @@ class UniqueSet;
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class Unique V8_FINAL {
|
class Unique V8_FINAL {
|
||||||
public:
|
public:
|
||||||
// TODO(titzer): make private and introduce a factory.
|
// TODO(titzer): make private and introduce a uniqueness scope.
|
||||||
explicit Unique(Handle<T> handle) {
|
explicit Unique(Handle<T> handle) {
|
||||||
if (handle.is_null()) {
|
if (handle.is_null()) {
|
||||||
raw_address_ = NULL;
|
raw_address_ = NULL;
|
||||||
@ -111,8 +111,11 @@ class Unique V8_FINAL {
|
|||||||
return raw_address_ == NULL;
|
return raw_address_ == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the handle from this Unique in order to dereference it.
|
inline bool IsKnownGlobal(void* global) const {
|
||||||
// WARNING: Only do this if you have access to the heap.
|
ASSERT(IsInitialized());
|
||||||
|
return raw_address_ == reinterpret_cast<Address>(global);
|
||||||
|
}
|
||||||
|
|
||||||
inline Handle<T> handle() const {
|
inline Handle<T> handle() const {
|
||||||
return handle_;
|
return handle_;
|
||||||
}
|
}
|
||||||
@ -123,7 +126,11 @@ class Unique V8_FINAL {
|
|||||||
|
|
||||||
// TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
|
// TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
|
||||||
static Unique<T> CreateUninitialized(Handle<T> handle) {
|
static Unique<T> CreateUninitialized(Handle<T> handle) {
|
||||||
return Unique<T>(static_cast<Address>(NULL), handle);
|
return Unique<T>(reinterpret_cast<Address>(NULL), handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Unique<T> CreateImmovable(Handle<T> handle) {
|
||||||
|
return Unique<T>(reinterpret_cast<Address>(*handle), handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class UniqueSet<T>; // Uses internal details for speed.
|
friend class UniqueSet<T>; // Uses internal details for speed.
|
||||||
@ -171,9 +178,10 @@ class UniqueSet V8_FINAL : public ZoneObject {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether this set contains the given element. O(|this|)
|
||||||
|
// TODO(titzer): use binary search for large sets to make this O(log|this|)
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool Contains(Unique<U> elem) const {
|
bool Contains(Unique<U> elem) const {
|
||||||
// TODO(titzer): use binary search for larger sets.
|
|
||||||
for (int i = 0; i < size_; i++) {
|
for (int i = 0; i < size_; i++) {
|
||||||
if (this->array_[i] == elem) return true;
|
if (this->array_[i] == elem) return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user