Commit a4c73fa7 authored by jgruber's avatar jgruber Committed by Commit bot

[csa] Add CSA::CallBuiltin and Builtins::CallableFor

This is another step towards making calls to builtins more convenient.

Builtins::CallableFor is an automatically generated Callable accessor for TFS
builtins (whereas previously we had to manually add an accessor to
code-factory.{h,cc}).

CSA::CallBuiltin is a convenience wrapper around CallStub for TFS builtins.

We can begin removing accessors for TFS builtins from CodeFactory in an
upcoming commit.

BUG=v8:5737

Review-Url: https://codereview.chromium.org/2752213002
Cr-Commit-Position: refs/heads/master@{#43865}
parent 11f69171
...@@ -1056,6 +1056,7 @@ v8_source_set("v8_base") { ...@@ -1056,6 +1056,7 @@ v8_source_set("v8_base") {
"src/builtins/builtins.h", "src/builtins/builtins.h",
"src/cached-powers.cc", "src/cached-powers.cc",
"src/cached-powers.h", "src/cached-powers.h",
"src/callable.h",
"src/cancelable-task.cc", "src/cancelable-task.cc",
"src/cancelable-task.h", "src/cancelable-task.h",
"src/char-predicates-inl.h", "src/char-predicates-inl.h",
......
...@@ -476,8 +476,6 @@ Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context, ...@@ -476,8 +476,6 @@ Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
Node* const context, Node* const regexp, Node* const string, Node* const context, Node* const regexp, Node* const string,
Label* if_didnotmatch, const bool is_fastpath) { Label* if_didnotmatch, const bool is_fastpath) {
Isolate* const isolate = this->isolate();
Node* const null = NullConstant(); Node* const null = NullConstant();
Node* const int_zero = IntPtrConstant(0); Node* const int_zero = IntPtrConstant(0);
Node* const smi_zero = SmiConstant(Smi::kZero); Node* const smi_zero = SmiConstant(Smi::kZero);
...@@ -505,9 +503,8 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( ...@@ -505,9 +503,8 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
Bind(&call_tolength); Bind(&call_tolength);
{ {
Callable tolength_callable = CodeFactory::ToLength(isolate);
var_lastindex.Bind( var_lastindex.Bind(
CallStub(tolength_callable, context, regexp_lastindex)); CallBuiltin(Builtins::kToLength, context, regexp_lastindex));
Goto(&next); Goto(&next);
} }
...@@ -647,8 +644,8 @@ Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver( ...@@ -647,8 +644,8 @@ Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver(
Node* const method_name_str = HeapConstant( Node* const method_name_str = HeapConstant(
isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED)); isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED));
Callable callable = CodeFactory::ToString(isolate()); Node* const value_str =
Node* const value_str = CallStub(callable, context, maybe_receiver); CallBuiltin(Builtins::kToString, context, maybe_receiver);
CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str, CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str,
value_str); value_str);
...@@ -1631,8 +1628,6 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, ...@@ -1631,8 +1628,6 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
Node* const regexp, Node* const regexp,
Node* const string, Node* const string,
const bool is_fastpath) { const bool is_fastpath) {
Isolate* const isolate = this->isolate();
Node* const null = NullConstant(); Node* const null = NullConstant();
Node* const int_zero = IntPtrConstant(0); Node* const int_zero = IntPtrConstant(0);
Node* const smi_zero = SmiConstant(Smi::kZero); Node* const smi_zero = SmiConstant(Smi::kZero);
...@@ -1745,11 +1740,9 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, ...@@ -1745,11 +1740,9 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
Node* const match_length = LoadStringLength(match); Node* const match_length = LoadStringLength(match);
GotoIfNot(SmiEqual(match_length, smi_zero), &loop); GotoIfNot(SmiEqual(match_length, smi_zero), &loop);
Node* last_index = LoadLastIndex(context, regexp, is_fastpath); Node* const last_index =
CallBuiltin(Builtins::kToLength, context,
Callable tolength_callable = CodeFactory::ToLength(isolate); LoadLastIndex(context, regexp, is_fastpath));
last_index = CallStub(tolength_callable, context, last_index);
Node* const new_last_index = Node* const new_last_index =
AdvanceStringIndex(string, last_index, is_unicode); AdvanceStringIndex(string, last_index, is_unicode);
...@@ -2225,8 +2218,8 @@ TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { ...@@ -2225,8 +2218,8 @@ TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) {
BranchIfFastRegExp(context, map, &stub, &runtime); BranchIfFastRegExp(context, map, &stub, &runtime);
Bind(&stub); Bind(&stub);
Callable split_callable = CodeFactory::RegExpSplit(isolate()); Return(CallBuiltin(Builtins::kRegExpSplit, context, receiver, string,
Return(CallStub(split_callable, context, receiver, string, maybe_limit)); maybe_limit));
Bind(&runtime); Bind(&runtime);
Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string, Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string,
...@@ -2564,15 +2557,14 @@ TF_BUILTIN(RegExpReplace, RegExpBuiltinsAssembler) { ...@@ -2564,15 +2557,14 @@ TF_BUILTIN(RegExpReplace, RegExpBuiltinsAssembler) {
// 3. Does ToString({replace_value}) contain '$'? // 3. Does ToString({replace_value}) contain '$'?
Bind(&checkreplacestring); Bind(&checkreplacestring);
{ {
Callable tostring_callable = CodeFactory::ToString(isolate());
Node* const replace_string = Node* const replace_string =
CallStub(tostring_callable, context, replace_value); CallBuiltin(Builtins::kToString, context, replace_value);
Callable indexof_callable = CodeFactory::StringIndexOf(isolate());
Node* const dollar_string = HeapConstant( Node* const dollar_string = HeapConstant(
isolate()->factory()->LookupSingleCharacterStringFromCode('$')); isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
Node* const dollar_ix = CallStub(indexof_callable, context, replace_string, Node* const dollar_ix =
dollar_string, SmiConstant(0)); CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
dollar_string, SmiConstant(0));
GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
Return( Return(
...@@ -2636,16 +2628,15 @@ TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) { ...@@ -2636,16 +2628,15 @@ TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) {
Node* const receiver = maybe_receiver; Node* const receiver = maybe_receiver;
// Convert {maybe_string} to a String. // Convert {maybe_string} to a String.
Callable tostring_callable = CodeFactory::ToString(isolate()); Node* const string = CallBuiltin(Builtins::kToString, context, maybe_string);
Node* const string = CallStub(tostring_callable, context, maybe_string);
// Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
Label stub(this), runtime(this, Label::kDeferred); Label stub(this), runtime(this, Label::kDeferred);
BranchIfFastRegExp(context, map, &stub, &runtime); BranchIfFastRegExp(context, map, &stub, &runtime);
Bind(&stub); Bind(&stub);
Callable replace_callable = CodeFactory::RegExpReplace(isolate()); Return(CallBuiltin(Builtins::kRegExpReplace, context, receiver, string,
Return(CallStub(replace_callable, context, receiver, string, replace_value)); replace_value));
Bind(&runtime); Bind(&runtime);
Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string, Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
#include "src/api.h" #include "src/api.h"
#include "src/assembler-inl.h" #include "src/assembler-inl.h"
#include "src/callable.h"
#include "src/code-events.h" #include "src/code-events.h"
#include "src/compiler/code-assembler.h" #include "src/compiler/code-assembler.h"
#include "src/ic/ic-state.h" #include "src/ic/ic-state.h"
...@@ -274,6 +275,23 @@ Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { ...@@ -274,6 +275,23 @@ Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) {
return Handle<Code>::null(); return Handle<Code>::null();
} }
// static
Callable Builtins::CallableFor(Isolate* isolate, Name name) {
switch (name) {
#define CASE(Name, _, __, InterfaceDescriptor, ...) \
case k##Name: { \
Handle<Code> code(Code::cast(isolate->builtins()->builtins_[name])); \
auto descriptor = InterfaceDescriptor##Descriptor(isolate); \
return Callable(code, descriptor); \
}
BUILTIN_LIST_TFS(CASE)
#undef CASE
default:
UNREACHABLE();
return Callable(Handle<Code>::null(), VoidDescriptor(isolate));
}
}
// static // static
const char* Builtins::name(int index) { const char* Builtins::name(int index) {
switch (index) { switch (index) {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class Callable;
template <typename T> template <typename T>
class Handle; class Handle;
class Isolate; class Isolate;
...@@ -886,6 +887,10 @@ class Isolate; ...@@ -886,6 +887,10 @@ class Isolate;
#define BUILTIN_LIST_ALL(V) BUILTIN_LIST(V, V, V, V, V, V, V) #define BUILTIN_LIST_ALL(V) BUILTIN_LIST(V, V, V, V, V, V, V)
#define BUILTIN_LIST_TFS(V) \
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, V, \
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
#define BUILTIN_LIST_C(V) \ #define BUILTIN_LIST_C(V) \
BUILTIN_LIST(V, V, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \ BUILTIN_LIST(V, V, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
IGNORE_BUILTIN, IGNORE_BUILTIN) IGNORE_BUILTIN, IGNORE_BUILTIN)
...@@ -959,6 +964,8 @@ class Builtins { ...@@ -959,6 +964,8 @@ class Builtins {
return reinterpret_cast<Address>(&builtins_[name]); return reinterpret_cast<Address>(&builtins_[name]);
} }
static Callable CallableFor(Isolate* isolate, Name name);
static const char* name(int index); static const char* name(int index);
// Returns the C++ entry point for builtins implemented in C++, and the null // Returns the C++ entry point for builtins implemented in C++, and the null
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CALLABLE_H_
#define V8_CALLABLE_H_
#include "src/allocation.h"
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
class Code;
// Associates a body of code with an interface descriptor.
class Callable final BASE_EMBEDDED {
public:
Callable(Handle<Code> code, CallInterfaceDescriptor descriptor)
: code_(code), descriptor_(descriptor) {}
Handle<Code> code() const { return code_; }
CallInterfaceDescriptor descriptor() const { return descriptor_; }
private:
const Handle<Code> code_;
const CallInterfaceDescriptor descriptor_;
};
} // namespace internal
} // namespace v8
#endif // V8_CALLABLE_H_
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/allocation.h" #include "src/allocation.h"
#include "src/assembler.h" #include "src/assembler.h"
#include "src/callable.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/globals.h" #include "src/globals.h"
#include "src/interface-descriptors.h" #include "src/interface-descriptors.h"
...@@ -14,20 +15,6 @@ ...@@ -14,20 +15,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// Associates a body of code with an interface descriptor.
class Callable final BASE_EMBEDDED {
public:
Callable(Handle<Code> code, CallInterfaceDescriptor descriptor)
: code_(code), descriptor_(descriptor) {}
Handle<Code> code() const { return code_; }
CallInterfaceDescriptor descriptor() const { return descriptor_; }
private:
const Handle<Code> code_;
const CallInterfaceDescriptor descriptor_;
};
class V8_EXPORT_PRIVATE CodeFactory final { class V8_EXPORT_PRIVATE CodeFactory final {
public: public:
// CEntryStub has var-args semantics (all the arguments are passed on the // CEntryStub has var-args semantics (all the arguments are passed on the
......
...@@ -1026,6 +1026,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -1026,6 +1026,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
name); name);
} }
template <class... TArgs>
Node* CallBuiltin(Builtins::Name id, Node* context, TArgs... args) {
return CallStub(Builtins::CallableFor(isolate(), id), context, args...);
}
void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors, void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors,
Node* name_index, Variable* var_details, Node* name_index, Variable* var_details,
Variable* var_value); Variable* var_value);
......
...@@ -533,6 +533,7 @@ ...@@ -533,6 +533,7 @@
'builtins/builtins.h', 'builtins/builtins.h',
'cached-powers.cc', 'cached-powers.cc',
'cached-powers.h', 'cached-powers.h',
'callable.h',
'cancelable-task.cc', 'cancelable-task.cc',
'cancelable-task.h', 'cancelable-task.h',
'char-predicates.cc', 'char-predicates.cc',
......
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