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") {
"src/builtins/builtins.h",
"src/cached-powers.cc",
"src/cached-powers.h",
"src/callable.h",
"src/cancelable-task.cc",
"src/cancelable-task.h",
"src/char-predicates-inl.h",
......
......@@ -476,8 +476,6 @@ Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
Node* const context, Node* const regexp, Node* const string,
Label* if_didnotmatch, const bool is_fastpath) {
Isolate* const isolate = this->isolate();
Node* const null = NullConstant();
Node* const int_zero = IntPtrConstant(0);
Node* const smi_zero = SmiConstant(Smi::kZero);
......@@ -505,9 +503,8 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
Bind(&call_tolength);
{
Callable tolength_callable = CodeFactory::ToLength(isolate);
var_lastindex.Bind(
CallStub(tolength_callable, context, regexp_lastindex));
CallBuiltin(Builtins::kToLength, context, regexp_lastindex));
Goto(&next);
}
......@@ -647,8 +644,8 @@ Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver(
Node* const method_name_str = HeapConstant(
isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED));
Callable callable = CodeFactory::ToString(isolate());
Node* const value_str = CallStub(callable, context, maybe_receiver);
Node* const value_str =
CallBuiltin(Builtins::kToString, context, maybe_receiver);
CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str,
value_str);
......@@ -1631,8 +1628,6 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
Node* const regexp,
Node* const string,
const bool is_fastpath) {
Isolate* const isolate = this->isolate();
Node* const null = NullConstant();
Node* const int_zero = IntPtrConstant(0);
Node* const smi_zero = SmiConstant(Smi::kZero);
......@@ -1745,11 +1740,9 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
Node* const match_length = LoadStringLength(match);
GotoIfNot(SmiEqual(match_length, smi_zero), &loop);
Node* last_index = LoadLastIndex(context, regexp, is_fastpath);
Callable tolength_callable = CodeFactory::ToLength(isolate);
last_index = CallStub(tolength_callable, context, last_index);
Node* const last_index =
CallBuiltin(Builtins::kToLength, context,
LoadLastIndex(context, regexp, is_fastpath));
Node* const new_last_index =
AdvanceStringIndex(string, last_index, is_unicode);
......@@ -2225,8 +2218,8 @@ TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) {
BranchIfFastRegExp(context, map, &stub, &runtime);
Bind(&stub);
Callable split_callable = CodeFactory::RegExpSplit(isolate());
Return(CallStub(split_callable, context, receiver, string, maybe_limit));
Return(CallBuiltin(Builtins::kRegExpSplit, context, receiver, string,
maybe_limit));
Bind(&runtime);
Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string,
......@@ -2564,15 +2557,14 @@ TF_BUILTIN(RegExpReplace, RegExpBuiltinsAssembler) {
// 3. Does ToString({replace_value}) contain '$'?
Bind(&checkreplacestring);
{
Callable tostring_callable = CodeFactory::ToString(isolate());
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(
isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
Node* const dollar_ix = CallStub(indexof_callable, context, replace_string,
dollar_string, SmiConstant(0));
Node* const dollar_ix =
CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
dollar_string, SmiConstant(0));
GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
Return(
......@@ -2636,16 +2628,15 @@ TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) {
Node* const receiver = maybe_receiver;
// Convert {maybe_string} to a String.
Callable tostring_callable = CodeFactory::ToString(isolate());
Node* const string = CallStub(tostring_callable, context, maybe_string);
Node* const string = CallBuiltin(Builtins::kToString, context, maybe_string);
// Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
Label stub(this), runtime(this, Label::kDeferred);
BranchIfFastRegExp(context, map, &stub, &runtime);
Bind(&stub);
Callable replace_callable = CodeFactory::RegExpReplace(isolate());
Return(CallStub(replace_callable, context, receiver, string, replace_value));
Return(CallBuiltin(Builtins::kRegExpReplace, context, receiver, string,
replace_value));
Bind(&runtime);
Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string,
......
......@@ -5,6 +5,7 @@
#include "src/builtins/builtins.h"
#include "src/api.h"
#include "src/assembler-inl.h"
#include "src/callable.h"
#include "src/code-events.h"
#include "src/compiler/code-assembler.h"
#include "src/ic/ic-state.h"
......@@ -274,6 +275,23 @@ Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) {
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
const char* Builtins::name(int index) {
switch (index) {
......
......@@ -11,6 +11,7 @@
namespace v8 {
namespace internal {
class Callable;
template <typename T>
class Handle;
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_TFS(V) \
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, V, \
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
#define BUILTIN_LIST_C(V) \
BUILTIN_LIST(V, V, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
IGNORE_BUILTIN, IGNORE_BUILTIN)
......@@ -959,6 +964,8 @@ class Builtins {
return reinterpret_cast<Address>(&builtins_[name]);
}
static Callable CallableFor(Isolate* isolate, Name name);
static const char* name(int index);
// 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 @@
#include "src/allocation.h"
#include "src/assembler.h"
#include "src/callable.h"
#include "src/codegen.h"
#include "src/globals.h"
#include "src/interface-descriptors.h"
......@@ -14,20 +15,6 @@
namespace v8 {
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 {
public:
// CEntryStub has var-args semantics (all the arguments are passed on the
......
......@@ -1026,6 +1026,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
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,
Node* name_index, Variable* var_details,
Variable* var_value);
......
......@@ -533,6 +533,7 @@
'builtins/builtins.h',
'cached-powers.cc',
'cached-powers.h',
'callable.h',
'cancelable-task.cc',
'cancelable-task.h',
'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