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() {
int CompilationInfo::num_parameters() const {
if (IsStub()) {
DCHECK(parameter_count_ > 0);
return parameter_count_;
} else {
return scope()->num_parameters();
}
return has_scope() ? scope()->num_parameters() : parameter_count_;
}
int CompilationInfo::num_heap_slots() const {
if (IsStub()) {
return 0;
} else {
return scope()->num_heap_slots();
}
return has_scope() ? scope()->num_heap_slots() : 0;
}
Code::Flags CompilationInfo::flags() const {
if (IsStub()) {
return Code::ComputeFlags(code_stub()->GetCodeKind(),
code_stub()->GetICState(),
code_stub()->GetExtraICState(),
code_stub()->GetStubType());
} else {
return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
}
return code_stub() != nullptr
? Code::ComputeFlags(
code_stub()->GetCodeKind(), code_stub()->GetICState(),
code_stub()->GetExtraICState(), code_stub()->GetStubType())
: Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
}
......
......@@ -163,6 +163,7 @@ class CompilationInfo {
int num_parameters() const;
int num_heap_slots() const;
Code::Flags flags() const;
bool has_scope() const { return scope() != nullptr; }
void set_parameter_count(int parameter_count) {
DCHECK(IsStub());
......@@ -270,6 +271,11 @@ class CompilationInfo {
optimization_id_ = isolate()->NextOptimizationId();
}
void SetStub(CodeStub* code_stub) {
SetMode(STUB);
code_stub_ = code_stub;
}
// Deoptimization support.
bool HasDeoptimizationSupport() const {
return GetFlag(kDeoptimizationSupport);
......
......@@ -32,6 +32,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceInlineIsInstanceType(node, JS_ARRAY_TYPE);
case Runtime::kInlineIsFunction:
return ReduceInlineIsInstanceType(node, JS_FUNCTION_TYPE);
case Runtime::kInlineJSValueGetValue:
return ReduceInlineJSValueGetValue(node);
case Runtime::kInlineConstructDouble:
return ReduceInlineConstructDouble(node);
case Runtime::kInlineDoubleLo:
......@@ -44,6 +46,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceInlineMathFloor(node);
case Runtime::kInlineMathSqrt:
return ReduceInlineMathSqrt(node);
case Runtime::kInlineStringGetLength:
return ReduceInlineStringGetLength(node);
case Runtime::kInlineValueOf:
return ReduceInlineValueOf(node);
default:
......@@ -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) {
Node* high = NodeProperties::GetValueInput(node, 0);
Node* low = NodeProperties::GetValueInput(node, 1);
......@@ -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) {
// if (%_IsSmi(value)) {
// return value;
......@@ -258,6 +280,7 @@ Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
node->ReplaceInput(1, b);
node->ReplaceInput(2, c);
node->TrimInputCount(3);
NodeProperties::ReplaceWithValue(node, node, node);
return Changed(node);
}
......
......@@ -31,11 +31,13 @@ class JSIntrinsicLowering FINAL : public Reducer {
Reduction ReduceInlineIsSmi(Node* node);
Reduction ReduceInlineIsNonNegativeSmi(Node* node);
Reduction ReduceInlineIsInstanceType(Node* node, InstanceType instance_type);
Reduction ReduceInlineJSValueGetValue(Node* node);
Reduction ReduceInlineConstructDouble(Node* node);
Reduction ReduceInlineDoubleLo(Node* node);
Reduction ReduceInlineDoubleHi(Node* node);
Reduction ReduceInlineMathFloor(Node* node);
Reduction ReduceInlineMathSqrt(Node* node);
Reduction ReduceInlineStringGetLength(Node* node);
Reduction ReduceInlineValueOf(Node* node);
Reduction Change(Node* node, const Operator* op);
......
......@@ -315,9 +315,9 @@ class AstGraphBuilderWithPositions : public AstGraphBuilder {
source_positions_(source_positions),
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_);
return AstGraphBuilder::CreateGraph(constant_context);
return AstGraphBuilder::CreateGraph(constant_context, stack_check);
}
#define DEF_VISIT(type) \
......@@ -420,7 +420,8 @@ struct GraphBuilderPhase {
AstGraphBuilderWithPositions graph_builder(
temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
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();
}
}
......
......@@ -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) {
DCHECK(call->arguments()->length() == 2);
DCHECK_NOT_NULL(call->arguments()->at(1)->AsLiteral());
......@@ -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.
void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
DCHECK_EQ(4, call->arguments()->length());
......
......@@ -2231,7 +2231,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
F(SetInitialize) \
/* Arrays */ \
F(HasFastPackedElements) \
F(GetPrototype)
F(GetPrototype) \
/* Strings */ \
F(StringGetLength) \
/* JSValue */ \
F(JSValueGetValue)
#define GENERATOR_DECLARATION(Name) void Generate##Name(CallRuntime* call);
FOR_EACH_HYDROGEN_INTRINSIC(GENERATOR_DECLARATION)
......
......@@ -694,3 +694,14 @@ function ToPositiveInteger(x, rangeErrorName) {
// that is cloned when running the code. It is essential that the
// boilerplate gets the right prototype.
%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) {
}
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) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 2);
......
......@@ -1301,5 +1301,13 @@ RUNTIME_FUNCTION(Runtime_IsStringWrapperSafeForDefaultValueOf) {
UNIMPLEMENTED();
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
......@@ -713,7 +713,11 @@ namespace internal {
F(SetInitialize, 1, 1) \
/* Arrays */ \
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) \
......
......@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/bootstrapper.h"
#include "src/code-stubs.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/raw-machine-assembler.h"
#include "src/globals.h"
#include "src/handles.h"
#include "src/parser.h"
#include "test/cctest/compiler/function-tester.h"
#if V8_TURBOFAN_TARGET
......@@ -17,6 +17,20 @@ using namespace v8::internal;
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 {
public:
explicit StringLengthStubTF(Isolate* isolate) : CodeStub(isolate) {}
......@@ -28,18 +42,13 @@ class StringLengthStubTF : public CodeStub {
};
Handle<Code> GenerateCode() OVERRIDE {
CompilationInfoWithZone info(this, isolate());
Graph graph(info.zone());
CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
RawMachineAssembler m(isolate(), &graph, descriptor->GetMachineSignature());
Node* str = m.Load(kMachAnyTagged, m.Parameter(0),
m.Int32Constant(JSValue::kValueOffset - kHeapObjectTag));
Node* len = m.Load(kMachAnyTagged, str,
m.Int32Constant(String::kLengthOffset - kHeapObjectTag));
m.Return(len);
return Pipeline::GenerateCodeForTesting(&info, &graph, m.Export());
// Build a "hybrid" CompilationInfo for a JSFunction/CodeStub pair.
CompilationInfoWithZone info(GetFunction(isolate(), "STRING_LENGTH_STUB"));
info.SetStub(this);
// Run a "mini pipeline", extracted from compiler.cc.
CHECK(Parser::ParseStatic(info.parse_info()));
CHECK(Compiler::Analyze(info.parse_info()));
return Pipeline(&info).GenerateCode();
}
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