summaryrefslogtreecommitdiff
path: root/deps/v8/src/code-stubs-hydrogen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/code-stubs-hydrogen.cc')
-rw-r--r--deps/v8/src/code-stubs-hydrogen.cc244
1 files changed, 93 insertions, 151 deletions
diff --git a/deps/v8/src/code-stubs-hydrogen.cc b/deps/v8/src/code-stubs-hydrogen.cc
index d1cabde1bd..81304e5002 100644
--- a/deps/v8/src/code-stubs-hydrogen.cc
+++ b/deps/v8/src/code-stubs-hydrogen.cc
@@ -48,7 +48,8 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
protected:
virtual HValue* BuildCodeStub() = 0;
- int GetParameterCount() const {
+ int GetParameterCount() const { return descriptor_.GetParameterCount(); }
+ int GetRegisterParameterCount() const {
return descriptor_.GetRegisterParameterCount();
}
HParameter* GetParameter(int parameter) {
@@ -118,7 +119,7 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
ElementsKind kind);
- SmartArrayPointer<HParameter*> parameters_;
+ base::SmartArrayPointer<HParameter*> parameters_;
HValue* arguments_length_;
CompilationInfo* info_;
CodeStubDescriptor descriptor_;
@@ -138,6 +139,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
}
int param_count = GetParameterCount();
+ int register_param_count = GetRegisterParameterCount();
HEnvironment* start_environment = graph()->start_environment();
HBasicBlock* next_block = CreateBasicBlock(start_environment);
Goto(next_block);
@@ -148,11 +150,16 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
HInstruction* stack_parameter_count = NULL;
for (int i = 0; i < param_count; ++i) {
Representation r = GetParameterRepresentation(i);
- HParameter* param = Add<HParameter>(i,
- HParameter::REGISTER_PARAMETER, r);
+ HParameter* param;
+ if (i >= register_param_count) {
+ param = Add<HParameter>(i - register_param_count,
+ HParameter::STACK_PARAMETER, r);
+ } else {
+ param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r);
+ }
start_environment->Bind(i, param);
parameters_[i] = param;
- if (IsParameterCountRegister(i)) {
+ if (i < register_param_count && IsParameterCountRegister(i)) {
param->set_type(HType::Smi());
stack_parameter_count = param;
arguments_length_ = stack_parameter_count;
@@ -161,7 +168,9 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
DCHECK(!runtime_stack_params || arguments_length_ != NULL);
if (!runtime_stack_params) {
- stack_parameter_count = graph()->GetConstantMinus1();
+ stack_parameter_count =
+ Add<HConstant>(param_count - register_param_count - 1);
+ // graph()->GetConstantMinus1();
arguments_length_ = graph()->GetConstant0();
}
@@ -313,7 +322,6 @@ Handle<Code> NumberToStringStub::GenerateCode() {
// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
-// Possible optimizations: put the type string into the oddballs.
template <>
HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() {
Factory* factory = isolate()->factory();
@@ -332,7 +340,6 @@ HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() {
{ Push(number_string); }
is_number.Else();
{
- HConstant* undefined_string = Add<HConstant>(factory->undefined_string());
HValue* map = AddLoadMap(object, smi_check);
HValue* instance_type = Add<HLoadNamedField>(
map, nullptr, HObjectAccess::ForMapInstanceType());
@@ -349,24 +356,8 @@ HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() {
instance_type, Add<HConstant>(ODDBALL_TYPE), Token::EQ);
is_oddball.Then();
{
- IfBuilder is_true_or_false(this);
- is_true_or_false.If<HCompareObjectEqAndBranch>(
- object, graph()->GetConstantTrue());
- is_true_or_false.OrIf<HCompareObjectEqAndBranch>(
- object, graph()->GetConstantFalse());
- is_true_or_false.Then();
- { Push(Add<HConstant>(factory->boolean_string())); }
- is_true_or_false.Else();
- {
- IfBuilder is_null(this);
- is_null.If<HCompareObjectEqAndBranch>(object,
- graph()->GetConstantNull());
- is_null.Then();
- { Push(object_string); }
- is_null.Else();
- { Push(undefined_string); }
- }
- is_true_or_false.End();
+ Push(Add<HLoadNamedField>(object, nullptr,
+ HObjectAccess::ForOddballTypeOf()));
}
is_oddball.Else();
{
@@ -389,13 +380,22 @@ HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() {
{ Push(Add<HConstant>(factory->function_string())); }
is_function.Else();
{
+#define SIMD128_BUILDER_OPEN(TYPE, Type, type, lane_count, lane_type) \
+ IfBuilder is_##type(this); \
+ is_##type.If<HCompareObjectEqAndBranch>( \
+ map, Add<HConstant>(factory->type##_map())); \
+ is_##type.Then(); \
+ { Push(Add<HConstant>(factory->type##_string())); } \
+ is_##type.Else(); {
+ SIMD128_TYPES(SIMD128_BUILDER_OPEN)
+#undef SIMD128_BUILDER_OPEN
// Is it an undetectable object?
IfBuilder is_undetectable(this);
is_undetectable.If<HIsUndetectableAndBranch>(object);
is_undetectable.Then();
{
// typeof an undetectable object is 'undefined'.
- Push(undefined_string);
+ Push(Add<HConstant>(factory->undefined_string()));
}
is_undetectable.Else();
{
@@ -403,6 +403,9 @@ HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() {
// host objects gives that it is okay to return "object".
Push(object_string);
}
+#define SIMD128_BUILDER_CLOSE(TYPE, Type, type, lane_count, lane_type) }
+ SIMD128_TYPES(SIMD128_BUILDER_CLOSE)
+#undef SIMD128_BUILDER_CLOSE
}
is_function.End();
}
@@ -1605,12 +1608,12 @@ Handle<Code> StoreGlobalStub::GenerateCode() {
}
-template<>
+template <>
HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
- HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex);
- HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex);
- HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex);
- HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex);
+ HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex);
+ HValue* key = GetParameter(StoreTransitionDescriptor::kNameIndex);
+ HValue* value = GetParameter(StoreTransitionDescriptor::kValueIndex);
+ HValue* map = GetParameter(StoreTransitionDescriptor::kMapIndex);
if (FLAG_trace_elements_transitions) {
// Tracing elements transitions is the job of the runtime.
@@ -1640,6 +1643,16 @@ Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
}
+template <>
+HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() {
+ HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex);
+ return BuildToObject(receiver);
+}
+
+
+Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
+
+
void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
HValue* js_function,
HValue* native_context,
@@ -1743,71 +1756,59 @@ void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
is_optimized.Else();
{
AddIncrementCounter(counters->fast_new_closure_try_optimized());
- // optimized_map points to fixed array of 3-element entries
- // (native context, optimized code, literals).
- // Map must never be empty, so check the first elements.
+ // The {optimized_map} points to fixed array of 4-element entries:
+ // (native context, optimized code, literals, ast-id).
+ // Iterate through the {optimized_map} backwards. After the loop, if no
+ // matching optimized code was found, install unoptimized code.
+ // for(i = map.length() - SharedFunctionInfo::kEntryLength;
+ // i >= SharedFunctionInfo::kEntriesStart;
+ // i -= SharedFunctionInfo::kEntryLength) { ... }
HValue* first_entry_index =
Add<HConstant>(SharedFunctionInfo::kEntriesStart);
- IfBuilder already_in(this);
- BuildCheckAndInstallOptimizedCode(js_function, native_context, &already_in,
- optimized_map, first_entry_index);
- already_in.Else();
+ HValue* shared_function_entry_length =
+ Add<HConstant>(SharedFunctionInfo::kEntryLength);
+ LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
+ shared_function_entry_length);
+ HValue* array_length = Add<HLoadNamedField>(
+ optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
+ HValue* start_pos =
+ AddUncasted<HSub>(array_length, shared_function_entry_length);
+ HValue* slot_iterator =
+ loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
{
- // Iterate through the rest of map backwards. Do not double check first
- // entry. After the loop, if no matching optimized code was found,
- // install unoptimized code.
- // for(i = map.length() - SharedFunctionInfo::kEntryLength;
- // i > SharedFunctionInfo::kEntriesStart;
- // i -= SharedFunctionInfo::kEntryLength) { .. }
- HValue* shared_function_entry_length =
- Add<HConstant>(SharedFunctionInfo::kEntryLength);
- LoopBuilder loop_builder(this,
- context(),
- LoopBuilder::kPostDecrement,
- shared_function_entry_length);
- HValue* array_length = Add<HLoadNamedField>(
- optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
- HValue* start_pos = AddUncasted<HSub>(array_length,
- shared_function_entry_length);
- HValue* slot_iterator = loop_builder.BeginBody(start_pos,
- first_entry_index,
- Token::GT);
+ IfBuilder done_check(this);
+ BuildCheckAndInstallOptimizedCode(js_function, native_context,
+ &done_check, optimized_map,
+ slot_iterator);
+ // Fall out of the loop
+ loop_builder.Break();
+ }
+ loop_builder.EndBody();
+
+ // If {slot_iterator} is less than the first entry index, then we failed to
+ // find a context-dependent code and try context-independent code next.
+ IfBuilder no_optimized_code_check(this);
+ no_optimized_code_check.If<HCompareNumericAndBranch>(
+ slot_iterator, first_entry_index, Token::LT);
+ no_optimized_code_check.Then();
+ {
+ IfBuilder shared_code_check(this);
+ HValue* shared_code =
+ Add<HLoadNamedField>(optimized_map, nullptr,
+ HObjectAccess::ForOptimizedCodeMapSharedCode());
+ shared_code_check.IfNot<HCompareObjectEqAndBranch>(
+ shared_code, graph()->GetConstantUndefined());
+ shared_code_check.Then();
{
- IfBuilder done_check(this);
- BuildCheckAndInstallOptimizedCode(js_function, native_context,
- &done_check,
- optimized_map,
- slot_iterator);
- // Fall out of the loop
- loop_builder.Break();
+ // Store the context-independent optimized code.
+ HValue* literals = Add<HConstant>(factory->empty_fixed_array());
+ BuildInstallOptimizedCode(js_function, native_context, shared_code,
+ literals);
}
- loop_builder.EndBody();
-
- // If slot_iterator equals first entry index, then we failed to find a
- // context-dependent code and try context-independent code next.
- IfBuilder no_optimized_code_check(this);
- no_optimized_code_check.If<HCompareNumericAndBranch>(
- slot_iterator, first_entry_index, Token::EQ);
- no_optimized_code_check.Then();
+ shared_code_check.Else();
{
- IfBuilder shared_code_check(this);
- HValue* shared_code = Add<HLoadNamedField>(
- optimized_map, nullptr,
- HObjectAccess::ForOptimizedCodeMapSharedCode());
- shared_code_check.IfNot<HCompareObjectEqAndBranch>(
- shared_code, graph()->GetConstantUndefined());
- shared_code_check.Then();
- {
- // Store the context-independent optimized code.
- HValue* literals = Add<HConstant>(factory->empty_fixed_array());
- BuildInstallOptimizedCode(js_function, native_context, shared_code,
- literals);
- }
- shared_code_check.Else();
- {
- // Store the unoptimized code.
- BuildInstallCode(js_function, shared_info);
- }
+ // Store the unoptimized code.
+ BuildInstallCode(js_function, shared_info);
}
}
}
@@ -1982,13 +1983,6 @@ class CodeStubGraphBuilder<KeyedLoadGenericStub>
HValue* bit_field2,
ElementsKind kind);
- void BuildExternalElementLoad(HGraphBuilder::IfBuilder* if_builder,
- HValue* receiver,
- HValue* key,
- HValue* instance_type,
- HValue* bit_field2,
- ElementsKind kind);
-
KeyedLoadGenericStub* casted_stub() {
return static_cast<KeyedLoadGenericStub*>(stub());
}
@@ -2010,8 +2004,6 @@ void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildElementsKindLimitCheck(
void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildFastElementLoad(
HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key,
HValue* instance_type, HValue* bit_field2, ElementsKind kind) {
- DCHECK(!IsExternalArrayElementsKind(kind));
-
BuildElementsKindLimitCheck(if_builder, bit_field2, kind);
IfBuilder js_array_check(this);
@@ -2031,20 +2023,6 @@ void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildFastElementLoad(
}
-void CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildExternalElementLoad(
- HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key,
- HValue* instance_type, HValue* bit_field2, ElementsKind kind) {
- DCHECK(IsExternalArrayElementsKind(kind));
-
- BuildElementsKindLimitCheck(if_builder, bit_field2, kind);
-
- Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
- false, kind,
- LOAD, NEVER_RETURN_HOLE,
- STANDARD_STORE));
-}
-
-
HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
HValue* key = GetParameter(LoadDescriptor::kNameIndex);
@@ -2106,42 +2084,6 @@ HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
Deoptimizer::EAGER);
Push(graph()->GetConstant0());
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_INT8_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_UINT8_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_INT16_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_UINT16_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_INT32_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_UINT32_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_FLOAT32_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_FLOAT64_ELEMENTS);
-
- kind_if.Else();
- BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
- EXTERNAL_UINT8_CLAMPED_ELEMENTS);
-
kind_if.ElseDeopt(
Deoptimizer::kElementsKindUnhandledInKeyedLoadGenericStub);
@@ -2229,7 +2171,7 @@ HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
index->ClearFlag(HValue::kCanOverflow);
HValue* property_index =
Add<HLoadKeyed>(cache_field_offsets, index, nullptr,
- EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0);
+ INT32_ELEMENTS, NEVER_RETURN_HOLE, 0);
Push(property_index);
}
lookup_if->Else();