Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 913ff665198b25051e63472cb6e6c5a9ec49afc1..f48b75e55cd3e825dbdccf7de206f036a21ecaf3 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -44,6 +44,7 @@ |
#include "hydrogen-infer-representation.h" |
#include "hydrogen-infer-types.h" |
#include "hydrogen-gvn.h" |
+#include "hydrogen-mark-deoptimize.h" |
#include "hydrogen-minus-zero.h" |
#include "hydrogen-osr.h" |
#include "hydrogen-range-analysis.h" |
@@ -610,7 +611,9 @@ void HGraph::Verify(bool do_full_verify) const { |
HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, |
int32_t value) { |
if (!pointer->is_set()) { |
- HConstant* constant = new(zone()) HConstant(value); |
+ // Can't pass GetInvalidContext() to HConstant::New, because that will |
+ // recursively call GetConstant |
+ HConstant* constant = HConstant::New(zone(), NULL, value); |
constant->InsertAfter(GetConstantUndefined()); |
pointer->set(constant); |
} |
@@ -836,9 +839,8 @@ void HGraphBuilder::IfBuilder::Deopt() { |
void HGraphBuilder::IfBuilder::Return(HValue* value) { |
HBasicBlock* block = builder_->current_block(); |
- HValue* context = builder_->environment()->LookupContext(); |
HValue* parameter_count = builder_->graph()->GetConstantMinus1(); |
- block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); |
+ block->FinishExit(builder_->New<HReturn>(value, parameter_count)); |
builder_->set_current_block(NULL); |
if (did_else_) { |
first_false_block_ = NULL; |
@@ -988,6 +990,28 @@ HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
} |
+void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, |
+ HValue* context) { |
+ if (FLAG_native_code_counters && counter->Enabled()) { |
+ HValue* reference = Add<HConstant>(ExternalReference(counter)); |
+ HValue* old_value = Add<HLoadNamedField>(reference, |
+ HObjectAccess::ForCounter()); |
+ HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); |
+ new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow |
+ Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), |
+ new_value); |
+ } |
+} |
+ |
+ |
+void HGraphBuilder::AddSimulate(BailoutId id, |
+ RemovableSimulate removable) { |
+ ASSERT(current_block() != NULL); |
+ ASSERT(no_side_effects_scope_count_ == 0); |
+ current_block()->AddSimulate(id, removable); |
+} |
+ |
+ |
HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
HBasicBlock* b = graph()->CreateBasicBlock(); |
b->SetInitialEnvironment(env); |
@@ -1044,9 +1068,7 @@ void HGraphBuilder::PadEnvironmentForContinuation( |
HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) { |
- HCheckMaps* check = HCheckMaps::New(obj, map, zone(), top_info()); |
- AddInstruction(check); |
- return check; |
+ return Add<HCheckMaps>(obj, map, top_info()); |
} |
@@ -1078,10 +1100,17 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
Token::GTE); |
capacity_checker.Then(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
- HValue* new_capacity = BuildNewElementsCapacity(context, key); |
+ HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); |
+ HValue* max_capacity = Add<HAdd>(current_capacity, max_gap); |
+ IfBuilder key_checker(this); |
+ key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); |
+ key_checker.Then(); |
+ key_checker.ElseDeopt(); |
+ key_checker.End(); |
+ HValue* new_capacity = BuildNewElementsCapacity(key); |
HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
kind, kind, length, |
new_capacity); |
@@ -1097,7 +1126,8 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
HAdd::New(zone, context, key, graph_->GetConstant1())); |
new_length->ClearFlag(HValue::kCanOverflow); |
- AddStore(object, HObjectAccess::ForArrayLength(kind), new_length); |
+ Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), |
+ new_length); |
} |
length_checker.Else(); |
@@ -1154,7 +1184,7 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object, |
HInstruction* elements = AddLoadElements(object); |
HInstruction* empty_fixed_array = Add<HConstant>( |
- isolate()->factory()->empty_fixed_array(), Representation::Tagged()); |
+ isolate()->factory()->empty_fixed_array()); |
IfBuilder if_builder(this); |
@@ -1165,7 +1195,7 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object, |
HInstruction* elements_length = AddLoadFixedArrayLength(elements); |
HInstruction* array_length = is_jsarray |
- ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL) |
+ ? Add<HLoadNamedField>(object, HObjectAccess::ForArrayLength(from_kind)) |
: elements_length; |
BuildGrowElementsCapacity(object, elements, from_kind, to_kind, |
@@ -1174,7 +1204,7 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object, |
if_builder.End(); |
} |
- AddStore(object, HObjectAccess::ForMap(), map); |
+ Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); |
} |
@@ -1189,7 +1219,6 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
LoadKeyedHoleMode load_mode, |
KeyedAccessStoreMode store_mode) { |
ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); |
- Zone* zone = this->zone(); |
// No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
// on a HElementsTransition instruction. The flag can also be removed if the |
// map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
@@ -1207,15 +1236,14 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
HValue* elements = AddLoadElements(object, mapcheck); |
if (is_store && (fast_elements || fast_smi_only_elements) && |
store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
- HCheckMaps* check_cow_map = HCheckMaps::New( |
- elements, isolate()->factory()->fixed_array_map(), zone, top_info()); |
+ HCheckMaps* check_cow_map = Add<HCheckMaps>( |
+ elements, isolate()->factory()->fixed_array_map(), top_info()); |
check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
- AddInstruction(check_cow_map); |
} |
HInstruction* length = NULL; |
if (is_js_array) { |
- length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind), |
- mapcheck); |
+ length = Add<HLoadNamedField>(object, |
+ HObjectAccess::ForArrayLength(elements_kind), mapcheck); |
} else { |
length = AddLoadFixedArrayLength(elements); |
} |
@@ -1224,8 +1252,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
if (IsExternalArrayElementsKind(elements_kind)) { |
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
NoObservableSideEffectsScope no_effects(this); |
- HLoadExternalArrayPointer* external_elements = |
- Add<HLoadExternalArrayPointer>(elements); |
+ HLoadExternalArrayPointer* external_elements = |
+ Add<HLoadExternalArrayPointer>(elements); |
IfBuilder length_checker(this); |
length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
length_checker.Then(); |
@@ -1275,11 +1303,10 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
elements = BuildCopyElementsOnWrite(object, elements, elements_kind, |
length); |
} else { |
- HCheckMaps* check_cow_map = HCheckMaps::New( |
+ HCheckMaps* check_cow_map = Add<HCheckMaps>( |
elements, isolate()->factory()->fixed_array_map(), |
- zone, top_info()); |
+ top_info()); |
check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
- AddInstruction(check_cow_map); |
} |
} |
} |
@@ -1288,37 +1315,29 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
} |
-HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
- ElementsKind kind, |
+HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, |
HValue* capacity) { |
- Zone* zone = this->zone(); |
+ int elements_size; |
+ InstanceType instance_type; |
+ |
+ if (IsFastDoubleElementsKind(kind)) { |
+ elements_size = kDoubleSize; |
+ instance_type = FIXED_DOUBLE_ARRAY_TYPE; |
+ } else { |
+ elements_size = kPointerSize; |
+ instance_type = FIXED_ARRAY_TYPE; |
+ } |
- int elements_size = IsFastDoubleElementsKind(kind) |
- ? kDoubleSize : kPointerSize; |
HConstant* elements_size_value = Add<HConstant>(elements_size); |
- HValue* mul = AddInstruction( |
- HMul::New(zone, context, capacity, elements_size_value)); |
+ HValue* mul = Add<HMul>(capacity, elements_size_value); |
mul->ClearFlag(HValue::kCanOverflow); |
HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
- HValue* total_size = AddInstruction( |
- HAdd::New(zone, context, mul, header_size)); |
+ HValue* total_size = Add<HAdd>(mul, header_size); |
total_size->ClearFlag(HValue::kCanOverflow); |
- HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
- if (isolate()->heap()->ShouldGloballyPretenure()) { |
- // TODO(hpayer): When pretenuring can be internalized, flags can become |
- // private to HAllocate. |
- if (IsFastDoubleElementsKind(kind)) { |
- flags = static_cast<HAllocate::Flags>( |
- flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
- } else { |
- flags = static_cast<HAllocate::Flags>( |
- flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
- } |
- } |
- |
- return Add<HAllocate>(context, total_size, HType::JSArray(), flags); |
+ return Add<HAllocate>(total_size, HType::JSArray(), |
+ isolate()->heap()->GetPretenureMode(), instance_type); |
} |
@@ -1331,15 +1350,18 @@ void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
: factory->fixed_array_map(); |
AddStoreMapConstant(elements, map); |
- AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity); |
+ Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), |
+ capacity); |
} |
HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
- HValue* context, |
ElementsKind kind, |
HValue* capacity) { |
- HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
+ // The HForceRepresentation is to prevent possible deopt on int-smi |
+ // conversion after allocation but before the new object fields are set. |
+ capacity = Add<HForceRepresentation>(capacity, Representation::Smi()); |
+ HValue* new_elements = BuildAllocateElements(kind, capacity); |
BuildInitializeElementsHeader(new_elements, kind, capacity); |
return new_elements; |
} |
@@ -1352,14 +1374,15 @@ HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
HValue* allocation_site_payload, |
HValue* length_field) { |
- AddStore(array, HObjectAccess::ForMap(), array_map); |
+ Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); |
HConstant* empty_fixed_array = |
- Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
+ Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
- AddStore(array, access, empty_fixed_array); |
- AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field); |
+ Add<HStoreNamedField>(array, access, empty_fixed_array); |
+ Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), |
+ length_field); |
if (mode == TRACK_ALLOCATION_SITE) { |
BuildCreateAllocationMemento(array, |
@@ -1372,10 +1395,9 @@ HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
elements_location += AllocationMemento::kSize; |
} |
- HInnerAllocatedObject* elements = |
- Add<HInnerAllocatedObject>(array, elements_location); |
- AddStore(array, HObjectAccess::ForElementsPointer(), elements); |
- return elements; |
+ HValue* elements = Add<HInnerAllocatedObject>(array, elements_location); |
+ Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); |
+ return static_cast<HInnerAllocatedObject*>(elements); |
} |
@@ -1418,8 +1440,10 @@ HInstruction* HGraphBuilder::AddExternalArrayElementAccess( |
return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind); |
} else { |
ASSERT(val == NULL); |
- HLoadKeyed* load = Add<HLoadKeyed>(external_elements, checked_key, |
- dependency, elements_kind); |
+ HLoadKeyed* load = Add<HLoadKeyed>(external_elements, |
+ checked_key, |
+ dependency, |
+ elements_kind); |
if (FLAG_opt_safe_uint32_operations && |
elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
graph()->RecordUint32Instruction(load); |
@@ -1461,31 +1485,27 @@ HInstruction* HGraphBuilder::AddFastElementAccess( |
HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, |
HValue* typecheck) { |
- return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); |
+ return Add<HLoadNamedField>(object, |
+ HObjectAccess::ForElementsPointer(), |
+ typecheck); |
} |
HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { |
- return AddLoad(object, HObjectAccess::ForFixedArrayLength()); |
+ return Add<HLoadNamedField>(object, |
+ HObjectAccess::ForFixedArrayLength()); |
} |
-HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
- HValue* old_capacity) { |
- Zone* zone = this->zone(); |
- HValue* half_old_capacity = |
- AddInstruction(HShr::New(zone, context, old_capacity, |
- graph_->GetConstant1())); |
- half_old_capacity->ClearFlag(HValue::kCanOverflow); |
+HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) { |
+ HValue* half_old_capacity = Add<HShr>(old_capacity, graph_->GetConstant1()); |
- HValue* new_capacity = AddInstruction( |
- HAdd::New(zone, context, half_old_capacity, old_capacity)); |
+ HValue* new_capacity = Add<HAdd>(half_old_capacity, old_capacity); |
new_capacity->ClearFlag(HValue::kCanOverflow); |
HValue* min_growth = Add<HConstant>(16); |
- new_capacity = AddInstruction( |
- HAdd::New(zone, context, new_capacity, min_growth)); |
+ new_capacity = Add<HAdd>(new_capacity, min_growth); |
new_capacity->ClearFlag(HValue::kCanOverflow); |
return new_capacity; |
@@ -1499,8 +1519,6 @@ void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { |
int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; |
max_size -= JSArray::kSize / element_size; |
HConstant* max_size_constant = Add<HConstant>(max_size); |
- // Since we're forcing Integer32 representation for this HBoundsCheck, |
- // there's no need to Smi-check the index. |
Add<HBoundsCheck>(length, max_size_constant); |
} |
@@ -1511,25 +1529,23 @@ HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
ElementsKind new_kind, |
HValue* length, |
HValue* new_capacity) { |
- HValue* context = environment()->LookupContext(); |
- |
BuildNewSpaceArrayCheck(new_capacity, new_kind); |
HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( |
- context, new_kind, new_capacity); |
+ new_kind, new_capacity); |
- BuildCopyElements(context, elements, kind, |
+ BuildCopyElements(elements, kind, |
new_elements, new_kind, |
length, new_capacity); |
- AddStore(object, HObjectAccess::ForElementsPointer(), new_elements); |
+ Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
+ new_elements); |
return new_elements; |
} |
-void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
- HValue* elements, |
+void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, |
ElementsKind elements_kind, |
HValue* from, |
HValue* to) { |
@@ -1571,7 +1587,7 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
Add<HStoreKeyed>(elements, key, hole, elements_kind); |
} |
} else { |
- LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
+ LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
HValue* key = builder.BeginBody(from, to, Token::LT); |
@@ -1582,8 +1598,7 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
} |
-void HGraphBuilder::BuildCopyElements(HValue* context, |
- HValue* from_elements, |
+void HGraphBuilder::BuildCopyElements(HValue* from_elements, |
ElementsKind from_elements_kind, |
HValue* to_elements, |
ElementsKind to_elements_kind, |
@@ -1597,11 +1612,11 @@ void HGraphBuilder::BuildCopyElements(HValue* context, |
// If the copy might trigger a GC, make sure that the FixedArray is |
// pre-initialized with holes to make sure that it's always in a consistent |
// state. |
- BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
+ BuildFillElementsWithHole(to_elements, to_elements_kind, |
graph()->GetConstant0(), capacity); |
} |
- LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
+ LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
@@ -1623,14 +1638,13 @@ void HGraphBuilder::BuildCopyElements(HValue* context, |
if (!pre_fill_with_holes && length != capacity) { |
// Fill unused capacity with the hole. |
- BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
+ BuildFillElementsWithHole(to_elements, to_elements_kind, |
key, capacity); |
} |
} |
-HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
- HValue* boilerplate, |
+HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate, |
HValue* allocation_site, |
AllocationSiteMode mode, |
ElementsKind kind, |
@@ -1643,26 +1657,28 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
size += AllocationMemento::kSize; |
} |
int elems_offset = size; |
+ InstanceType instance_type = IsFastDoubleElementsKind(kind) ? |
+ FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; |
if (length > 0) { |
size += IsFastDoubleElementsKind(kind) |
? FixedDoubleArray::SizeFor(length) |
: FixedArray::SizeFor(length); |
} |
- HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
// Allocate both the JS array and the elements array in one big |
// allocation. This avoids multiple limit checks. |
HValue* size_in_bytes = Add<HConstant>(size); |
- HInstruction* object = Add<HAllocate>(context, |
- size_in_bytes, |
+ HInstruction* object = Add<HAllocate>(size_in_bytes, |
HType::JSObject(), |
- allocate_flags); |
+ NOT_TENURED, |
+ instance_type); |
// Copy the JS array part. |
for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
if ((i != JSArray::kElementsOffset) || (length == 0)) { |
HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
- AddStore(object, access, AddLoad(boilerplate, access)); |
+ Add<HStoreNamedField>(object, access, |
+ Add<HLoadNamedField>(boilerplate, access)); |
} |
} |
@@ -1676,12 +1692,14 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
// elements pointer in the resulting object. |
HValue* boilerplate_elements = AddLoadElements(boilerplate); |
HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); |
- AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); |
+ Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
+ object_elements); |
// Copy the elements array header. |
for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
- AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); |
+ Add<HStoreNamedField>(object_elements, access, |
+ Add<HLoadNamedField>(boilerplate_elements, access)); |
} |
// Copy the elements array contents. |
@@ -1711,8 +1729,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp( |
UNREACHABLE(); |
case Token::SUB: { |
HInstruction* instr = |
- HMul::New(zone(), environment()->LookupContext(), |
- input, graph()->GetConstantMinus1()); |
+ NewUncasted<HMul>(input, graph()->GetConstantMinus1()); |
Representation rep = Representation::FromType(type); |
if (type->Is(Type::None())) { |
Add<HDeoptimize>(Deoptimizer::SOFT); |
@@ -1728,7 +1745,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp( |
if (type->Is(Type::None())) { |
Add<HDeoptimize>(Deoptimizer::SOFT); |
} |
- return new(zone()) HBitNot(input); |
+ return New<HBitNot>(input); |
} |
} |
@@ -1783,22 +1800,22 @@ HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object, |
isolate()->heap()->allocation_memento_map()); |
AddStoreMapConstant(alloc_memento, alloc_memento_map); |
HObjectAccess access = HObjectAccess::ForAllocationMementoSite(); |
- AddStore(alloc_memento, access, alloc_site); |
+ Add<HStoreNamedField>(alloc_memento, access, alloc_site); |
return alloc_memento; |
} |
-HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { |
+HInstruction* HGraphBuilder::BuildGetNativeContext() { |
// Get the global context, then the native context |
- HInstruction* global_object = Add<HGlobalObject>(context); |
+ HInstruction* global_object = Add<HGlobalObject>(); |
HObjectAccess access = HObjectAccess::ForJSObjectOffset( |
GlobalObject::kNativeContextOffset); |
- return AddLoad(global_object, access); |
+ return Add<HLoadNamedField>(global_object, access); |
} |
-HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { |
- HInstruction* native_context = BuildGetNativeContext(context); |
+HInstruction* HGraphBuilder::BuildGetArrayFunction() { |
+ HInstruction* native_context = BuildGetNativeContext(); |
HInstruction* index = |
Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); |
return Add<HLoadKeyed>( |
@@ -1832,7 +1849,7 @@ HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
} |
-HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
+HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { |
if (kind_ == GetInitialFastElementsKind()) { |
// No need for a context lookup if the kind_ matches the initial |
// map, because we can just load the map in that case. |
@@ -1841,7 +1858,7 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
builder()->BuildLoadNamedField(constructor_function_, access)); |
} |
- HInstruction* native_context = builder()->BuildGetNativeContext(context); |
+ HInstruction* native_context = builder()->BuildGetNativeContext(); |
HInstruction* index = builder()->Add<HConstant>( |
static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
@@ -1865,7 +1882,6 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
HValue* length_node) { |
- HValue* context = builder()->environment()->LookupContext(); |
ASSERT(length_node != NULL); |
int base_size = JSArray::kSize; |
@@ -1878,15 +1894,12 @@ HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
HInstruction* elements_size_value = |
builder()->Add<HConstant>(elements_size()); |
- HInstruction* mul = HMul::New(zone(), context, length_node, |
- elements_size_value); |
+ HInstruction* mul = builder()->Add<HMul>(length_node, elements_size_value); |
mul->ClearFlag(HValue::kCanOverflow); |
- builder()->AddInstruction(mul); |
HInstruction* base = builder()->Add<HConstant>(base_size); |
- HInstruction* total_size = HAdd::New(zone(), context, base, mul); |
+ HInstruction* total_size = builder()->Add<HAdd>(base, mul); |
total_size->ClearFlag(HValue::kCanOverflow); |
- builder()->AddInstruction(total_size); |
return total_size; |
} |
@@ -1927,19 +1940,23 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
HValue* capacity, |
HValue* length_field, |
bool fill_with_hole) { |
- HValue* context = builder()->environment()->LookupContext(); |
- |
+ // These HForceRepresentations are because we store these as fields in the |
+ // objects we construct, and an int32-to-smi HChange could deopt. Accept |
+ // the deopt possibility now, before allocation occurs. |
+ capacity = builder()->Add<HForceRepresentation>(capacity, |
+ Representation::Smi()); |
+ length_field = builder()->Add<HForceRepresentation>(length_field, |
+ Representation::Smi()); |
// Allocate (dealing with failure appropriately) |
- HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); |
- HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, |
- HType::JSArray(), flags); |
+ HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, |
+ HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); |
// Fill in the fields: map, properties, length |
HValue* map; |
if (allocation_site_payload_ == NULL) { |
map = EmitInternalMapCode(); |
} else { |
- map = EmitMapCode(context); |
+ map = EmitMapCode(); |
} |
elements_location_ = builder()->BuildJSArrayHeader(new_object, |
map, |
@@ -1952,7 +1969,7 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); |
if (fill_with_hole) { |
- builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
+ builder()->BuildFillElementsWithHole(elements_location_, kind_, |
graph()->GetConstant0(), capacity); |
} |
@@ -1960,20 +1977,6 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
} |
-HStoreNamedField* HGraphBuilder::AddStore(HValue *object, |
- HObjectAccess access, |
- HValue *val) { |
- return Add<HStoreNamedField>(object, access, val); |
-} |
- |
- |
-HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, |
- HObjectAccess access, |
- HValue *typecheck) { |
- return Add<HLoadNamedField>(object, access, typecheck); |
-} |
- |
- |
HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
Handle<Map> map) { |
return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
@@ -1981,15 +1984,14 @@ HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
} |
-HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin, |
- HValue* context) { |
- HGlobalObject* global_object = Add<HGlobalObject>(context); |
+HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { |
+ HGlobalObject* global_object = Add<HGlobalObject>(); |
HObjectAccess access = HObjectAccess::ForJSObjectOffset( |
GlobalObject::kBuiltinsOffset); |
- HValue* builtins = AddLoad(global_object, access); |
+ HValue* builtins = Add<HLoadNamedField>(global_object, access); |
HObjectAccess function_access = HObjectAccess::ForJSObjectOffset( |
JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); |
- return AddLoad(builtins, function_access); |
+ return Add<HLoadNamedField>(builtins, function_access); |
} |
@@ -2487,38 +2489,6 @@ void HGraph::CollectPhis() { |
} |
-void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { |
- if (!phi->CheckFlag(HValue::kAllowUndefinedAsNaN)) return; |
- phi->ClearFlag(HValue::kAllowUndefinedAsNaN); |
- for (int i = 0; i < phi->OperandCount(); ++i) { |
- HValue* input = phi->OperandAt(i); |
- if (input->IsPhi()) { |
- RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
- } |
- } |
-} |
- |
- |
-void HGraph::MarkDeoptimizeOnUndefined() { |
- HPhase phase("H_MarkDeoptimizeOnUndefined", this); |
- // Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use |
- // with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set. |
- // Currently only HCompareNumericAndBranch, with double input representation, |
- // has this flag set. The flag is used by HChange tagged->double, which must |
- // deoptimize if one of its uses has this flag set. |
- for (int i = 0; i < phi_list()->length(); i++) { |
- HPhi* phi = phi_list()->at(i); |
- for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
- HValue* use_value = it.value(); |
- if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { |
- RecursivelyMarkPhiDeoptimizeOnUndefined(phi); |
- break; |
- } |
- } |
- } |
-} |
- |
- |
// Implementation of utility class to encapsulate the translation state for |
// a (possibly inlined) function. |
FunctionState::FunctionState(HOptimizedGraphBuilder* owner, |
@@ -2610,7 +2580,7 @@ void ValueContext::ReturnValue(HValue* value) { |
// The value is tracked in the bailout environment, and communicated |
// through the environment as the result of the expression. |
if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { |
- owner()->Bailout("bad value context for arguments value"); |
+ owner()->Bailout(kBadValueContextForArgumentsValue); |
} |
owner()->Push(value); |
} |
@@ -2662,7 +2632,7 @@ void EffectContext::ReturnContinuation(HIfContinuation* continuation, |
void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
ASSERT(!instr->IsControlInstruction()); |
if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
- return owner()->Bailout("bad value context for arguments object value"); |
+ return owner()->Bailout(kBadValueContextForArgumentsObjectValue); |
} |
owner()->AddInstruction(instr); |
owner()->Push(instr); |
@@ -2675,7 +2645,7 @@ void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { |
ASSERT(!instr->HasObservableSideEffects()); |
if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
- return owner()->Bailout("bad value context for arguments object value"); |
+ return owner()->Bailout(kBadValueContextForArgumentsObjectValue); |
} |
HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); |
HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); |
@@ -2765,7 +2735,7 @@ void TestContext::BuildBranch(HValue* value) { |
// branch. |
HOptimizedGraphBuilder* builder = owner(); |
if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { |
- builder->Bailout("arguments object value in a test context"); |
+ builder->Bailout(kArgumentsObjectValueInATestContext); |
} |
if (value->IsConstant()) { |
HConstant* constant_value = HConstant::cast(value); |
@@ -2811,7 +2781,7 @@ void TestContext::BuildBranch(HValue* value) { |
} while (false) |
-void HOptimizedGraphBuilder::Bailout(const char* reason) { |
+void HOptimizedGraphBuilder::Bailout(BailoutReason reason) { |
current_info()->set_bailout_reason(reason); |
SetStackOverflow(); |
} |
@@ -2870,16 +2840,16 @@ void HOptimizedGraphBuilder::VisitExpressions( |
bool HOptimizedGraphBuilder::BuildGraph() { |
if (current_info()->function()->is_generator()) { |
- Bailout("function is a generator"); |
+ Bailout(kFunctionIsAGenerator); |
return false; |
} |
Scope* scope = current_info()->scope(); |
if (scope->HasIllegalRedeclaration()) { |
- Bailout("function with illegal redeclaration"); |
+ Bailout(kFunctionWithIllegalRedeclaration); |
return false; |
} |
if (scope->calls_eval()) { |
- Bailout("function calls eval"); |
+ Bailout(kFunctionCallsEval); |
return false; |
} |
SetUpScope(scope); |
@@ -2913,7 +2883,7 @@ bool HOptimizedGraphBuilder::BuildGraph() { |
VisitDeclarations(scope->declarations()); |
Add<HSimulate>(BailoutId::Declarations()); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
Add<HStackCheck>(context, HStackCheck::kFunctionEntry); |
VisitStatements(current_info()->function()->body()); |
@@ -2945,8 +2915,7 @@ bool HOptimizedGraphBuilder::BuildGraph() { |
} |
-bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
- *bailout_reason = SmartArrayPointer<char>(); |
+bool HGraph::Optimize(BailoutReason* bailout_reason) { |
OrderBlocks(); |
AssignDominators(); |
@@ -2967,14 +2936,12 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
Run<HPropagateDeoptimizingMarkPhase>(); |
if (!CheckConstPhiUses()) { |
- *bailout_reason = SmartArrayPointer<char>(StrDup( |
- "Unsupported phi use of const variable")); |
+ *bailout_reason = kUnsupportedPhiUseOfConstVariable; |
return false; |
} |
Run<HRedundantPhiEliminationPhase>(); |
if (!CheckArgumentsPhiUses()) { |
- *bailout_reason = SmartArrayPointer<char>(StrDup( |
- "Unsupported phi use of arguments")); |
+ *bailout_reason = kUnsupportedPhiUseOfArguments; |
return false; |
} |
@@ -2991,7 +2958,7 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
// This must happen after inferring representations. |
Run<HMergeRemovableSimulatesPhase>(); |
- MarkDeoptimizeOnUndefined(); |
+ Run<HMarkDeoptimizeOnUndefinedPhase>(); |
Run<HRepresentationChangesPhase>(); |
Run<HInferTypesPhase>(); |
@@ -3124,15 +3091,19 @@ HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
- HConstant* undefined_constant = Add<HConstant>( |
- isolate()->factory()->undefined_value()); |
+ // First special is HContext. |
+ HInstruction* context = Add<HContext>(); |
+ environment()->BindContext(context); |
+ |
+ HConstant* undefined_constant = HConstant::cast(Add<HConstant>( |
+ isolate()->factory()->undefined_value())); |
graph()->set_undefined_constant(undefined_constant); |
// Create an arguments object containing the initial parameters. Set the |
// initial values of parameters including "this" having parameter index 0. |
ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
HArgumentsObject* arguments_object = |
- new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); |
+ New<HArgumentsObject>(environment()->parameter_count()); |
for (int i = 0; i < environment()->parameter_count(); ++i) { |
HInstruction* parameter = Add<HParameter>(i); |
arguments_object->AddArgument(parameter, zone()); |
@@ -3141,10 +3112,6 @@ void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
AddInstruction(arguments_object); |
graph()->SetArgumentsObject(arguments_object); |
- // First special is HContext. |
- HInstruction* context = Add<HContext>(); |
- environment()->BindContext(context); |
- |
// Initialize specials and locals to undefined. |
for (int i = environment()->parameter_count() + 1; |
i < environment()->length(); |
@@ -3156,7 +3123,7 @@ void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
// not have declarations). |
if (scope->arguments() != NULL) { |
if (!scope->arguments()->IsStackAllocated()) { |
- return Bailout("context-allocated arguments"); |
+ return Bailout(kContextAllocatedArguments); |
} |
environment()->Bind(scope->arguments(), |
@@ -3177,7 +3144,7 @@ void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
if (stmt->scope() != NULL) { |
- return Bailout("ScopedBlock"); |
+ return Bailout(kScopedBlock); |
} |
BreakAndContinueInfo break_info(stmt); |
{ BreakAndContinueScope push(&break_info, this); |
@@ -3389,7 +3356,7 @@ void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- return Bailout("WithStatement"); |
+ return Bailout(kWithStatement); |
} |
@@ -3404,15 +3371,15 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { |
ZoneList<CaseClause*>* clauses = stmt->cases(); |
int clause_count = clauses->length(); |
if (clause_count > kCaseClauseLimit) { |
- return Bailout("SwitchStatement: too many clauses"); |
+ return Bailout(kSwitchStatementTooManyClauses); |
} |
ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); |
if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { |
- return Bailout("SwitchStatement: mixed or non-literal switch labels"); |
+ return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels); |
} |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
CHECK_ALIVE(VisitForValue(stmt->tag())); |
Add<HSimulate>(stmt->EntryId()); |
@@ -3560,9 +3527,9 @@ void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
BreakAndContinueInfo* break_info) { |
BreakAndContinueScope push(break_info, this); |
Add<HSimulate>(stmt->StackCheckId()); |
- HValue* context = environment()->LookupContext(); |
- HStackCheck* stack_check = Add<HStackCheck>( |
- context, HStackCheck::kBackwardsBranch); |
+ HValue* context = environment()->context(); |
+ HStackCheck* stack_check = HStackCheck::cast(Add<HStackCheck>( |
+ context, HStackCheck::kBackwardsBranch)); |
ASSERT(loop_entry->IsLoopHeader()); |
loop_entry->loop_information()->set_stack_check(stack_check); |
CHECK_BAILOUT(Visit(stmt->body())); |
@@ -3701,16 +3668,16 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
ASSERT(current_block()->HasPredecessor()); |
if (!FLAG_optimize_for_in) { |
- return Bailout("ForInStatement optimization is disabled"); |
+ return Bailout(kForInStatementOptimizationIsDisabled); |
} |
if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) { |
- return Bailout("ForInStatement is not fast case"); |
+ return Bailout(kForInStatementIsNotFastCase); |
} |
if (!stmt->each()->IsVariableProxy() || |
!stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { |
- return Bailout("ForInStatement with non-local each variable"); |
+ return Bailout(kForInStatementWithNonLocalEachVariable); |
} |
Variable* each_var = stmt->each()->AsVariableProxy()->var(); |
@@ -3718,8 +3685,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
CHECK_ALIVE(VisitForValue(stmt->enumerable())); |
HValue* enumerable = Top(); // Leave enumerable at the top. |
- HInstruction* map = Add<HForInPrepareMap>( |
- environment()->LookupContext(), enumerable); |
+ HInstruction* map = Add<HForInPrepareMap>(enumerable); |
Add<HSimulate>(stmt->PrepareId()); |
HInstruction* array = Add<HForInCacheArray>( |
@@ -3785,9 +3751,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
set_current_block(body_exit); |
HValue* current_index = Pop(); |
- HInstruction* new_index = HAdd::New(zone(), |
- environment()->LookupContext(), |
- current_index, |
+ HInstruction* new_index = New<HAdd>(current_index, |
graph()->GetConstant1()); |
PushAndAdd(new_index); |
body_exit = current_block(); |
@@ -3807,7 +3771,7 @@ void HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- return Bailout("ForOfStatement"); |
+ return Bailout(kForOfStatement); |
} |
@@ -3815,7 +3779,7 @@ void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- return Bailout("TryCatchStatement"); |
+ return Bailout(kTryCatchStatement); |
} |
@@ -3824,7 +3788,7 @@ void HOptimizedGraphBuilder::VisitTryFinallyStatement( |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- return Bailout("TryFinallyStatement"); |
+ return Bailout(kTryFinallyStatement); |
} |
@@ -3832,7 +3796,7 @@ void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- return Bailout("DebuggerStatement"); |
+ return Bailout(kDebuggerStatement); |
} |
@@ -3866,7 +3830,7 @@ void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
} |
// We also have a stack overflow if the recursive compilation did. |
if (HasStackOverflow()) return; |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HFunctionLiteral* instr = |
new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
return ast_context()->ReturnInstruction(instr, expr->id()); |
@@ -3878,7 +3842,7 @@ void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- return Bailout("SharedFunctionInfoLiteral"); |
+ return Bailout(kSharedFunctionInfoLiteral); |
} |
@@ -3940,7 +3904,7 @@ HOptimizedGraphBuilder::GlobalPropertyAccess |
HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
ASSERT(var->IsContextSlot()); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
int length = current_info()->scope()->ContextChainLength(var->scope()); |
while (length-- > 0) { |
context = Add<HOuterContext>(context); |
@@ -3958,14 +3922,14 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
case Variable::UNALLOCATED: { |
if (IsLexicalVariableMode(variable->mode())) { |
// TODO(rossberg): should this be an ASSERT? |
- return Bailout("reference to global lexical variable"); |
+ return Bailout(kReferenceToGlobalLexicalVariable); |
} |
// Handle known global constants like 'undefined' specially to avoid a |
// load from a global cell for them. |
Handle<Object> constant_value = |
isolate()->factory()->GlobalConstantFor(variable->name()); |
if (!constant_value.is_null()) { |
- HConstant* instr = new(zone()) HConstant(constant_value); |
+ HConstant* instr = New<HConstant>(constant_value); |
return ast_context()->ReturnInstruction(instr, expr->id()); |
} |
@@ -3988,7 +3952,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
constant_object = |
FlattenGetString(Handle<String>::cast(constant_object)); |
} |
- HConstant* constant = new(zone()) HConstant(constant_object); |
+ HConstant* constant = New<HConstant>(constant_object); |
return ast_context()->ReturnInstruction(constant, expr->id()); |
} else { |
HLoadGlobalCell* instr = |
@@ -3996,7 +3960,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
return ast_context()->ReturnInstruction(instr, expr->id()); |
} |
} else { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
AddInstruction(global_object); |
HLoadGlobalGeneric* instr = |
@@ -4015,7 +3979,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
if (value == graph()->GetConstantHole()) { |
ASSERT(IsDeclaredVariableMode(variable->mode()) && |
variable->mode() != VAR); |
- return Bailout("reference to uninitialized variable"); |
+ return Bailout(kReferenceToUninitializedVariable); |
} |
return ast_context()->ReturnValue(value); |
} |
@@ -4027,7 +3991,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
} |
case Variable::LOOKUP: |
- return Bailout("reference to a variable which requires dynamic lookup"); |
+ return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); |
} |
} |
@@ -4036,7 +4000,7 @@ void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
- HConstant* instr = new(zone()) HConstant(expr->value()); |
+ HConstant* instr = New<HConstant>(expr->value()); |
return ast_context()->ReturnInstruction(instr, expr->id()); |
} |
@@ -4047,7 +4011,7 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
ASSERT(current_block()->HasPredecessor()); |
Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
Handle<FixedArray> literals(closure->literals()); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, |
literals, |
@@ -4224,7 +4188,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* literal; |
// Check whether to use fast or slow deep-copying for boilerplate. |
@@ -4269,8 +4233,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
Runtime::FunctionId function_id = |
(expr->depth() > 1 || expr->may_store_doubles()) |
? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; |
- literal = Add<HCallRuntime>(context, |
- isolate()->factory()->empty_string(), |
+ literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
Runtime::FunctionForId(function_id), |
4); |
} |
@@ -4327,7 +4290,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
case ObjectLiteral::Property::PROTOTYPE: |
case ObjectLiteral::Property::SETTER: |
case ObjectLiteral::Property::GETTER: |
- return Bailout("Object literal with complex property"); |
+ return Bailout(kObjectLiteralWithComplexProperty); |
default: UNREACHABLE(); |
} |
} |
@@ -4352,7 +4315,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
ASSERT(current_block()->HasPredecessor()); |
ZoneList<Expression*>* subexprs = expr->values(); |
int length = subexprs->length(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* literal; |
Handle<AllocationSite> site; |
@@ -4366,7 +4329,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
isolate(), literals, expr->constant_elements()); |
if (raw_boilerplate.is_null()) { |
- return Bailout("array boilerplate creation failed"); |
+ return Bailout(kArrayBoilerplateCreationFailed); |
} |
site = isolate()->factory()->NewAllocationSite(); |
@@ -4431,15 +4394,14 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
Runtime::FunctionId function_id = (expr->depth() > 1) |
? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
- literal = Add<HCallRuntime>(context, |
- isolate()->factory()->empty_string(), |
+ literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
Runtime::FunctionForId(function_id), |
3); |
// De-opt if elements kind changed from boilerplate_elements_kind. |
Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), |
isolate()); |
- AddInstruction(HCheckMaps::New(literal, map, zone(), top_info())); |
+ Add<HCheckMaps>(literal, map, top_info()); |
} |
// The array is expected in the bailout environment during computation |
@@ -4458,7 +4420,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
CHECK_ALIVE(VisitForValue(subexpr)); |
HValue* value = Pop(); |
- if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
+ if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral); |
elements = AddLoadElements(literal); |
@@ -4516,15 +4478,7 @@ static bool ComputeLoadStoreField(Handle<Map> type, |
void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
BuildCheckHeapObject(object); |
- AddInstruction(HCheckMaps::New(object, map, zone(), top_info())); |
-} |
- |
- |
-void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
- Handle<Map> map) { |
- BuildCheckHeapObject(object); |
- AddInstruction(HCheckMaps::NewWithTransitions( |
- object, map, zone(), top_info())); |
+ Add<HCheckMaps>(object, map, top_info()); |
} |
@@ -4546,7 +4500,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
if (proto_result.IsProperty()) { |
// If the inherited property could induce readonly-ness, bail out. |
if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) { |
- Bailout("improper object on prototype chain for store"); |
+ Bailout(kImproperObjectOnPrototypeChainForStore); |
return NULL; |
} |
// We only need to check up to the preexisting property. |
@@ -4559,9 +4513,9 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
ASSERT(proto->GetPrototype(isolate())->IsNull()); |
} |
ASSERT(proto->IsJSObject()); |
- Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), |
- Handle<JSObject>(JSObject::cast(proto)), |
- zone(), top_info()); |
+ Add<HCheckPrototypeMaps>( |
+ Handle<JSObject>(JSObject::cast(map->prototype())), |
+ Handle<JSObject>(JSObject::cast(proto)), top_info()); |
} |
HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
@@ -4575,23 +4529,26 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
// The store requires a mutable HeapNumber to be allocated. |
NoObservableSideEffectsScope no_side_effects(this); |
HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
- HInstruction* heap_number = Add<HAllocate>( |
- environment()->LookupContext(), heap_number_size, |
- HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); |
+ HInstruction* heap_number = Add<HAllocate>(heap_number_size, |
+ HType::HeapNumber(), isolate()->heap()->GetPretenureMode(), |
+ HEAP_NUMBER_TYPE); |
AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); |
- AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value); |
- instr = new(zone()) HStoreNamedField( |
- object, heap_number_access, heap_number); |
+ Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
+ value); |
+ instr = New<HStoreNamedField>(object, heap_number_access, |
+ heap_number); |
} else { |
// Already holds a HeapNumber; load the box and write its value field. |
- HInstruction* heap_number = AddLoad(object, heap_number_access); |
+ HInstruction* heap_number = Add<HLoadNamedField>(object, |
+ heap_number_access); |
heap_number->set_type(HType::HeapNumber()); |
- instr = new(zone()) HStoreNamedField(heap_number, |
- HObjectAccess::ForHeapNumberValue(), value); |
+ instr = New<HStoreNamedField>(heap_number, |
+ HObjectAccess::ForHeapNumberValue(), |
+ value); |
} |
} else { |
// This is a normal store. |
- instr = new(zone()) HStoreNamedField(object, field_access, value); |
+ instr = New<HStoreNamedField>(object, field_access, value); |
} |
if (transition_to_field) { |
@@ -4609,7 +4566,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( |
HValue* object, |
Handle<String> name, |
HValue* value) { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
return new(zone()) HStoreNamedGeneric( |
context, |
object, |
@@ -4627,7 +4584,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( |
// Handle a store to a known field. |
LookupResult lookup(isolate()); |
if (ComputeLoadStoreField(map, name, &lookup, true)) { |
- AddCheckMapsWithTransitions(object, map); |
+ AddCheckMap(object, map); |
return BuildStoreNamedField(object, name, value, map, &lookup); |
} |
@@ -4686,7 +4643,7 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( |
if (count == types->length()) { |
// Everything matched; can use monomorphic load. |
BuildCheckHeapObject(object); |
- AddInstruction(HCheckMaps::New(object, types, zone())); |
+ Add<HCheckMaps>(object, types); |
return BuildLoadNamedField(object, access); |
} |
@@ -4708,13 +4665,13 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( |
if (!lookup.IsField()) return NULL; |
BuildCheckHeapObject(object); |
- AddInstruction(HCheckMaps::New(object, types, zone())); |
+ Add<HCheckMaps>(object, types); |
Handle<JSObject> holder(lookup.holder()); |
Handle<Map> holder_map(holder->map()); |
- AddInstruction(new(zone()) HCheckPrototypeMaps( |
- Handle<JSObject>::cast(prototype), holder, zone(), top_info())); |
- HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); |
+ Add<HCheckPrototypeMaps>( |
+ Handle<JSObject>::cast(prototype), holder, top_info()); |
+ HValue* holder_value = Add<HConstant>(holder); |
return BuildLoadNamedField(holder_value, |
HObjectAccess::ForField(holder_map, &lookup, name)); |
} |
@@ -4730,7 +4687,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
if (instr == NULL) { |
// Something did not match; must use a polymorphic load. |
BuildCheckHeapObject(object); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
instr = new(zone()) HLoadNamedFieldPolymorphic( |
context, object, types, name, zone()); |
} |
@@ -4787,7 +4744,7 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( |
// Everything matched; can use monomorphic store. |
BuildCheckHeapObject(object); |
- AddInstruction(HCheckMaps::New(object, types, zone())); |
+ Add<HCheckMaps>(object, types); |
HInstruction* store; |
CHECK_ALIVE_OR_RETURN( |
store = BuildStoreNamedField( |
@@ -4959,10 +4916,9 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
} |
} else { |
- HValue* context = environment()->LookupContext(); |
- HGlobalObject* global_object = Add<HGlobalObject>(context); |
+ HGlobalObject* global_object = Add<HGlobalObject>(); |
HStoreGlobalGeneric* instr = |
- Add<HStoreGlobalGeneric>(context, global_object, var->name(), |
+ Add<HStoreGlobalGeneric>(global_object, var->name(), |
value, function_strict_mode_flag()); |
instr->set_position(position); |
ASSERT(instr->HasObservableSideEffects()); |
@@ -5048,7 +5004,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
if (proxy != NULL) { |
Variable* var = proxy->var(); |
if (var->mode() == LET) { |
- return Bailout("unsupported let compound assignment"); |
+ return Bailout(kUnsupportedLetCompoundAssignment); |
} |
CHECK_ALIVE(VisitForValue(operation)); |
@@ -5064,7 +5020,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
case Variable::PARAMETER: |
case Variable::LOCAL: |
if (var->mode() == CONST) { |
- return Bailout("unsupported const compound assignment"); |
+ return Bailout(kUnsupportedConstCompoundAssignment); |
} |
BindIfLive(var, Top()); |
break; |
@@ -5080,8 +5036,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
int count = current_info()->scope()->num_parameters(); |
for (int i = 0; i < count; ++i) { |
if (var == current_info()->scope()->parameter(i)) { |
- Bailout( |
- "assignment to parameter, function uses arguments object"); |
+ Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); |
} |
} |
} |
@@ -5103,8 +5058,8 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
} |
HValue* context = BuildContextChainWalk(var); |
- HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
- mode, Top()); |
+ HStoreContextSlot* instr = Add<HStoreContextSlot>( |
+ context, var->index(), mode, Top()); |
if (instr->HasObservableSideEffects()) { |
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
} |
@@ -5112,7 +5067,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
} |
case Variable::LOOKUP: |
- return Bailout("compound assignment to lookup slot"); |
+ return Bailout(kCompoundAssignmentToLookupSlot); |
} |
return ast_context()->ReturnValue(Pop()); |
@@ -5201,7 +5156,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
} |
} else { |
- return Bailout("invalid lhs in compound assignment"); |
+ return Bailout(kInvalidLhsInCompoundAssignment); |
} |
} |
@@ -5238,11 +5193,11 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
} |
} else if (var->mode() == CONST_HARMONY) { |
if (expr->op() != Token::INIT_CONST_HARMONY) { |
- return Bailout("non-initializer assignment to const"); |
+ return Bailout(kNonInitializerAssignmentToConst); |
} |
} |
- if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
+ if (proxy->IsArguments()) return Bailout(kAssignmentToArguments); |
// Handle the assignment. |
switch (var->location()) { |
@@ -5261,7 +5216,7 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
if (var->mode() == LET && expr->op() == Token::ASSIGN) { |
HValue* env_value = environment()->Lookup(var); |
if (env_value == graph()->GetConstantHole()) { |
- return Bailout("assignment to let variable before initialization"); |
+ return Bailout(kAssignmentToLetVariableBeforeInitialization); |
} |
} |
// We do not allow the arguments object to occur in a context where it |
@@ -5283,7 +5238,7 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
int count = current_info()->scope()->num_parameters(); |
for (int i = 0; i < count; ++i) { |
if (var == current_info()->scope()->parameter(i)) { |
- return Bailout("assignment to parameter in arguments object"); |
+ return Bailout(kAssignmentToParameterInArgumentsObject); |
} |
} |
} |
@@ -5315,8 +5270,8 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
} |
HValue* context = BuildContextChainWalk(var); |
- HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
- mode, Top()); |
+ HStoreContextSlot* instr = Add<HStoreContextSlot>( |
+ context, var->index(), mode, Top()); |
if (instr->HasObservableSideEffects()) { |
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
} |
@@ -5324,10 +5279,10 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
} |
case Variable::LOOKUP: |
- return Bailout("assignment to LOOKUP variable"); |
+ return Bailout(kAssignmentToLOOKUPVariable); |
} |
} else { |
- return Bailout("invalid left-hand side in assignment"); |
+ return Bailout(kInvalidLeftHandSideInAssignment); |
} |
} |
@@ -5348,9 +5303,8 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { |
ASSERT(ast_context()->IsEffect()); |
CHECK_ALIVE(VisitForValue(expr->exception())); |
- HValue* context = environment()->LookupContext(); |
HValue* value = environment()->Pop(); |
- HThrow* instr = Add<HThrow>(context, value); |
+ HThrow* instr = Add<HThrow>(value); |
instr->set_position(expr->position()); |
Add<HSimulate>(expr->id()); |
current_block()->FinishExit(new(zone()) HAbnormalExit); |
@@ -5359,17 +5313,32 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { |
HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
- HObjectAccess access) { |
+ HObjectAccess access, |
+ HValue* typecheck) { |
if (FLAG_track_double_fields && access.representation().IsDouble()) { |
// load the heap number |
- HLoadNamedField* heap_number = |
- AddLoad(object, access.WithRepresentation(Representation::Tagged())); |
+ HLoadNamedField* heap_number = Add<HLoadNamedField>( |
+ object, access.WithRepresentation(Representation::Tagged())); |
heap_number->set_type(HType::HeapNumber()); |
// load the double value from it |
- return new(zone()) HLoadNamedField(heap_number, |
- HObjectAccess::ForHeapNumberValue(), NULL); |
+ return New<HLoadNamedField>(heap_number, |
+ HObjectAccess::ForHeapNumberValue(), |
+ typecheck); |
+ } |
+ return New<HLoadNamedField>(object, access, typecheck); |
+} |
+ |
+ |
+HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object, |
+ HValue* typecheck) { |
+ if (FLAG_fold_constants && object->IsConstant()) { |
+ HConstant* constant = HConstant::cast(object); |
+ if (constant->HasStringValue()) { |
+ return New<HConstant>(constant->StringValue()->length()); |
+ } |
} |
- return new(zone()) HLoadNamedField(object, access, NULL); |
+ return BuildLoadNamedField( |
+ object, HObjectAccess::ForStringLength(), typecheck); |
} |
@@ -5380,7 +5349,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
if (expr->IsUninitialized()) { |
Add<HDeoptimize>(Deoptimizer::SOFT); |
} |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
return new(zone()) HLoadNamedGeneric(context, object, name); |
} |
@@ -5407,8 +5376,8 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
// Handle access to various length properties |
if (name->Equals(isolate()->heap()->length_string())) { |
if (map->instance_type() == JS_ARRAY_TYPE) { |
- AddCheckMapsWithTransitions(object, map); |
- return new(zone()) HLoadNamedField(object, |
+ AddCheckMap(object, map); |
+ return New<HLoadNamedField>(object, |
HObjectAccess::ForArrayLength(map->elements_kind())); |
} |
} |
@@ -5425,7 +5394,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
if (lookup.IsConstant()) { |
AddCheckMap(object, map); |
Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); |
- return new(zone()) HConstant(constant); |
+ return New<HConstant>(constant); |
} |
// Handle a load from a known field somewhere in the prototype chain. |
@@ -5435,7 +5404,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
Handle<JSObject> holder(lookup.holder()); |
Handle<Map> holder_map(holder->map()); |
AddCheckMap(object, map); |
- Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
+ Add<HCheckPrototypeMaps>(prototype, holder, top_info()); |
HValue* holder_value = Add<HConstant>(holder); |
return BuildLoadNamedField(holder_value, |
HObjectAccess::ForField(holder_map, &lookup, name)); |
@@ -5447,9 +5416,9 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
Handle<JSObject> holder(lookup.holder()); |
Handle<Map> holder_map(holder->map()); |
AddCheckMap(object, map); |
- Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
+ Add<HCheckPrototypeMaps>(prototype, holder, top_info()); |
Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate()); |
- return new(zone()) HConstant(constant); |
+ return New<HConstant>(constant); |
} |
// No luck, do a generic load. |
@@ -5459,7 +5428,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
HValue* key) { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
return new(zone()) HLoadKeyedGeneric(context, object, key); |
} |
@@ -5472,9 +5441,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( |
Handle<Map> map, |
bool is_store, |
KeyedAccessStoreMode store_mode) { |
- HCheckMaps* mapcheck = HCheckMaps::New( |
- object, map, zone(), top_info(), dependency); |
- AddInstruction(mapcheck); |
+ HCheckMaps* mapcheck = Add<HCheckMaps>(object, map, top_info(), dependency); |
if (dependency) { |
mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
} |
@@ -5485,7 +5452,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( |
isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
- Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); |
+ Add<HCheckPrototypeMaps>(prototype, object_prototype, top_info()); |
load_mode = ALLOW_RETURN_HOLE; |
graph()->MarkDependsOnEmptyArrayProtoElements(); |
} |
@@ -5542,8 +5509,7 @@ HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
} |
if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
- HCheckMaps* check_maps = HCheckMaps::New(object, maps, zone()); |
- AddInstruction(check_maps); |
+ HCheckMaps* check_maps = Add<HCheckMaps>(object, maps); |
HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
object, key, val, check_maps, |
most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
@@ -5608,8 +5574,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
ASSERT(Map::IsValidElementsTransition( |
map->elements_kind(), |
transition_target.at(i)->elements_kind())); |
- HValue* context = environment()->LookupContext(); |
- transition = Add<HTransitionElementsKind>(context, object, map, |
+ transition = Add<HTransitionElementsKind>(object, map, |
transition_target.at(i)); |
} else { |
untransitionable_maps.Add(map); |
@@ -5655,12 +5620,12 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
HInstruction* access = NULL; |
if (IsFastElementsKind(elements_kind)) { |
if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
- AddInstruction(HCheckMaps::New( |
+ Add<HCheckMaps>( |
elements, isolate()->factory()->fixed_array_map(), |
- zone(), top_info(), mapcompare)); |
+ top_info(), mapcompare); |
} |
if (map->instance_type() == JS_ARRAY_TYPE) { |
- HInstruction* length = AddLoad( |
+ HInstruction* length = Add<HLoadNamedField>( |
object, HObjectAccess::ForArrayLength(elements_kind), mapcompare); |
checked_key = Add<HBoundsCheck>(key, length); |
} else { |
@@ -5756,7 +5721,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( |
HValue* object, |
HValue* key, |
HValue* value) { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
return new(zone()) HStoreKeyedGeneric( |
context, |
object, |
@@ -5782,13 +5747,12 @@ void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { |
HInstruction* insert_after = entry; |
for (int i = 0; i < arguments_values->length(); i++) { |
HValue* argument = arguments_values->at(i); |
- HInstruction* push_argument = new(zone()) HPushArgument(argument); |
+ HInstruction* push_argument = New<HPushArgument>(argument); |
push_argument->InsertAfter(insert_after); |
insert_after = push_argument; |
} |
- HArgumentsElements* arguments_elements = |
- new(zone()) HArgumentsElements(true); |
+ HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); |
arguments_elements->ClearFlag(HValue::kUseGVN); |
arguments_elements->InsertAfter(insert_after); |
function_state()->set_arguments_elements(arguments_elements); |
@@ -5810,12 +5774,12 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
if (function_state()->outer() == NULL) { |
HInstruction* elements = Add<HArgumentsElements>(false); |
- result = new(zone()) HArgumentsLength(elements); |
+ result = New<HArgumentsLength>(elements); |
} else { |
// Number of arguments without receiver. |
int argument_count = environment()-> |
arguments_environment()->parameter_count() - 1; |
- result = new(zone()) HConstant(argument_count); |
+ result = New<HConstant>(argument_count); |
} |
} else { |
Push(graph()->GetArgumentsObject()); |
@@ -5858,15 +5822,16 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
if (expr->IsStringLength()) { |
HValue* string = Pop(); |
BuildCheckHeapObject(string); |
- AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
- instr = HStringLength::New(zone(), string); |
+ HInstruction* checkstring = |
+ AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
+ instr = BuildLoadStringLength(string, checkstring); |
} else if (expr->IsStringAccess()) { |
CHECK_ALIVE(VisitForValue(expr->key())); |
HValue* index = Pop(); |
HValue* string = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* char_code = |
- BuildStringCharCodeAt(context, string, index); |
+ BuildStringCharCodeAt(string, index); |
AddInstruction(char_code); |
instr = HStringCharFromCode::New(zone(), context, char_code); |
@@ -5937,7 +5902,7 @@ void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
Handle<Map> receiver_map) { |
if (!holder.is_null()) { |
Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
- Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
+ Add<HCheckPrototypeMaps>(prototype, holder, top_info()); |
} |
} |
@@ -5949,7 +5914,7 @@ void HOptimizedGraphBuilder::AddCheckConstantFunction( |
// Constant functions have the nice property that the map will change if they |
// are overwritten. Therefore it is enough to check the map of the holder and |
// its prototypes. |
- AddCheckMapsWithTransitions(receiver, receiver_map); |
+ AddCheckMap(receiver, receiver_map); |
AddCheckPrototypeMaps(holder, receiver_map); |
} |
@@ -6006,7 +5971,7 @@ bool HOptimizedGraphBuilder::TryCallPolymorphicAsMonomorphic( |
if (!expr->ComputeTarget(map, name)) return false; |
BuildCheckHeapObject(receiver); |
- AddInstruction(HCheckMaps::New(receiver, types, zone())); |
+ Add<HCheckMaps>(receiver, types); |
AddCheckPrototypeMaps(expr->holder(), map); |
if (FLAG_trace_inlining) { |
Handle<JSFunction> caller = current_info()->closure(); |
@@ -6162,7 +6127,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( |
Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1)); |
FinishExitWithHardDeoptimization(join); |
} else { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); |
call->set_position(expr->position()); |
PreProcessCall(call); |
@@ -6309,7 +6274,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
if (target_info.isolate()->has_pending_exception()) { |
// Parse or scope error, never optimize this function. |
SetStackOverflow(); |
- target_shared->DisableOptimization("parse/scope error"); |
+ target_shared->DisableOptimization(kParseScopeError); |
} |
TraceInline(target, caller, "parse failure"); |
return false; |
@@ -6428,7 +6393,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
ASSERT(function->scope()->arguments()->IsStackAllocated()); |
HEnvironment* arguments_env = inner_env->arguments_environment(); |
int arguments_count = arguments_env->parameter_count(); |
- arguments_object = Add<HArgumentsObject>(arguments_count, zone()); |
+ arguments_object = Add<HArgumentsObject>(arguments_count); |
inner_env->Bind(function->scope()->arguments(), arguments_object); |
for (int i = 0; i < arguments_count; i++) { |
arguments_object->AddArgument(arguments_env->Lookup(i), zone()); |
@@ -6439,7 +6404,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
Add<HEnterInlined>(target, arguments_count, function, |
function_state()->inlining_kind(), |
function->scope()->arguments(), |
- arguments_object, undefined_receiver, zone()); |
+ arguments_object, undefined_receiver); |
function_state()->set_entry(enter_inlined); |
VisitDeclarations(target_info.scope()->declarations()); |
@@ -6448,7 +6413,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
// Bail out if the inline function did, as we cannot residualize a call |
// instead. |
TraceInline(target, caller, "inline graph construction failed"); |
- target_shared->DisableOptimization("inlining bailed out"); |
+ target_shared->DisableOptimization(kInliningBailedOut); |
inline_bailout_ = true; |
delete target_state; |
return true; |
@@ -6630,7 +6595,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, |
case kMathTan: |
if (expr->arguments()->length() == 1) { |
HValue* argument = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
Drop(1); // Receiver. |
HInstruction* op = |
HUnaryMathOperation::New(zone(), context, argument, id); |
@@ -6645,7 +6610,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, |
HValue* right = Pop(); |
HValue* left = Pop(); |
Drop(1); // Receiver. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* op = HMul::NewImul(zone(), context, left, right); |
if (drop_extra) Drop(1); // Optionally drop the function. |
ast_context()->ReturnInstruction(op, expr->id()); |
@@ -6676,13 +6641,13 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
if (argument_count == 2 && check_type == STRING_CHECK) { |
HValue* index = Pop(); |
HValue* string = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
ASSERT(!expr->holder().is_null()); |
Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck( |
STRING_CHECK, expr->holder()->GetIsolate()), |
- expr->holder(), zone(), top_info()); |
+ expr->holder(), top_info()); |
HInstruction* char_code = |
- BuildStringCharCodeAt(context, string, index); |
+ BuildStringCharCodeAt(string, index); |
if (id == kStringCharCodeAt) { |
ast_context()->ReturnInstruction(char_code, expr->id()); |
return true; |
@@ -6698,7 +6663,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
HValue* argument = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
Drop(1); // Receiver. |
HInstruction* result = |
HStringCharFromCode::New(zone(), context, argument); |
@@ -6720,7 +6685,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
HValue* argument = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
Drop(1); // Receiver. |
HInstruction* op = |
HUnaryMathOperation::New(zone(), context, argument, id); |
@@ -6735,7 +6700,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
HValue* right = Pop(); |
HValue* left = Pop(); |
Pop(); // Pop receiver. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* result = NULL; |
// Use sqrt() if exponent is 0.5 or -0.5. |
if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
@@ -6760,7 +6725,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
} |
if (result == NULL) { |
- result = HPower::New(zone(), left, right); |
+ result = HPower::New(zone(), context, left, right); |
} |
ast_context()->ReturnInstruction(result, expr->id()); |
return true; |
@@ -6770,8 +6735,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
Drop(1); // Receiver. |
- HValue* context = environment()->LookupContext(); |
- HGlobalObject* global_object = Add<HGlobalObject>(context); |
+ HGlobalObject* global_object = Add<HGlobalObject>(); |
HRandom* result = new(zone()) HRandom(global_object); |
ast_context()->ReturnInstruction(result, expr->id()); |
return true; |
@@ -6784,7 +6748,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
HValue* right = Pop(); |
HValue* left = Pop(); |
Drop(1); // Receiver. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin |
: HMathMinMax::kMathMax; |
HInstruction* result = |
@@ -6799,7 +6763,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
HValue* right = Pop(); |
HValue* left = Pop(); |
Drop(1); // Receiver. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* result = HMul::NewImul(zone(), context, left, right); |
ast_context()->ReturnInstruction(result, expr->id()); |
return true; |
@@ -6883,12 +6847,12 @@ bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { |
} |
Drop(arguments_count - 1); |
- PushAndAdd(new(zone()) HPushArgument(Pop())); |
+ PushAndAdd(New<HPushArgument>(Pop())); |
for (int i = 1; i < arguments_count; i++) { |
- PushAndAdd(new(zone()) HPushArgument(arguments_values->at(i))); |
+ PushAndAdd(New<HPushArgument>(arguments_values->at(i))); |
} |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInvokeFunction* call = new(zone()) HInvokeFunction( |
context, |
function, |
@@ -6902,55 +6866,6 @@ bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { |
} |
-// Checks if all maps in |types| are from the same family, i.e., are elements |
-// transitions of each other. Returns either NULL if they are not from the same |
-// family, or a Map* indicating the map with the first elements kind of the |
-// family that is in the list. |
-static Map* CheckSameElementsFamily(SmallMapList* types) { |
- if (types->length() <= 1) return NULL; |
- // Check if all maps belong to the same transition family. |
- Map* kinds[kFastElementsKindCount]; |
- Map* first_map = *types->first(); |
- ElementsKind first_kind = first_map->elements_kind(); |
- if (!IsFastElementsKind(first_kind)) return NULL; |
- int first_index = GetSequenceIndexFromFastElementsKind(first_kind); |
- int last_index = first_index; |
- |
- for (int i = 0; i < kFastElementsKindCount; i++) kinds[i] = NULL; |
- |
- kinds[first_index] = first_map; |
- |
- for (int i = 1; i < types->length(); ++i) { |
- Map* map = *types->at(i); |
- ElementsKind elements_kind = map->elements_kind(); |
- if (!IsFastElementsKind(elements_kind)) return NULL; |
- int index = GetSequenceIndexFromFastElementsKind(elements_kind); |
- if (index < first_index) { |
- first_index = index; |
- } else if (index > last_index) { |
- last_index = index; |
- } else if (kinds[index] != map) { |
- return NULL; |
- } |
- kinds[index] = map; |
- } |
- |
- Map* current = kinds[first_index]; |
- for (int i = first_index + 1; i <= last_index; i++) { |
- Map* next = kinds[i]; |
- if (next != NULL) { |
- ElementsKind current_kind = next->elements_kind(); |
- if (next != current->LookupElementsTransitionMap(current_kind)) { |
- return NULL; |
- } |
- current = next; |
- } |
- } |
- |
- return kinds[first_index]; |
-} |
- |
- |
void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
@@ -6974,7 +6889,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
call = new(zone()) HCallKeyed(context, key, argument_count); |
call->set_position(expr->position()); |
Drop(argument_count + 1); // 1 is the key. |
@@ -6996,12 +6911,6 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
receiver_map = (types == NULL || types->is_empty()) |
? Handle<Map>::null() |
: types->first(); |
- } else { |
- Map* family_map = CheckSameElementsFamily(types); |
- if (family_map != NULL) { |
- receiver_map = Handle<Map>(family_map); |
- monomorphic = expr->ComputeTarget(receiver_map, name); |
- } |
} |
HValue* receiver = |
@@ -7024,7 +6933,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
// When the target has a custom call IC generator, use the IC, |
// because it is likely to generate better code. Also use the IC |
// when a primitive receiver check is required. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
call = PreProcessCall( |
new(zone()) HCallNamed(context, name, argument_count)); |
} else { |
@@ -7041,7 +6950,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
return; |
} else { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
call = PreProcessCall( |
new(zone()) HCallNamed(context, name, argument_count)); |
} |
@@ -7049,7 +6958,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
} else { |
VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
- return Bailout("possible direct call to eval"); |
+ return Bailout(kPossibleDirectCallToEval); |
} |
bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
@@ -7069,7 +6978,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
if (known_global_function) { |
// Push the global object instead of the global receiver because |
// code generated by the full code generator expects it. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
PushAndAdd(global_object); |
CHECK_ALIVE(VisitExpressions(expr->arguments())); |
@@ -7103,7 +7012,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
// When the target has a custom call IC generator, use the IC, |
// because it is likely to generate better code. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
call = PreProcessCall( |
new(zone()) HCallNamed(context, var->name(), argument_count)); |
} else { |
@@ -7111,12 +7020,11 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
argument_count)); |
} |
} else { |
- HValue* context = environment()->LookupContext(); |
- HGlobalObject* receiver = Add<HGlobalObject>(context); |
- PushAndAdd(new(zone()) HPushArgument(receiver)); |
+ HGlobalObject* receiver = Add<HGlobalObject>(); |
+ PushAndAdd(New<HPushArgument>(receiver)); |
CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
- call = new(zone()) HCallGlobal(context, var->name(), argument_count); |
+ call = New<HCallGlobal>(var->name(), argument_count); |
Drop(argument_count); |
} |
@@ -7125,9 +7033,8 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
// evaluation of the arguments. |
CHECK_ALIVE(VisitForValue(expr->expression())); |
HValue* function = Top(); |
- HValue* context = environment()->LookupContext(); |
- HGlobalObject* global = Add<HGlobalObject>(context); |
- HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
+ HGlobalObject* global = Add<HGlobalObject>(); |
+ HGlobalReceiver* receiver = New<HGlobalReceiver>(global); |
PushAndAdd(receiver); |
CHECK_ALIVE(VisitExpressions(expr->arguments())); |
Add<HCheckFunction>(function, expr->target()); |
@@ -7144,24 +7051,20 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
if (TryInlineCall(expr, true)) { // Drop function from environment. |
return; |
} else { |
- call = PreProcessCall( |
- new(zone()) HInvokeFunction(context, |
- function, |
- expr->target(), |
- argument_count)); |
+ call = PreProcessCall(New<HInvokeFunction>(function, expr->target(), |
+ argument_count)); |
Drop(1); // The function. |
} |
} else { |
CHECK_ALIVE(VisitForValue(expr->expression())); |
HValue* function = Top(); |
- HValue* context = environment()->LookupContext(); |
- HGlobalObject* global_object = Add<HGlobalObject>(context); |
+ HGlobalObject* global_object = Add<HGlobalObject>(); |
HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object); |
- PushAndAdd(new(zone()) HPushArgument(receiver)); |
+ PushAndAdd(New<HPushArgument>(receiver)); |
CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
- call = new(zone()) HCallFunction(context, function, argument_count); |
+ call = New<HCallFunction>(function, argument_count); |
Drop(argument_count + 1); |
} |
} |
@@ -7185,7 +7088,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
Factory* factory = isolate()->factory(); |
if (FLAG_inline_construct && |
@@ -7213,42 +7116,41 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
// Allocate an instance of the implicit receiver object. |
HValue* size_in_bytes = Add<HConstant>(instance_size); |
- HAllocate::Flags flags = HAllocate::DefaultFlags(); |
- if (FLAG_pretenuring_call_new && |
- isolate()->heap()->ShouldGloballyPretenure()) { |
- flags = static_cast<HAllocate::Flags>( |
- flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
- } |
+ PretenureFlag pretenure_flag = |
+ (FLAG_pretenuring_call_new && |
+ isolate()->heap()->GetPretenureMode() == TENURED) |
+ ? TENURED : NOT_TENURED; |
HAllocate* receiver = |
- Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); |
+ Add<HAllocate>(size_in_bytes, HType::JSObject(), pretenure_flag, |
+ JS_OBJECT_TYPE); |
receiver->set_known_initial_map(initial_map); |
// Load the initial map from the constructor. |
HValue* constructor_value = Add<HConstant>(constructor); |
HValue* initial_map_value = |
- AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset( |
+ Add<HLoadNamedField>(constructor_value, HObjectAccess::ForJSObjectOffset( |
JSFunction::kPrototypeOrInitialMapOffset)); |
// Initialize map and fields of the newly allocated object. |
{ NoObservableSideEffectsScope no_effects(this); |
ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); |
- AddStore(receiver, |
- HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset), |
- initial_map_value); |
+ Add<HStoreNamedField>(receiver, |
+ HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset), |
+ initial_map_value); |
HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); |
- AddStore(receiver, |
- HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset), |
- empty_fixed_array); |
- AddStore(receiver, |
- HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset), |
- empty_fixed_array); |
+ Add<HStoreNamedField>(receiver, |
+ HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset), |
+ empty_fixed_array); |
+ Add<HStoreNamedField>(receiver, |
+ HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset), |
+ empty_fixed_array); |
if (initial_map->inobject_properties() != 0) { |
HConstant* undefined = graph()->GetConstantUndefined(); |
for (int i = 0; i < initial_map->inobject_properties(); i++) { |
int property_offset = JSObject::kHeaderSize + i * kPointerSize; |
- AddStore(receiver, |
- HObjectAccess::ForJSObjectOffset(property_offset), |
- undefined); |
+ Add<HStoreNamedField>(receiver, |
+ HObjectAccess::ForJSObjectOffset(property_offset), |
+ undefined); |
} |
} |
} |
@@ -7324,7 +7226,7 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
if (expr->is_jsruntime()) { |
- return Bailout("call to a JavaScript runtime function"); |
+ return Bailout(kCallToAJavaScriptRuntimeFunction); |
} |
const Runtime::Function* function = expr->function(); |
@@ -7346,11 +7248,10 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
ASSERT(function->intrinsic_type == Runtime::RUNTIME); |
CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
- HValue* context = environment()->LookupContext(); |
Handle<String> name = expr->name(); |
int argument_count = expr->arguments()->length(); |
- HCallRuntime* call = |
- new(zone()) HCallRuntime(context, name, function, argument_count); |
+ HCallRuntime* call = New<HCallRuntime>(name, function, |
+ argument_count); |
Drop(argument_count); |
return ast_context()->ReturnInstruction(call, expr->id()); |
} |
@@ -7381,19 +7282,18 @@ void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
CHECK_ALIVE(VisitForValue(prop->key())); |
HValue* key = Pop(); |
HValue* obj = Pop(); |
- HValue* context = environment()->LookupContext(); |
- HValue* function = AddLoadJSBuiltin(Builtins::DELETE, context); |
+ HValue* function = AddLoadJSBuiltin(Builtins::DELETE); |
Add<HPushArgument>(obj); |
Add<HPushArgument>(key); |
Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag())); |
// TODO(olivf) InvokeFunction produces a check for the parameter count, |
// even though we are certain to pass the correct number of arguments here. |
- HInstruction* instr = new(zone()) HInvokeFunction(context, function, 3); |
+ HInstruction* instr = New<HInvokeFunction>(function, 3); |
return ast_context()->ReturnInstruction(instr, expr->id()); |
} else if (proxy != NULL) { |
Variable* var = proxy->var(); |
if (var->IsUnallocated()) { |
- Bailout("delete with global variable"); |
+ Bailout(kDeleteWithGlobalVariable); |
} else if (var->IsStackAllocated() || var->IsContextSlot()) { |
// Result of deleting non-global variables is false. 'this' is not |
// really a variable, though we implement it as one. The |
@@ -7403,7 +7303,7 @@ void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
: graph()->GetConstantFalse(); |
return ast_context()->ReturnValue(value); |
} else { |
- Bailout("delete with non-global variable"); |
+ Bailout(kDeleteWithNonGlobalVariable); |
} |
} else { |
// Result of deleting non-property, non-variable reference is true. |
@@ -7423,7 +7323,7 @@ void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { |
void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
HValue* value = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* instr = new(zone()) HTypeof(context, value); |
return ast_context()->ReturnInstruction(instr, expr->id()); |
} |
@@ -7520,11 +7420,9 @@ HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
HConstant* delta = (expr->op() == Token::INC) |
? graph()->GetConstant1() |
: graph()->GetConstantMinus1(); |
- HValue* context = environment()->LookupContext(); |
- HInstruction* instr = HAdd::New(zone(), context, Top(), delta); |
+ HInstruction* instr = Add<HAdd>(Top(), delta); |
instr->SetFlag(HInstruction::kCannotBeTagged); |
instr->ClearAllSideEffects(); |
- AddInstruction(instr); |
return instr; |
} |
@@ -7537,7 +7435,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
VariableProxy* proxy = target->AsVariableProxy(); |
Property* prop = target->AsProperty(); |
if (proxy == NULL && prop == NULL) { |
- return Bailout("invalid lhs in count operation"); |
+ return Bailout(kInvalidLhsInCountOperation); |
} |
// Match the full code generator stack by simulating an extra stack |
@@ -7551,7 +7449,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
if (proxy != NULL) { |
Variable* var = proxy->var(); |
if (var->mode() == CONST) { |
- return Bailout("unsupported count operation with const"); |
+ return Bailout(kUnsupportedCountOperationWithConst); |
} |
// Argument of the count operation is a variable, not a property. |
ASSERT(prop == NULL); |
@@ -7585,7 +7483,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
int count = current_info()->scope()->num_parameters(); |
for (int i = 0; i < count; ++i) { |
if (var == current_info()->scope()->parameter(i)) { |
- return Bailout("assignment to parameter in arguments object"); |
+ return Bailout(kAssignmentToParameterInArgumentsObject); |
} |
} |
} |
@@ -7602,7 +7500,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
} |
case Variable::LOOKUP: |
- return Bailout("lookup variable in count operation"); |
+ return Bailout(kLookupVariableInCountOperation); |
} |
} else { |
@@ -7689,7 +7587,6 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
- HValue* context, |
HValue* string, |
HValue* index) { |
if (string->IsConstant() && index->IsConstant()) { |
@@ -7699,17 +7596,18 @@ HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
int32_t i = c_index->NumberValueAsInteger32(); |
Handle<String> s = c_string->StringValue(); |
if (i < 0 || i >= s->length()) { |
- return new(zone()) HConstant(OS::nan_value()); |
+ return New<HConstant>(OS::nan_value()); |
} |
- return new(zone()) HConstant(s->Get(i)); |
+ return New<HConstant>(s->Get(i)); |
} |
} |
BuildCheckHeapObject(string); |
- AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
- HInstruction* length = HStringLength::New(zone(), string); |
+ HValue* checkstring = |
+ AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
+ HInstruction* length = BuildLoadStringLength(string, checkstring); |
AddInstruction(length); |
HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
- return new(zone()) HStringCharCodeAt(context, string, checked_index); |
+ return New<HStringCharCodeAt>(string, checked_index); |
} |
@@ -7779,26 +7677,6 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { |
*expected = handle(Type::Number(), isolate()); |
return AddInstruction(number.value); |
} |
- return value; |
- } |
- |
- Handle<Type> expected_type = *expected; |
- Representation rep = Representation::FromType(expected_type); |
- if (!rep.IsTagged()) return value; |
- |
- // If our type feedback suggests that we can non-observably truncate to number |
- // we introduce the appropriate check here. This avoids 'value' having a |
- // tagged representation later on. |
- if (expected_type->Is(Type::Oddball())) { |
- // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to |
- // also record booleans and convert them to 0/1 here. |
- IfBuilder if_nan(this); |
- if_nan.If<HCompareObjectEqAndBranch>(value, |
- graph()->GetConstantUndefined()); |
- if_nan.Then(); |
- if_nan.ElseDeopt(); |
- if_nan.End(); |
- return Add<HConstant>(OS::nan_value(), Representation::Double()); |
} |
return value; |
@@ -7809,7 +7687,7 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
BinaryOperation* expr, |
HValue* left, |
HValue* right) { |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
Handle<Type> left_type = expr->left()->bounds().lower; |
Handle<Type> right_type = expr->right()->bounds().lower; |
Handle<Type> result_type = expr->bounds().lower; |
@@ -7862,7 +7740,7 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
break; |
case Token::BIT_XOR: |
case Token::BIT_AND: |
- instr = HBitwise::New(zone(), expr->op(), context, left, right); |
+ instr = NewUncasted<HBitwise>(expr->op(), left, right); |
break; |
case Token::BIT_OR: { |
HValue* operand, *shift_amount; |
@@ -7871,7 +7749,7 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
MatchRotateRight(left, right, &operand, &shift_amount)) { |
instr = new(zone()) HRor(context, operand, shift_amount); |
} else { |
- instr = HBitwise::New(zone(), expr->op(), context, left, right); |
+ instr = NewUncasted<HBitwise>(expr->op(), left, right); |
} |
break; |
} |
@@ -8116,14 +7994,14 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
CHECK_ALIVE(VisitForValue(expr->left())); |
CHECK_ALIVE(VisitForValue(expr->right())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HValue* right = Pop(); |
HValue* left = Pop(); |
Token::Value op = expr->op(); |
if (IsLiteralCompareBool(left, op, right)) { |
HCompareObjectEqAndBranch* result = |
- new(zone()) HCompareObjectEqAndBranch(left, right); |
+ New<HCompareObjectEqAndBranch>(left, right); |
result->set_position(expr->position()); |
return ast_context()->ReturnControl(result, expr->id()); |
} |
@@ -8169,7 +8047,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
// Code below assumes that we don't fall through. |
UNREACHABLE(); |
} else if (op == Token::IN) { |
- HValue* function = AddLoadJSBuiltin(Builtins::IN, context); |
+ HValue* function = AddLoadJSBuiltin(Builtins::IN); |
Add<HPushArgument>(left); |
Add<HPushArgument>(right); |
// TODO(olivf) InvokeFunction produces a check for the parameter count, |
@@ -8193,10 +8071,10 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
// Can we get away with map check and not instance type check? |
if (combined_type->IsClass()) { |
Handle<Map> map = combined_type->AsClass(); |
- AddCheckMapsWithTransitions(left, map); |
- AddCheckMapsWithTransitions(right, map); |
+ AddCheckMap(left, map); |
+ AddCheckMap(right, map); |
HCompareObjectEqAndBranch* result = |
- new(zone()) HCompareObjectEqAndBranch(left, right); |
+ New<HCompareObjectEqAndBranch>(left, right); |
result->set_position(expr->position()); |
return ast_context()->ReturnControl(result, expr->id()); |
} else { |
@@ -8211,7 +8089,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
} |
} |
default: |
- return Bailout("Unsupported non-primitive compare"); |
+ return Bailout(kUnsupportedNonPrimitiveCompare); |
} |
} else if (combined_type->Is(Type::InternalizedString()) && |
Token::IsEqualityOp(op)) { |
@@ -8277,7 +8155,7 @@ HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
// If we share optimized code between different closures, the |
// this-function is not a constant, except inside an inlined body. |
if (function_state()->outer() != NULL) { |
- return new(zone()) HConstant( |
+ return New<HConstant>( |
function_state()->compilation_info()->closure()); |
} else { |
return new(zone()) HThisFunction; |
@@ -8298,34 +8176,27 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
HInstruction* target = NULL; |
HInstruction* data_target = NULL; |
- ElementsKind kind = boilerplate_object->map()->elements_kind(); |
- |
- if (isolate()->heap()->ShouldGloballyPretenure()) { |
+ if (isolate()->heap()->GetPretenureMode() == TENURED) { |
if (data_size != 0) { |
- HAllocate::Flags data_flags = |
- static_cast<HAllocate::Flags>(HAllocate::DefaultFlags(kind) | |
- HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
HValue* size_in_bytes = Add<HConstant>(data_size); |
- data_target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), |
- data_flags); |
+ data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED, |
+ FIXED_DOUBLE_ARRAY_TYPE); |
Handle<Map> free_space_map = isolate()->factory()->free_space_map(); |
AddStoreMapConstant(data_target, free_space_map); |
HObjectAccess access = |
HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); |
- AddStore(data_target, access, size_in_bytes); |
+ Add<HStoreNamedField>(data_target, access, size_in_bytes); |
} |
if (pointer_size != 0) { |
- HAllocate::Flags pointer_flags = |
- static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | |
- HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
HValue* size_in_bytes = Add<HConstant>(pointer_size); |
- target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), |
- pointer_flags); |
+ target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED, |
+ JS_OBJECT_TYPE); |
} |
} else { |
- HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
+ InstanceType instance_type = boilerplate_object->map()->instance_type(); |
HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); |
- target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); |
+ target = Add<HAllocate>(size_in_bytes, HType::JSObject(), NOT_TENURED, |
+ instance_type); |
} |
int offset = 0; |
@@ -8346,8 +8217,6 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
HInstruction* data_target, |
int* data_offset, |
AllocationSiteMode mode) { |
- Zone* zone = this->zone(); |
- |
bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && |
boilerplate_object->map()->CanTrackAllocationSite(); |
@@ -8359,8 +8228,7 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
HInstruction* allocation_site = NULL; |
if (create_allocation_site_info) { |
- allocation_site = AddInstruction(new(zone) HConstant( |
- allocation_site_object, Representation::Tagged())); |
+ allocation_site = Add<HConstant>(allocation_site_object); |
} |
// Only elements backing stores for non-COW arrays need to be copied. |
@@ -8441,14 +8309,15 @@ HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( |
} |
result = elements; |
} |
- AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); |
+ Add<HStoreNamedField>(object_header, HObjectAccess::ForElementsPointer(), |
+ elements); |
Handle<Object> properties_field = |
Handle<Object>(boilerplate_object->properties(), isolate()); |
ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
HInstruction* properties = Add<HConstant>(properties_field); |
HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
- AddStore(object_header, access, properties); |
+ Add<HStoreNamedField>(object_header, access, properties); |
if (boilerplate_object->IsJSArray()) { |
Handle<JSArray> boilerplate_array = |
@@ -8458,7 +8327,7 @@ HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( |
HInstruction* length = Add<HConstant>(length_field); |
ASSERT(boilerplate_array->length()->IsSmi()); |
- AddStore(object_header, HObjectAccess::ForArrayLength( |
+ Add<HStoreNamedField>(object_header, HObjectAccess::ForArrayLength( |
boilerplate_array->GetElementsKind()), length); |
} |
@@ -8503,7 +8372,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, |
*offset); |
- AddStore(object_properties, access, value_instruction); |
+ Add<HStoreNamedField>(object_properties, access, value_instruction); |
BuildEmitDeepCopy(value_object, original_value_object, |
Handle<Object>::null(), target, |
offset, data_target, data_offset, |
@@ -8524,12 +8393,12 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
} |
AddStoreMapConstant(double_box, |
isolate()->factory()->heap_number_map()); |
- AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
+ Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), |
value_instruction); |
value_instruction = double_box; |
} |
- AddStore(object_properties, access, value_instruction); |
+ Add<HStoreNamedField>(object_properties, access, value_instruction); |
} |
} |
@@ -8540,7 +8409,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
ASSERT(boilerplate_object->IsJSObject()); |
int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
- AddStore(object_properties, access, value_instruction); |
+ Add<HStoreNamedField>(object_properties, access, value_instruction); |
} |
} |
@@ -8649,7 +8518,7 @@ void HOptimizedGraphBuilder::VisitDeclarations( |
int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | |
DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | |
DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); |
- Add<HDeclareGlobals>(environment()->LookupContext(), array, flags); |
+ Add<HDeclareGlobals>(array, flags); |
globals_.Clear(); |
} |
} |
@@ -8678,7 +8547,7 @@ void HOptimizedGraphBuilder::VisitVariableDeclaration( |
case Variable::CONTEXT: |
if (hole_init) { |
HValue* value = graph()->GetConstantHole(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HStoreContextSlot* store = Add<HStoreContextSlot>( |
context, variable->index(), HStoreContextSlot::kNoCheck, value); |
if (store->HasObservableSideEffects()) { |
@@ -8687,7 +8556,7 @@ void HOptimizedGraphBuilder::VisitVariableDeclaration( |
} |
break; |
case Variable::LOOKUP: |
- return Bailout("unsupported lookup slot in declaration"); |
+ return Bailout(kUnsupportedLookupSlotInDeclaration); |
} |
} |
@@ -8716,7 +8585,7 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
case Variable::CONTEXT: { |
CHECK_ALIVE(VisitForValue(declaration->fun())); |
HValue* value = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HStoreContextSlot* store = Add<HStoreContextSlot>( |
context, variable->index(), HStoreContextSlot::kNoCheck, value); |
if (store->HasObservableSideEffects()) { |
@@ -8725,7 +8594,7 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
break; |
} |
case Variable::LOOKUP: |
- return Bailout("unsupported lookup slot in declaration"); |
+ return Bailout(kUnsupportedLookupSlotInDeclaration); |
} |
} |
@@ -8846,7 +8715,7 @@ void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { |
- return Bailout("inlined runtime function: IsNonNegativeSmi"); |
+ return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi); |
} |
@@ -8862,8 +8731,7 @@ void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( |
CallRuntime* call) { |
- return Bailout( |
- "inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); |
+ return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf); |
} |
@@ -8891,7 +8759,7 @@ void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { |
ASSERT(function_state()->outer() == NULL); |
ASSERT(call->arguments()->length() == 0); |
HInstruction* elements = Add<HArgumentsElements>(false); |
- HArgumentsLength* result = new(zone()) HArgumentsLength(elements); |
+ HArgumentsLength* result = New<HArgumentsLength>(elements); |
return ast_context()->ReturnInstruction(result, call->id()); |
} |
@@ -8917,7 +8785,7 @@ void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
// The special form detected by IsClassOfTest is detected before we get here |
// and does not cause a bailout. |
- return Bailout("inlined runtime function: ClassOf"); |
+ return Bailout(kInlinedRuntimeFunctionClassOf); |
} |
@@ -9000,7 +8868,7 @@ void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { |
// Create in-object property store to kValueOffset. |
set_current_block(if_js_value); |
- AddStore(object, |
+ Add<HStoreNamedField>(object, |
HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value); |
if_js_value->Goto(join); |
join->SetJoinId(call->id()); |
@@ -9016,8 +8884,7 @@ void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
HValue* index = Pop(); |
HValue* string = Pop(); |
- HValue* context = environment()->LookupContext(); |
- HInstruction* result = BuildStringCharCodeAt(context, string, index); |
+ HInstruction* result = BuildStringCharCodeAt(string, index); |
return ast_context()->ReturnInstruction(result, call->id()); |
} |
@@ -9027,8 +8894,7 @@ void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
ASSERT(call->arguments()->length() == 1); |
CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
HValue* char_code = Pop(); |
- HValue* context = environment()->LookupContext(); |
- HInstruction* result = HStringCharFromCode::New(zone(), context, char_code); |
+ HInstruction* result = New<HStringCharFromCode>(char_code); |
return ast_context()->ReturnInstruction(result, call->id()); |
} |
@@ -9040,10 +8906,9 @@ void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
HValue* index = Pop(); |
HValue* string = Pop(); |
- HValue* context = environment()->LookupContext(); |
- HInstruction* char_code = BuildStringCharCodeAt(context, string, index); |
+ HInstruction* char_code = BuildStringCharCodeAt(string, index); |
AddInstruction(char_code); |
- HInstruction* result = HStringCharFromCode::New(zone(), context, char_code); |
+ HInstruction* result = New<HStringCharFromCode>(char_code); |
return ast_context()->ReturnInstruction(result, call->id()); |
} |
@@ -9056,7 +8921,7 @@ void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
HValue* right = Pop(); |
HValue* left = Pop(); |
HCompareObjectEqAndBranch* result = |
- new(zone()) HCompareObjectEqAndBranch(left, right); |
+ New<HCompareObjectEqAndBranch>(left, right); |
return ast_context()->ReturnControl(result, call->id()); |
} |
@@ -9069,8 +8934,7 @@ void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { |
// Fast support for Math.random(). |
void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
- HValue* context = environment()->LookupContext(); |
- HGlobalObject* global_object = Add<HGlobalObject>(context); |
+ HGlobalObject* global_object = Add<HGlobalObject>(); |
HRandom* result = new(zone()) HRandom(global_object); |
return ast_context()->ReturnInstruction(result, call->id()); |
} |
@@ -9083,7 +8947,7 @@ void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
HValue* right = Pop(); |
HValue* left = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* result = HStringAdd::New( |
zone(), context, left, right, STRING_ADD_CHECK_BOTH); |
return ast_context()->ReturnInstruction(result, call->id()); |
@@ -9094,7 +8958,7 @@ void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
ASSERT_EQ(3, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); |
Drop(3); |
return ast_context()->ReturnInstruction(result, call->id()); |
@@ -9105,7 +8969,7 @@ void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { |
ASSERT_EQ(2, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::StringCompare, 2); |
Drop(2); |
@@ -9117,7 +8981,7 @@ void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
ASSERT_EQ(4, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); |
Drop(4); |
return ast_context()->ReturnInstruction(result, call->id()); |
@@ -9128,7 +8992,7 @@ void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
ASSERT_EQ(3, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); |
Drop(3); |
@@ -9138,7 +9002,7 @@ void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
// Support for fast native caches. |
void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
- return Bailout("inlined runtime function: GetFromCache"); |
+ return Bailout(kInlinedRuntimeFunctionGetFromCache); |
} |
@@ -9146,7 +9010,7 @@ void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
ASSERT_EQ(1, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::NumberToString, 1); |
Drop(1); |
@@ -9166,7 +9030,6 @@ void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
CHECK_ALIVE(VisitForValue(call->arguments()->last())); |
HValue* function = Pop(); |
- HValue* context = environment()->LookupContext(); |
// Branch for function proxies, or other non-functions. |
HHasInstanceTypeAndBranch* typecheck = |
@@ -9179,14 +9042,13 @@ void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
current_block()->Finish(typecheck); |
set_current_block(if_jsfunction); |
- HInstruction* invoke_result = |
- Add<HInvokeFunction>(context, function, arg_count); |
+ HInstruction* invoke_result = Add<HInvokeFunction>(function, arg_count); |
Drop(arg_count); |
Push(invoke_result); |
if_jsfunction->Goto(join); |
set_current_block(if_nonfunction); |
- HInstruction* call_result = Add<HCallFunction>(context, function, arg_count); |
+ HInstruction* call_result = Add<HCallFunction>(function, arg_count); |
Drop(arg_count); |
Push(call_result); |
if_nonfunction->Goto(join); |
@@ -9204,7 +9066,7 @@ void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { |
CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
HValue* right = Pop(); |
HValue* left = Pop(); |
- HInstruction* result = HPower::New(zone(), left, right); |
+ HInstruction* result = HPower::New(zone(), context(), left, right); |
return ast_context()->ReturnInstruction(result, call->id()); |
} |
@@ -9212,7 +9074,7 @@ void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { |
ASSERT_EQ(1, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
result->set_transcendental_type(TranscendentalCache::SIN); |
@@ -9224,7 +9086,7 @@ void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { |
ASSERT_EQ(1, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
result->set_transcendental_type(TranscendentalCache::COS); |
@@ -9236,7 +9098,7 @@ void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { |
ASSERT_EQ(1, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
result->set_transcendental_type(TranscendentalCache::TAN); |
@@ -9248,7 +9110,7 @@ void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { |
ASSERT_EQ(1, call->arguments()->length()); |
CHECK_ALIVE(VisitArgumentList(call->arguments())); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HCallStub* result = |
new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
result->set_transcendental_type(TranscendentalCache::LOG); |
@@ -9261,7 +9123,7 @@ void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { |
ASSERT(call->arguments()->length() == 1); |
CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
HValue* value = Pop(); |
- HValue* context = environment()->LookupContext(); |
+ HValue* context = environment()->context(); |
HInstruction* result = |
HUnaryMathOperation::New(zone(), context, value, kMathSqrt); |
return ast_context()->ReturnInstruction(result, call->id()); |
@@ -9270,7 +9132,7 @@ void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { |
// Check whether two RegExps are equivalent |
void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { |
- return Bailout("inlined runtime function: IsRegExpEquivalent"); |
+ return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); |
} |
@@ -9284,18 +9146,18 @@ void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { |
void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { |
- return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
+ return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin); |
} |
// Support for generators. |
void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { |
- return Bailout("inlined runtime function: GeneratorNext"); |
+ return Bailout(kInlinedRuntimeFunctionGeneratorNext); |
} |
void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { |
- return Bailout("inlined runtime function: GeneratorThrow"); |
+ return Bailout(kInlinedRuntimeFunctionGeneratorThrow); |
} |
@@ -9571,7 +9433,7 @@ HEnvironment* HEnvironment::CopyForInlining( |
if (undefined_receiver) { |
inner->SetValueAt(0, undefined); |
} |
- inner->SetValueAt(arity + 1, LookupContext()); |
+ inner->SetValueAt(arity + 1, context()); |
for (int i = arity + 2; i < inner->length(); ++i) { |
inner->SetValueAt(i, undefined); |
} |