Commit 9118b2fa authored by svenpanne's avatar svenpanne Committed by Commit bot

Tweak the TurboFan pipeline for stub compilation.

Review URL: https://codereview.chromium.org/1010673004

Cr-Commit-Position: refs/heads/master@{#27268}
parent 92f96e4e
...@@ -221,33 +221,21 @@ void CompilationInfo::RollbackDependencies() { ...@@ -221,33 +221,21 @@ void CompilationInfo::RollbackDependencies() {
int CompilationInfo::num_parameters() const { int CompilationInfo::num_parameters() const {
if (IsStub()) { return has_scope() ? scope()->num_parameters() : parameter_count_;
DCHECK(parameter_count_ > 0);
return parameter_count_;
} else {
return scope()->num_parameters();
}
} }
int CompilationInfo::num_heap_slots() const { int CompilationInfo::num_heap_slots() const {
if (IsStub()) { return has_scope() ? scope()->num_heap_slots() : 0;
return 0;
} else {
return scope()->num_heap_slots();
}
} }
Code::Flags CompilationInfo::flags() const { Code::Flags CompilationInfo::flags() const {
if (IsStub()) { return code_stub() != nullptr
return Code::ComputeFlags(code_stub()->GetCodeKind(), ? Code::ComputeFlags(
code_stub()->GetICState(), code_stub()->GetCodeKind(), code_stub()->GetICState(),
code_stub()->GetExtraICState(), code_stub()->GetExtraICState(), code_stub()->GetStubType())
code_stub()->GetStubType()); : Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
} else {
return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
}
} }
......
...@@ -163,6 +163,7 @@ class CompilationInfo { ...@@ -163,6 +163,7 @@ class CompilationInfo {
int num_parameters() const; int num_parameters() const;
int num_heap_slots() const; int num_heap_slots() const;
Code::Flags flags() const; Code::Flags flags() const;
bool has_scope() const { return scope() != nullptr; }
void set_parameter_count(int parameter_count) { void set_parameter_count(int parameter_count) {
DCHECK(IsStub()); DCHECK(IsStub());
...@@ -270,6 +271,11 @@ class CompilationInfo { ...@@ -270,6 +271,11 @@ class CompilationInfo {
optimization_id_ = isolate()->NextOptimizationId(); optimization_id_ = isolate()->NextOptimizationId();
} }
void SetStub(CodeStub* code_stub) {
SetMode(STUB);
code_stub_ = code_stub;
}
// Deoptimization support. // Deoptimization support.
bool HasDeoptimizationSupport() const { bool HasDeoptimizationSupport() const {
return GetFlag(kDeoptimizationSupport); return GetFlag(kDeoptimizationSupport);
......
...@@ -32,6 +32,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { ...@@ -32,6 +32,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceInlineIsInstanceType(node, JS_ARRAY_TYPE); return ReduceInlineIsInstanceType(node, JS_ARRAY_TYPE);
case Runtime::kInlineIsFunction: case Runtime::kInlineIsFunction:
return ReduceInlineIsInstanceType(node, JS_FUNCTION_TYPE); return ReduceInlineIsInstanceType(node, JS_FUNCTION_TYPE);
case Runtime::kInlineJSValueGetValue:
return ReduceInlineJSValueGetValue(node);
case Runtime::kInlineConstructDouble: case Runtime::kInlineConstructDouble:
return ReduceInlineConstructDouble(node); return ReduceInlineConstructDouble(node);
case Runtime::kInlineDoubleLo: case Runtime::kInlineDoubleLo:
...@@ -44,6 +46,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { ...@@ -44,6 +46,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceInlineMathFloor(node); return ReduceInlineMathFloor(node);
case Runtime::kInlineMathSqrt: case Runtime::kInlineMathSqrt:
return ReduceInlineMathSqrt(node); return ReduceInlineMathSqrt(node);
case Runtime::kInlineStringGetLength:
return ReduceInlineStringGetLength(node);
case Runtime::kInlineValueOf: case Runtime::kInlineValueOf:
return ReduceInlineValueOf(node); return ReduceInlineValueOf(node);
default: default:
...@@ -103,6 +107,15 @@ Reduction JSIntrinsicLowering::ReduceInlineIsNonNegativeSmi(Node* node) { ...@@ -103,6 +107,15 @@ Reduction JSIntrinsicLowering::ReduceInlineIsNonNegativeSmi(Node* node) {
} }
Reduction JSIntrinsicLowering::ReduceInlineJSValueGetValue(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value,
effect, control);
}
Reduction JSIntrinsicLowering::ReduceInlineConstructDouble(Node* node) { Reduction JSIntrinsicLowering::ReduceInlineConstructDouble(Node* node) {
Node* high = NodeProperties::GetValueInput(node, 0); Node* high = NodeProperties::GetValueInput(node, 0);
Node* low = NodeProperties::GetValueInput(node, 1); Node* low = NodeProperties::GetValueInput(node, 1);
...@@ -177,6 +190,15 @@ Reduction JSIntrinsicLowering::ReduceInlineMathSqrt(Node* node) { ...@@ -177,6 +190,15 @@ Reduction JSIntrinsicLowering::ReduceInlineMathSqrt(Node* node) {
} }
Reduction JSIntrinsicLowering::ReduceInlineStringGetLength(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
return Change(node, simplified()->LoadField(AccessBuilder::ForStringLength()),
value, effect, control);
}
Reduction JSIntrinsicLowering::ReduceInlineValueOf(Node* node) { Reduction JSIntrinsicLowering::ReduceInlineValueOf(Node* node) {
// if (%_IsSmi(value)) { // if (%_IsSmi(value)) {
// return value; // return value;
...@@ -258,6 +280,7 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, ...@@ -258,6 +280,7 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
node->ReplaceInput(1, b); node->ReplaceInput(1, b);
node->ReplaceInput(2, c); node->ReplaceInput(2, c);
node->TrimInputCount(3); node->TrimInputCount(3);
NodeProperties::ReplaceWithValue(node, node, node);
return Changed(node); return Changed(node);
} }
......
...@@ -31,11 +31,13 @@ class JSIntrinsicLowering FINAL : public Reducer { ...@@ -31,11 +31,13 @@ class JSIntrinsicLowering FINAL : public Reducer {
Reduction ReduceInlineIsSmi(Node* node); Reduction ReduceInlineIsSmi(Node* node);
Reduction ReduceInlineIsNonNegativeSmi(Node* node); Reduction ReduceInlineIsNonNegativeSmi(Node* node);
Reduction ReduceInlineIsInstanceType(Node* node, InstanceType instance_type); Reduction ReduceInlineIsInstanceType(Node* node, InstanceType instance_type);
Reduction ReduceInlineJSValueGetValue(Node* node);
Reduction ReduceInlineConstructDouble(Node* node); Reduction ReduceInlineConstructDouble(Node* node);
Reduction ReduceInlineDoubleLo(Node* node); Reduction ReduceInlineDoubleLo(Node* node);
Reduction ReduceInlineDoubleHi(Node* node); Reduction ReduceInlineDoubleHi(Node* node);
Reduction ReduceInlineMathFloor(Node* node); Reduction ReduceInlineMathFloor(Node* node);
Reduction ReduceInlineMathSqrt(Node* node); Reduction ReduceInlineMathSqrt(Node* node);
Reduction ReduceInlineStringGetLength(Node* node);
Reduction ReduceInlineValueOf(Node* node); Reduction ReduceInlineValueOf(Node* node);
Reduction Change(Node* node, const Operator* op); Reduction Change(Node* node, const Operator* op);
......
...@@ -315,9 +315,9 @@ class AstGraphBuilderWithPositions : public AstGraphBuilder { ...@@ -315,9 +315,9 @@ class AstGraphBuilderWithPositions : public AstGraphBuilder {
source_positions_(source_positions), source_positions_(source_positions),
start_position_(info->shared_info()->start_position()) {} start_position_(info->shared_info()->start_position()) {}
bool CreateGraph(bool constant_context) { bool CreateGraph(bool constant_context, bool stack_check) {
SourcePositionTable::Scope pos_scope(source_positions_, start_position_); SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
return AstGraphBuilder::CreateGraph(constant_context); return AstGraphBuilder::CreateGraph(constant_context, stack_check);
} }
#define DEF_VISIT(type) \ #define DEF_VISIT(type) \
...@@ -420,7 +420,8 @@ struct GraphBuilderPhase { ...@@ -420,7 +420,8 @@ struct GraphBuilderPhase {
AstGraphBuilderWithPositions graph_builder( AstGraphBuilderWithPositions graph_builder(
temp_zone, data->info(), data->jsgraph(), data->loop_assignment(), temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
data->source_positions()); data->source_positions());
if (!graph_builder.CreateGraph(constant_context)) { bool stack_check = !data->info()->IsStub();
if (!graph_builder.CreateGraph(constant_context, stack_check)) {
data->set_compilation_failed(); data->set_compilation_failed();
} }
} }
......
...@@ -11719,6 +11719,17 @@ void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { ...@@ -11719,6 +11719,17 @@ void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) {
} }
void HOptimizedGraphBuilder::GenerateJSValueGetValue(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* value = Pop();
HInstruction* result = Add<HLoadNamedField>(
value, nullptr,
HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset));
return ast_context()->ReturnInstruction(result, call->id());
}
void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) {
DCHECK(call->arguments()->length() == 2); DCHECK(call->arguments()->length() == 2);
DCHECK_NOT_NULL(call->arguments()->at(1)->AsLiteral()); DCHECK_NOT_NULL(call->arguments()->at(1)->AsLiteral());
...@@ -11880,6 +11891,15 @@ void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { ...@@ -11880,6 +11891,15 @@ void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
} }
void HOptimizedGraphBuilder::GenerateStringGetLength(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* string = Pop();
HInstruction* result = AddLoadStringLength(string);
return ast_context()->ReturnInstruction(result, call->id());
}
// Support for direct calls from JavaScript to native RegExp code. // Support for direct calls from JavaScript to native RegExp code.
void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
DCHECK_EQ(4, call->arguments()->length()); DCHECK_EQ(4, call->arguments()->length());
......
...@@ -2231,7 +2231,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2231,7 +2231,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
F(SetInitialize) \ F(SetInitialize) \
/* Arrays */ \ /* Arrays */ \
F(HasFastPackedElements) \ F(HasFastPackedElements) \
F(GetPrototype) F(GetPrototype) \
/* Strings */ \
F(StringGetLength) \
/* JSValue */ \
F(JSValueGetValue)
#define GENERATOR_DECLARATION(Name) void Generate##Name(CallRuntime* call); #define GENERATOR_DECLARATION(Name) void Generate##Name(CallRuntime* call);
FOR_EACH_HYDROGEN_INTRINSIC(GENERATOR_DECLARATION) FOR_EACH_HYDROGEN_INTRINSIC(GENERATOR_DECLARATION)
......
...@@ -694,3 +694,14 @@ function ToPositiveInteger(x, rangeErrorName) { ...@@ -694,3 +694,14 @@ function ToPositiveInteger(x, rangeErrorName) {
// that is cloned when running the code. It is essential that the // that is cloned when running the code. It is essential that the
// boilerplate gets the right prototype. // boilerplate gets the right prototype.
%FunctionSetPrototype($Array, new $Array(0)); %FunctionSetPrototype($Array, new $Array(0));
/* -----------------------------------------------
- - - J a v a S c r i p t S t u b s - - -
-----------------------------------------------
*/
function STRING_LENGTH_STUB(name) {
var receiver = this; // implicit first parameter
return %_StringGetLength(%_JSValueGetValue(receiver));
}
...@@ -1497,6 +1497,14 @@ RUNTIME_FUNCTION(Runtime_SetValueOf) { ...@@ -1497,6 +1497,14 @@ RUNTIME_FUNCTION(Runtime_SetValueOf) {
} }
RUNTIME_FUNCTION(Runtime_JSValueGetValue) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSValue, obj, 0);
return JSValue::cast(obj)->value();
}
RUNTIME_FUNCTION(Runtime_ObjectEquals) { RUNTIME_FUNCTION(Runtime_ObjectEquals) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK(args.length() == 2); DCHECK(args.length() == 2);
......
...@@ -1301,5 +1301,13 @@ RUNTIME_FUNCTION(Runtime_IsStringWrapperSafeForDefaultValueOf) { ...@@ -1301,5 +1301,13 @@ RUNTIME_FUNCTION(Runtime_IsStringWrapperSafeForDefaultValueOf) {
UNIMPLEMENTED(); UNIMPLEMENTED();
return NULL; return NULL;
} }
RUNTIME_FUNCTION(Runtime_StringGetLength) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return Smi::FromInt(s->length());
}
} }
} // namespace v8::internal } // namespace v8::internal
...@@ -713,7 +713,11 @@ namespace internal { ...@@ -713,7 +713,11 @@ namespace internal {
F(SetInitialize, 1, 1) \ F(SetInitialize, 1, 1) \
/* Arrays */ \ /* Arrays */ \
F(HasFastPackedElements, 1, 1) \ F(HasFastPackedElements, 1, 1) \
F(GetPrototype, 1, 1) F(GetPrototype, 1, 1) \
/* Strings */ \
F(StringGetLength, 1, 1) \
/* JSValue */ \
F(JSValueGetValue, 1, 1)
#define FOR_EACH_INTRINSIC_RETURN_OBJECT(F) \ #define FOR_EACH_INTRINSIC_RETURN_OBJECT(F) \
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/bootstrapper.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/linkage.h" #include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h" #include "src/compiler/pipeline.h"
#include "src/compiler/raw-machine-assembler.h" #include "src/parser.h"
#include "src/globals.h"
#include "src/handles.h"
#include "test/cctest/compiler/function-tester.h" #include "test/cctest/compiler/function-tester.h"
#if V8_TURBOFAN_TARGET #if V8_TURBOFAN_TARGET
...@@ -17,6 +17,20 @@ using namespace v8::internal; ...@@ -17,6 +17,20 @@ using namespace v8::internal;
using namespace v8::internal::compiler; using namespace v8::internal::compiler;
static Handle<JSFunction> GetFunction(Isolate* isolate, const char* name) {
v8::ExtensionConfiguration no_extensions;
Handle<Context> ctx = isolate->bootstrapper()->CreateEnvironment(
MaybeHandle<JSGlobalProxy>(), v8::Handle<v8::ObjectTemplate>(),
&no_extensions);
Handle<JSBuiltinsObject> builtins = handle(ctx->builtins());
MaybeHandle<Object> fun = Object::GetProperty(isolate, builtins, name);
Handle<JSFunction> function = Handle<JSFunction>::cast(fun.ToHandleChecked());
// Just to make sure nobody calls this...
function->set_code(isolate->builtins()->builtin(Builtins::kIllegal));
return function;
}
class StringLengthStubTF : public CodeStub { class StringLengthStubTF : public CodeStub {
public: public:
explicit StringLengthStubTF(Isolate* isolate) : CodeStub(isolate) {} explicit StringLengthStubTF(Isolate* isolate) : CodeStub(isolate) {}
...@@ -28,18 +42,13 @@ class StringLengthStubTF : public CodeStub { ...@@ -28,18 +42,13 @@ class StringLengthStubTF : public CodeStub {
}; };
Handle<Code> GenerateCode() OVERRIDE { Handle<Code> GenerateCode() OVERRIDE {
CompilationInfoWithZone info(this, isolate()); // Build a "hybrid" CompilationInfo for a JSFunction/CodeStub pair.
Graph graph(info.zone()); CompilationInfoWithZone info(GetFunction(isolate(), "STRING_LENGTH_STUB"));
CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info); info.SetStub(this);
RawMachineAssembler m(isolate(), &graph, descriptor->GetMachineSignature()); // Run a "mini pipeline", extracted from compiler.cc.
CHECK(Parser::ParseStatic(info.parse_info()));
Node* str = m.Load(kMachAnyTagged, m.Parameter(0), CHECK(Compiler::Analyze(info.parse_info()));
m.Int32Constant(JSValue::kValueOffset - kHeapObjectTag)); return Pipeline(&info).GenerateCode();
Node* len = m.Load(kMachAnyTagged, str,
m.Int32Constant(String::kLengthOffset - kHeapObjectTag));
m.Return(len);
return Pipeline::GenerateCodeForTesting(&info, &graph, m.Export());
} }
Major MajorKey() const OVERRIDE { return StringLength; }; Major MajorKey() const OVERRIDE { return StringLength; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment