Revision: 19759
Author: [email protected]
Date: Mon Mar 10 14:50:01 2014 UTC
Log: Implement KnownSuccessor method to some control instructions.
[email protected]
BUG=v8:3118
LOG=N
Review URL: https://codereview.chromium.org/174863002
http://code.google.com/p/v8/source/detail?r=19759
Added:
/branches/bleeding_edge/test/mjsunit/constant-fold-control-instructions.js
Modified:
/branches/bleeding_edge/src/hydrogen-instructions.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/objects-inl.h
=======================================
--- /dev/null
+++
/branches/bleeding_edge/test/mjsunit/constant-fold-control-instructions.js
Mon Mar 10 14:50:01 2014 UTC
@@ -0,0 +1,43 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --fold-constants
+
+function test() {
+ assertEquals("string", typeof "");
+ assertEquals("number", typeof 1.1);
+ assertEquals("number", typeof 1);
+ assertEquals("boolean", typeof true);
+ assertEquals("function", typeof function() {});
+ assertEquals("object", typeof null);
+ assertEquals("object", typeof {});
+
+ assertTrue(%_IsObject({}));
+ assertTrue(%_IsObject(null));
+ assertTrue(%_IsObject(/regex/));
+ assertFalse(%_IsObject(0));
+ assertFalse(%_IsObject(""));
+
+ assertTrue(%_IsSmi(1));
+ assertFalse(%_IsSmi(1.1));
+ assertFalse(%_IsSmi({}));
+
+ assertTrue(%_IsRegExp(/regexp/));
+ assertFalse(%_IsRegExp({}));
+
+ assertTrue(%_IsArray([1]));
+ assertFalse(%_IsArray(function() {}));
+
+ assertTrue(%_IsFunction(function() {}));
+ assertFalse(%_IsFunction(null));
+
+ assertTrue(%_IsSpecObject(new Date()));
+ assertFalse(%_IsSpecObject(1));
+}
+
+
+test();
+test();
+%OptimizeFunctionOnNextCall(test);
+test();
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Mar 10
05:52:03 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Mar 10
14:50:01 2014 UTC
@@ -1215,19 +1215,53 @@
void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
- stream->Add(" == %o", *type_literal_);
+ stream->Add(" == %o", *type_literal_.handle());
HControlInstruction::PrintDataTo(stream);
}
-bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
- if (value()->representation().IsSpecialization()) {
- if (compares_number_type()) {
- *block = FirstSuccessor();
- } else {
- *block = SecondSuccessor();
+static String* TypeOfString(HConstant* constant, Isolate* isolate) {
+ Heap* heap = isolate->heap();
+ if (constant->HasNumberValue()) return heap->number_string();
+ if (constant->IsUndetectable()) return heap->undefined_string();
+ if (constant->HasStringValue()) return heap->string_string();
+ switch (constant->GetInstanceType()) {
+ case ODDBALL_TYPE: {
+ Unique<Object> unique = constant->GetUnique();
+ if (unique.IsKnownGlobal(heap->true_value()) ||
+ unique.IsKnownGlobal(heap->false_value())) {
+ return heap->boolean_string();
+ }
+ if (unique.IsKnownGlobal(heap->null_value())) {
+ return FLAG_harmony_typeof ? heap->null_string()
+ : heap->object_string();
+ }
+ ASSERT(unique.IsKnownGlobal(heap->undefined_value()));
+ return heap->undefined_string();
}
+ case SYMBOL_TYPE:
+ return heap->symbol_string();
+ case JS_FUNCTION_TYPE:
+ case JS_FUNCTION_PROXY_TYPE:
+ return heap->function_string();
+ default:
+ return heap->object_string();
+ }
+}
+
+
+bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ HConstant* constant = HConstant::cast(value());
+ String* type_string = TypeOfString(constant, isolate());
+ bool same_type = type_literal_.IsKnownGlobal(type_string);
+ *block = same_type ? FirstSuccessor() : SecondSuccessor();
return true;
+ } else if (value()->representation().IsSpecialization()) {
+ bool number_type =
+ type_literal_.IsKnownGlobal(isolate()->heap()->number_string());
+ *block = number_type ? FirstSuccessor() : SecondSuccessor();
+ return true;
}
*block = NULL;
return false;
@@ -2498,13 +2532,16 @@
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_(handle->BooleanValue()) {
+ boolean_value_(handle->BooleanValue()),
+ is_undetectable_(false),
+ instance_type_(kUnknownInstanceType) {
if (handle->IsHeapObject()) {
- Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap();
+ Handle<HeapObject> heap_obj = Handle<HeapObject>::cast(handle);
+ Heap* heap = heap_obj->GetHeap();
is_not_in_new_space_ = !heap->InNewSpace(*handle);
+ instance_type_ = heap_obj->map()->instance_type();
+ is_undetectable_ = heap_obj->map()->is_undetectable();
}
if (handle->IsNumber()) {
double n = handle->Number();
@@ -2514,12 +2551,8 @@
double_value_ = n;
has_double_value_ = true;
// TODO(titzer): if this heap number is new space, tenure a new one.
- } else {
- is_internalized_string_ = handle->IsInternalizedString();
}
- is_cell_ = !handle.is_null() &&
- (handle->IsCell() || handle->IsPropertyCell());
Initialize(r);
}
@@ -2527,20 +2560,20 @@
HConstant::HConstant(Unique<Object> unique,
Representation r,
HType type,
- bool is_internalize_string,
bool is_not_in_new_space,
- bool is_cell,
- bool boolean_value)
+ bool boolean_value,
+ bool is_undetectable,
+ InstanceType instance_type)
: HTemplateInstruction<0>(type),
object_(unique),
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) {
+ boolean_value_(boolean_value),
+ is_undetectable_(is_undetectable),
+ instance_type_(instance_type) {
ASSERT(!unique.handle().is_null());
ASSERT(!type.IsTaggedNumber());
Initialize(r);
@@ -2556,12 +2589,12 @@
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),
+ is_undetectable_(false),
int32_value_(integer_value),
- double_value_(FastI2D(integer_value)) {
+ double_value_(FastI2D(integer_value)),
+ instance_type_(kUnknownInstanceType) {
// It's possible to create a constant with a value in Smi-range but
stored
// in a (pre-existing) HeapNumber. See crbug.com/349878.
bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
@@ -2579,12 +2612,12 @@
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)),
+ is_undetectable_(false),
int32_value_(DoubleToInt32(double_value)),
- double_value_(double_value) {
+ double_value_(double_value),
+ instance_type_(kUnknownInstanceType) {
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
// It's possible to create a constant with a value in Smi-range but
stored
// in a (pre-existing) HeapNumber. See crbug.com/349878.
@@ -2602,11 +2635,11 @@
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) {
+ is_undetectable_(false),
+ external_reference_value_(reference),
+ instance_type_(kUnknownInstanceType) {
Initialize(Representation::External());
}
@@ -2705,10 +2738,10 @@
return new(zone) HConstant(object_,
r,
type_,
- is_internalized_string_,
is_not_in_new_space_,
- is_cell_,
- boolean_value_);
+ boolean_value_,
+ is_undetectable_,
+ instance_type_);
}
@@ -3022,17 +3055,82 @@
bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
- if (left()->IsConstant() && right()->IsConstant()) {
- bool comparison_result =
- HConstant::cast(left())->Equals(HConstant::cast(right()));
- *block = comparison_result
- ? FirstSuccessor()
- : SecondSuccessor();
+ if (FLAG_fold_constants && left()->IsConstant() &&
right()->IsConstant()) {
+ *block = HConstant::cast(left())->Equals(HConstant::cast(right()))
+ ? FirstSuccessor() : SecondSuccessor();
return true;
}
*block = NULL;
return false;
}
+
+
+bool ConstantIsObject(HConstant* constant, Isolate* isolate) {
+ if (constant->HasNumberValue()) return false;
+ if (constant->GetUnique().IsKnownGlobal(isolate->heap()->null_value())) {
+ return true;
+ }
+ if (constant->IsUndetectable()) return false;
+ InstanceType type = constant->GetInstanceType();
+ return (FIRST_NONCALLABLE_SPEC_OBJECT_TYPE <= type) &&
+ (type <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+}
+
+
+bool HIsObjectAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ *block = ConstantIsObject(HConstant::cast(value()), isolate())
+ ? FirstSuccessor() : SecondSuccessor();
+ return true;
+ }
+ *block = NULL;
+ return false;
+}
+
+
+bool HIsStringAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ *block = HConstant::cast(value())->HasStringValue()
+ ? FirstSuccessor() : SecondSuccessor();
+ return true;
+ }
+ *block = NULL;
+ return false;
+}
+
+
+bool HIsSmiAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ *block = HConstant::cast(value())->HasSmiValue()
+ ? FirstSuccessor() : SecondSuccessor();
+ return true;
+ }
+ *block = NULL;
+ return false;
+}
+
+
+bool HIsUndetectableAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ *block = HConstant::cast(value())->IsUndetectable()
+ ? FirstSuccessor() : SecondSuccessor();
+ return true;
+ }
+ *block = NULL;
+ return false;
+}
+
+
+bool HHasInstanceTypeAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ InstanceType type = HConstant::cast(value())->GetInstanceType();
+ *block = (from_ <= type) && (type <= to_)
+ ? FirstSuccessor() : SecondSuccessor();
+ return true;
+ }
+ *block = NULL;
+ return false;
+}
void HCompareHoleAndBranch::InferRepresentation(
@@ -3042,6 +3140,14 @@
bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (FLAG_fold_constants && value()->IsConstant()) {
+ HConstant* constant = HConstant::cast(value());
+ if (constant->HasDoubleValue()) {
+ *block = IsMinusZero(constant->DoubleValue())
+ ? FirstSuccessor() : SecondSuccessor();
+ }
+ return true;
+ }
if (value()->representation().IsSmiOrInteger32()) {
// A Smi or Integer32 cannot contain minus zero.
*block = SecondSuccessor();
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Mar 10 05:52:03
2014 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Mar 10 14:50:01
2014 UTC
@@ -3451,8 +3451,8 @@
bool is_not_in_new_space,
HInstruction* instruction) {
return instruction->Prepend(new(zone) HConstant(
- unique, Representation::Tagged(), HType::Tagged(), false,
- is_not_in_new_space, false, false));
+ unique, Representation::Tagged(), HType::Tagged(),
+ is_not_in_new_space, false, false, kUnknownInstanceType));
}
Handle<Object> handle(Isolate* isolate) {
@@ -3487,7 +3487,7 @@
bool ImmortalImmovable() const;
bool IsCell() const {
- return is_cell_;
+ return instance_type_ == CELL_TYPE || instance_type_ ==
PROPERTY_CELL_TYPE;
}
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
@@ -3535,14 +3535,14 @@
bool HasStringValue() const {
if (has_double_value_ || has_int32_value_) return false;
ASSERT(!object_.handle().is_null());
- return type_.IsString();
+ return instance_type_ < FIRST_NONSTRING_TYPE;
}
Handle<String> StringValue() const {
ASSERT(HasStringValue());
return Handle<String>::cast(object_.handle());
}
bool HasInternalizedStringValue() const {
- return HasStringValue() && is_internalized_string_;
+ return HasStringValue() &&
StringShape(instance_type_).IsInternalized();
}
bool HasExternalReferenceValue() const {
@@ -3554,6 +3554,8 @@
bool HasBooleanValue() const { return type_.IsBoolean(); }
bool BooleanValue() const { return boolean_value_; }
+ bool IsUndetectable() const { return is_undetectable_; }
+ InstanceType GetInstanceType() const { return instance_type_; }
virtual intptr_t Hashcode() V8_OVERRIDE {
if (has_int32_value_) {
@@ -3630,10 +3632,10 @@
HConstant(Unique<Object> unique,
Representation r,
HType type,
- bool is_internalized_string,
bool is_not_in_new_space,
- bool is_cell,
- bool boolean_value);
+ bool boolean_value,
+ bool is_undetectable,
+ InstanceType instance_type);
explicit HConstant(ExternalReference reference);
@@ -3656,13 +3658,15 @@
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;
+ bool is_undetectable_: 1;
int32_t int32_value_;
double double_value_;
ExternalReference external_reference_value_;
+
+ static const InstanceType kUnknownInstanceType = FILLER_TYPE;
+ InstanceType instance_type_;
};
@@ -4327,6 +4331,8 @@
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
}
+
+ virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
@@ -4347,6 +4353,8 @@
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
}
+
+ virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
@@ -4372,6 +4380,8 @@
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
}
+
+ virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
protected:
virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
@@ -4394,6 +4404,8 @@
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
}
+
+ virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
@@ -4476,6 +4488,8 @@
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
return Representation::Tagged();
}
+
+ virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
@@ -4558,8 +4572,7 @@
public:
DECLARE_INSTRUCTION_FACTORY_P2(HTypeofIsAndBranch, HValue*,
Handle<String>);
- Handle<String> type_literal() { return type_literal_; }
- bool compares_number_type() { return compares_number_type_; }
+ Handle<String> type_literal() { return type_literal_.handle(); }
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
@@ -4570,16 +4583,16 @@
virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
+ virtual void FinalizeUniqueness() V8_OVERRIDE {
+ type_literal_ = Unique<String>(type_literal_.handle());
+ }
+
private:
HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
: HUnaryControlInstruction(value, NULL, NULL),
- type_literal_(type_literal) {
- Heap* heap = type_literal->GetHeap();
- compares_number_type_ = type_literal->Equals(heap->number_string());
- }
+ type_literal_(Unique<String>::CreateUninitialized(type_literal)) {
}
- Handle<String> type_literal_;
- bool compares_number_type_ : 1;
+ Unique<String> type_literal_;
};
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Mar 10 11:49:29 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Mon Mar 10 14:50:01 2014 UTC
@@ -707,10 +707,10 @@
Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
Representation::Tagged(), \
htype, \
-
false, \
true, \
+
boolean_value, \
false, \
-
boolean_value); \
+
ODDBALL_TYPE); \
constant->InsertAfter(entry_block()->first()); \
constant_##name##_.set(constant); \
}
\
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Mar 10 12:23:05 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Mon Mar 10 14:50:01 2014 UTC
@@ -2080,7 +2080,6 @@
return true;
}
-
void Object::VerifyApiCallResultType() {
--
--
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/d/optout.