Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Unified Diff: src/builtins.cc

Issue 1824993002: [builtins] Add support for JS builtins written in TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins.h ('k') | src/compiler/code-stub-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index adb0340023bc885c8c69e044605722e124177ce0..82eca8c1f11ac8e86154e26c8e7961e25f53da81 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -9,6 +9,8 @@
#include "src/api-natives.h"
#include "src/base/once.h"
#include "src/bootstrapper.h"
+#include "src/code-factory.h"
+#include "src/compiler/code-stub-assembler.h"
#include "src/dateparser-inl.h"
#include "src/elements.h"
#include "src/frames-inl.h"
@@ -2012,6 +2014,81 @@ BUILTIN(MathImul) {
return *isolate->factory()->NewNumberFromInt(product);
}
+// ES6 section 20.2.2.32 Math.sqrt ( x )
+void Builtins::Generate_MathSqrt(compiler::CodeStubAssembler* assembler) {
+ typedef compiler::CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef compiler::CodeStubAssembler::Variable Variable;
+
+ Node* context = assembler->Parameter(4);
+
+ // Shared entry for the floating point sqrt.
+ Label do_fsqrt(assembler);
+ Variable var_fsqrt_x(assembler, MachineRepresentation::kFloat64);
+
+ // We might need to loop once due to the ToNumber conversion.
+ Variable var_x(assembler, MachineRepresentation::kTagged);
+ Label loop(assembler, &var_x);
+ var_x.Bind(assembler->Parameter(1));
+ assembler->Goto(&loop);
+ assembler->Bind(&loop);
+ {
+ // Load the current {x} value.
+ Node* x = var_x.value();
+
+ // Check if {x} is a Smi or a HeapObject.
+ Label if_xissmi(assembler), if_xisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(x), &if_xissmi, &if_xisnotsmi);
+
+ assembler->Bind(&if_xissmi);
+ {
+ // Perform the floating point sqrt.
+ var_fsqrt_x.Bind(assembler->SmiToFloat64(x));
+ assembler->Goto(&do_fsqrt);
+ }
+
+ assembler->Bind(&if_xisnotsmi);
+ {
+ // Load the map of {x}.
+ Node* x_map = assembler->LoadMap(x);
+
+ // Check if {x} is a HeapNumber.
+ Label if_xisnumber(assembler),
+ if_xisnotnumber(assembler, Label::kDeferred);
+ assembler->Branch(
+ assembler->WordEqual(x_map, assembler->HeapNumberMapConstant()),
+ &if_xisnumber, &if_xisnotnumber);
+
+ assembler->Bind(&if_xisnumber);
+ {
+ // Perform the floating point sqrt.
+ var_fsqrt_x.Bind(assembler->LoadHeapNumberValue(x));
+ assembler->Goto(&do_fsqrt);
+ }
+
+ assembler->Bind(&if_xisnotnumber);
+ {
+ // Convert {x} to a Number first.
+ Callable callable =
+ CodeFactory::NonNumberToNumber(assembler->isolate());
+ var_x.Bind(assembler->CallStub(callable, context, x));
+ assembler->Goto(&loop);
+ }
+ }
+ }
+
+ assembler->Bind(&do_fsqrt);
+ {
+ Node* x = var_fsqrt_x.value();
+ Node* value = assembler->Float64Sqrt(x);
+ Node* result = assembler->Allocate(HeapNumber::kSize,
+ compiler::CodeStubAssembler::kNone);
+ assembler->StoreMapNoWriteBarrier(result,
+ assembler->HeapNumberMapConstant());
+ assembler->StoreHeapNumberValue(result, value);
+ assembler->Return(result);
+ }
+}
// -----------------------------------------------------------------------------
// ES6 section 26.1 The Reflect Object
@@ -4275,12 +4352,14 @@ Address const Builtins::c_functions_[cfunction_count] = {
struct BuiltinDesc {
+ Handle<Code> (*builder)(Isolate*, struct BuiltinDesc const*);
byte* generator;
byte* c_code;
const char* s_name; // name is only used for generating log information.
int name;
Code::Flags flags;
BuiltinExtraArguments extra_args;
+ int argc;
};
#define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} }
@@ -4298,8 +4377,60 @@ class BuiltinFunctionTable {
friend class Builtins;
};
-static BuiltinFunctionTable builtin_function_table =
- BUILTIN_FUNCTION_TABLE_INIT;
+namespace {
+
+BuiltinFunctionTable builtin_function_table = BUILTIN_FUNCTION_TABLE_INIT;
+
+Handle<Code> MacroAssemblerBuilder(Isolate* isolate,
+ BuiltinDesc const* builtin_desc) {
+// For now we generate builtin adaptor code into a stack-allocated
+// buffer, before copying it into individual code objects. Be careful
+// with alignment, some platforms don't like unaligned code.
+#ifdef DEBUG
+ // We can generate a lot of debug code on Arm64.
+ const size_t buffer_size = 32 * KB;
+#elif V8_TARGET_ARCH_PPC64
+ // 8 KB is insufficient on PPC64 when FLAG_debug_code is on.
+ const size_t buffer_size = 10 * KB;
+#else
+ const size_t buffer_size = 8 * KB;
+#endif
+ union {
+ int force_alignment;
+ byte buffer[buffer_size]; // NOLINT(runtime/arrays)
+ } u;
+
+ MacroAssembler masm(isolate, u.buffer, sizeof(u.buffer),
+ CodeObjectRequired::kYes);
+ // Generate the code/adaptor.
+ typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
+ Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator);
+ // We pass all arguments to the generator, but it may not use all of
+ // them. This works because the first arguments are on top of the
+ // stack.
+ DCHECK(!masm.has_frame());
+ g(&masm, builtin_desc->name, builtin_desc->extra_args);
+ // Move the code into the object heap.
+ CodeDesc desc;
+ masm.GetCode(&desc);
+ Code::Flags flags = builtin_desc->flags;
+ return isolate->factory()->NewCode(desc, flags, masm.CodeObject());
+}
+
+Handle<Code> CodeStubAssemblerBuilder(Isolate* isolate,
+ BuiltinDesc const* builtin_desc) {
+ Zone zone;
+ compiler::CodeStubAssembler assembler(isolate, &zone, builtin_desc->argc,
+ builtin_desc->flags,
+ builtin_desc->s_name);
+ // Generate the code/adaptor.
+ typedef void (*Generator)(compiler::CodeStubAssembler*);
+ Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator);
+ g(&assembler);
+ return assembler.GenerateCode();
+}
+
+} // namespace
// Define array of pointers to generators and C builtin functions.
// We do this in a sort of roundabout way so that we can do the initialization
@@ -4307,47 +4438,70 @@ static BuiltinFunctionTable builtin_function_table =
// Code::Flags names a non-abstract type.
void Builtins::InitBuiltinFunctionTable() {
BuiltinDesc* functions = builtin_function_table.functions_;
- functions[builtin_count].generator = NULL;
- functions[builtin_count].c_code = NULL;
- functions[builtin_count].s_name = NULL;
+ functions[builtin_count].builder = nullptr;
+ functions[builtin_count].generator = nullptr;
+ functions[builtin_count].c_code = nullptr;
+ functions[builtin_count].s_name = nullptr;
functions[builtin_count].name = builtin_count;
functions[builtin_count].flags = static_cast<Code::Flags>(0);
functions[builtin_count].extra_args = BuiltinExtraArguments::kNone;
+ functions[builtin_count].argc = 0;
#define DEF_FUNCTION_PTR_C(aname, aextra_args) \
+ functions->builder = &MacroAssemblerBuilder; \
functions->generator = FUNCTION_ADDR(Generate_Adaptor); \
functions->c_code = FUNCTION_ADDR(Builtin_##aname); \
functions->s_name = #aname; \
functions->name = c_##aname; \
functions->flags = Code::ComputeFlags(Code::BUILTIN); \
functions->extra_args = BuiltinExtraArguments::aextra_args; \
+ functions->argc = 0; \
++functions;
#define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \
+ functions->builder = &MacroAssemblerBuilder; \
functions->generator = FUNCTION_ADDR(Generate_##aname); \
functions->c_code = NULL; \
functions->s_name = #aname; \
functions->name = k##aname; \
functions->flags = Code::ComputeFlags(Code::kind, state, extra); \
functions->extra_args = BuiltinExtraArguments::kNone; \
+ functions->argc = 0; \
+ ++functions;
+
+#define DEF_FUNCTION_PTR_T(aname, aargc) \
+ functions->builder = &CodeStubAssemblerBuilder; \
+ functions->generator = FUNCTION_ADDR(Generate_##aname); \
+ functions->c_code = NULL; \
+ functions->s_name = #aname; \
+ functions->name = k##aname; \
+ functions->flags = \
+ Code::ComputeFlags(Code::BUILTIN, UNINITIALIZED, kNoExtraICState); \
+ functions->extra_args = BuiltinExtraArguments::kNone; \
+ functions->argc = aargc; \
++functions;
#define DEF_FUNCTION_PTR_H(aname, kind) \
+ functions->builder = &MacroAssemblerBuilder; \
functions->generator = FUNCTION_ADDR(Generate_##aname); \
functions->c_code = NULL; \
functions->s_name = #aname; \
functions->name = k##aname; \
functions->flags = Code::ComputeHandlerFlags(Code::kind); \
functions->extra_args = BuiltinExtraArguments::kNone; \
+ functions->argc = 0; \
++functions;
BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
+ BUILTIN_LIST_T(DEF_FUNCTION_PTR_T)
BUILTIN_LIST_H(DEF_FUNCTION_PTR_H)
BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
#undef DEF_FUNCTION_PTR_C
#undef DEF_FUNCTION_PTR_A
+#undef DEF_FUNCTION_PTR_H
+#undef DEF_FUNCTION_PTR_T
}
@@ -4359,40 +4513,11 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
const BuiltinDesc* functions = builtin_function_table.functions();
- // For now we generate builtin adaptor code into a stack-allocated
- // buffer, before copying it into individual code objects. Be careful
- // with alignment, some platforms don't like unaligned code.
-#ifdef DEBUG
- // We can generate a lot of debug code on Arm64.
- const size_t buffer_size = 32*KB;
-#elif V8_TARGET_ARCH_PPC64
- // 8 KB is insufficient on PPC64 when FLAG_debug_code is on.
- const size_t buffer_size = 10 * KB;
-#else
- const size_t buffer_size = 8*KB;
-#endif
- union { int force_alignment; byte buffer[buffer_size]; } u;
-
// Traverse the list of builtins and generate an adaptor in a
// separate code object for each one.
for (int i = 0; i < builtin_count; i++) {
if (create_heap_objects) {
- MacroAssembler masm(isolate, u.buffer, sizeof u.buffer,
- CodeObjectRequired::kYes);
- // Generate the code/adaptor.
- typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
- Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
- // We pass all arguments to the generator, but it may not use all of
- // them. This works because the first arguments are on top of the
- // stack.
- DCHECK(!masm.has_frame());
- g(&masm, functions[i].name, functions[i].extra_args);
- // Move the code into the object heap.
- CodeDesc desc;
- masm.GetCode(&desc);
- Code::Flags flags = functions[i].flags;
- Handle<Code> code =
- isolate->factory()->NewCode(desc, flags, masm.CodeObject());
+ Handle<Code> code = (*functions[i].builder)(isolate, functions + i);
// Log the event and add the code to the builtins array.
PROFILE(isolate,
CodeCreateEvent(Logger::BUILTIN_TAG, AbstractCode::cast(*code),
@@ -4466,6 +4591,11 @@ Handle<Code> Builtins::name() { \
reinterpret_cast<Code**>(builtin_address(k##name)); \
return Handle<Code>(code_address); \
}
+#define DEFINE_BUILTIN_ACCESSOR_T(name, argc) \
+ Handle<Code> Builtins::name() { \
+ Code** code_address = reinterpret_cast<Code**>(builtin_address(k##name)); \
+ return Handle<Code>(code_address); \
+ }
#define DEFINE_BUILTIN_ACCESSOR_H(name, kind) \
Handle<Code> Builtins::name() { \
Code** code_address = \
@@ -4474,11 +4604,13 @@ Handle<Code> Builtins::name() { \
}
BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
+BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T)
BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
#undef DEFINE_BUILTIN_ACCESSOR_C
#undef DEFINE_BUILTIN_ACCESSOR_A
-
+#undef DEFINE_BUILTIN_ACCESSOR_T
+#undef DEFINE_BUILTIN_ACCESSOR_H
} // namespace internal
} // namespace v8
« no previous file with comments | « src/builtins.h ('k') | src/compiler/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698