Commit c07c675e authored by danno's avatar danno Committed by Commit bot

Add a flag to help platform ports bootstrap V8

A "--minimal" flag turns off all optimizing compilers and activates the
interpreter. The idea is that with this flag activated, only the
platform-specific stubs and a Turbofan implementation must be complete to start
d8 and run the bulk of the tests. Note that although this flag is constructed as
a runtime flag, it must be set to true when building the snapshot and therefore
creates a compile-time dependency.

BUG=chromium:608675

Review-Url: https://codereview.chromium.org/2189663002
Cr-Commit-Position: refs/heads/master@{#38150}
parent b9e9e846
......@@ -1156,6 +1156,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallFunction(prototype, factory->apply_string(),
Builtins::kFunctionPrototypeApply, 2, false);
if (FLAG_minimal) {
SimpleInstallFunction(prototype, factory->bind_string(),
Builtins::kFunctionPrototypeBind, 1, false);
} else {
FastFunctionBindStub bind_stub(isolate);
Handle<JSFunction> bind_function = factory->NewFunctionWithoutPrototype(
factory->bind_string(), bind_stub.GetCode(), false);
......@@ -1163,6 +1167,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
bind_function->shared()->set_length(1);
InstallFunction(prototype, bind_function, factory->bind_string(),
DONT_ENUM);
}
SimpleInstallFunction(prototype, factory->call_string(),
Builtins::kFunctionPrototypeCall, 1, false);
......
......@@ -248,12 +248,56 @@ Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(
return new_object;
}
Handle<Code> HydrogenCodeStub::GenerateRuntimeTailCall(
CodeStubDescriptor* descriptor) {
const char* name = CodeStub::MajorName(MajorKey());
Zone zone(isolate()->allocator());
CallInterfaceDescriptor interface_descriptor(GetCallInterfaceDescriptor());
CodeStubAssembler assembler(isolate(), &zone, interface_descriptor,
GetCodeFlags(), name);
int total_params = interface_descriptor.GetStackParameterCount() +
interface_descriptor.GetRegisterParameterCount();
switch (total_params) {
case 0:
assembler.TailCallRuntime(descriptor->miss_handler_id(),
assembler.Parameter(0));
break;
case 1:
assembler.TailCallRuntime(descriptor->miss_handler_id(),
assembler.Parameter(1), assembler.Parameter(0));
break;
case 2:
assembler.TailCallRuntime(descriptor->miss_handler_id(),
assembler.Parameter(2), assembler.Parameter(0),
assembler.Parameter(1));
break;
case 3:
assembler.TailCallRuntime(descriptor->miss_handler_id(),
assembler.Parameter(3), assembler.Parameter(0),
assembler.Parameter(1), assembler.Parameter(2));
break;
case 4:
assembler.TailCallRuntime(descriptor->miss_handler_id(),
assembler.Parameter(4), assembler.Parameter(0),
assembler.Parameter(1), assembler.Parameter(2),
assembler.Parameter(3));
break;
default:
UNIMPLEMENTED();
break;
}
return assembler.GenerateCode();
}
template <class Stub>
static Handle<Code> DoGenerateCode(Stub* stub) {
Isolate* isolate = stub->isolate();
CodeStubDescriptor descriptor(stub);
if (FLAG_minimal && descriptor.has_miss_handler()) {
return stub->GenerateRuntimeTailCall(&descriptor);
}
// If we are uninitialized we can use a light-weight stub to enter
// the runtime that is significantly faster than using the standard
// stub-failure deopt mechanism.
......
......@@ -25,9 +25,9 @@ RUNTIME_FUNCTION(UnexpectedStubMiss) {
return Smi::FromInt(0);
}
CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub)
: call_descriptor_(stub->GetCallInterfaceDescriptor()),
: isolate_(stub->isolate()),
call_descriptor_(stub->GetCallInterfaceDescriptor()),
stack_parameter_count_(no_reg),
hint_stack_parameter_count_(-1),
function_mode_(NOT_JS_FUNCTION_STUB_MODE),
......@@ -37,9 +37,9 @@ CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub)
stub->InitializeDescriptor(this);
}
CodeStubDescriptor::CodeStubDescriptor(Isolate* isolate, uint32_t stub_key)
: stack_parameter_count_(no_reg),
: isolate_(isolate),
stack_parameter_count_(no_reg),
hint_stack_parameter_count_(-1),
function_mode_(NOT_JS_FUNCTION_STUB_MODE),
deoptimization_handler_(NULL),
......@@ -270,6 +270,7 @@ MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
// static
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
if (FLAG_minimal) return;
// Generate the uninitialized versions of the stub.
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
BinaryOpICStub stub(isolate, static_cast<Token::Value>(op));
......@@ -289,6 +290,7 @@ void BinaryOpICStub::PrintState(std::ostream& os) const { // NOLINT
// static
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
const BinaryOpICState& state) {
if (FLAG_minimal) return;
BinaryOpICStub stub(isolate, state);
stub.GetCode();
}
......@@ -4090,6 +4092,7 @@ void ElementsTransitionAndStoreStub::InitializeDescriptor(
void ToObjectStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(Runtime::FunctionForId(Runtime::kToObject)->entry);
descriptor->SetMissHandler(Runtime::kToObject);
}
void StoreTransitionStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
......@@ -4097,11 +4100,14 @@ void StoreTransitionStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
FUNCTION_ADDR(Runtime_TransitionStoreIC_MissFromStubFailure));
}
void TypeofStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {}
void TypeofStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->SetMissHandler(Runtime::kTypeof);
}
void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(
Runtime::FunctionForId(Runtime::kNumberToString)->entry);
descriptor->SetMissHandler(Runtime::kNumberToString);
}
......@@ -4109,6 +4115,7 @@ void FastCloneRegExpStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
FastCloneRegExpDescriptor call_descriptor(isolate());
descriptor->Initialize(
Runtime::FunctionForId(Runtime::kCreateRegExpLiteral)->entry);
descriptor->SetMissHandler(Runtime::kCreateRegExpLiteral);
}
......@@ -4117,13 +4124,14 @@ void FastCloneShallowArrayStub::InitializeDescriptor(
FastCloneShallowArrayDescriptor call_descriptor(isolate());
descriptor->Initialize(
Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry);
descriptor->SetMissHandler(Runtime::kCreateArrayLiteralStubBailout);
}
void RegExpConstructResultStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
descriptor->Initialize(
Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry);
descriptor->SetMissHandler(Runtime::kRegExpConstructResult);
}
......@@ -4152,15 +4160,13 @@ SIMD128_TYPES(SIMD128_INIT_DESC)
void ToBooleanICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(FUNCTION_ADDR(Runtime_ToBooleanIC_Miss));
descriptor->SetMissHandler(ExternalReference(
Runtime::FunctionForId(Runtime::kToBooleanIC_Miss), isolate()));
descriptor->SetMissHandler(Runtime::kToBooleanIC_Miss);
}
void BinaryOpICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(FUNCTION_ADDR(Runtime_BinaryOpIC_Miss));
descriptor->SetMissHandler(ExternalReference(
Runtime::FunctionForId(Runtime::kBinaryOpIC_Miss), isolate()));
descriptor->SetMissHandler(Runtime::kBinaryOpIC_Miss);
}
......@@ -4173,6 +4179,7 @@ void BinaryOpWithAllocationSiteStub::InitializeDescriptor(
void StringAddStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(Runtime::FunctionForId(Runtime::kStringAdd)->entry);
descriptor->SetMissHandler(Runtime::kStringAdd);
}
......@@ -4575,6 +4582,7 @@ void StoreElementStub::Generate(MacroAssembler* masm) {
// static
void StoreFastElementStub::GenerateAheadOfTime(Isolate* isolate) {
if (FLAG_minimal) return;
StoreFastElementStub(isolate, false, FAST_HOLEY_ELEMENTS, STANDARD_STORE)
.GetCode();
StoreFastElementStub(isolate, false, FAST_HOLEY_ELEMENTS,
......
......@@ -48,7 +48,6 @@ namespace internal {
V(SubString) \
V(ToString) \
V(ToName) \
V(ToObject) \
V(StoreICTrampoline) \
V(KeyedStoreICTrampoline) \
V(StoreIC) \
......@@ -74,6 +73,7 @@ namespace internal {
V(LoadDictionaryElement) \
V(NameDictionaryLookup) \
V(NumberToString) \
V(ToObject) \
V(Typeof) \
V(RegExpConstructResult) \
V(StoreFastElement) \
......@@ -487,8 +487,9 @@ class CodeStubDescriptor {
int hint_stack_parameter_count = -1,
StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
void SetMissHandler(ExternalReference handler) {
miss_handler_ = handler;
void SetMissHandler(Runtime::FunctionId id) {
miss_handler_id_ = id;
miss_handler_ = ExternalReference(Runtime::FunctionForId(id), isolate_);
has_miss_handler_ = true;
// Our miss handler infrastructure doesn't currently support
// variable stack parameter counts.
......@@ -523,6 +524,11 @@ class CodeStubDescriptor {
return miss_handler_;
}
Runtime::FunctionId miss_handler_id() const {
DCHECK(has_miss_handler_);
return miss_handler_id_;
}
bool has_miss_handler() const {
return has_miss_handler_;
}
......@@ -545,6 +551,7 @@ class CodeStubDescriptor {
return stack_parameter_count_.is_valid();
}
Isolate* isolate_;
CallInterfaceDescriptor call_descriptor_;
Register stack_parameter_count_;
// If hint_stack_parameter_count_ > 0, the code stub can optimize the
......@@ -555,6 +562,7 @@ class CodeStubDescriptor {
Address deoptimization_handler_;
ExternalReference miss_handler_;
Runtime::FunctionId miss_handler_id_;
bool has_miss_handler_;
};
......@@ -579,6 +587,8 @@ class HydrogenCodeStub : public CodeStub {
Handle<Code> GenerateLightweightMissCode(ExternalReference miss);
Handle<Code> GenerateRuntimeTailCall(CodeStubDescriptor* descriptor);
template<class StateType>
void TraceTransition(StateType from, StateType to);
......
......@@ -1360,6 +1360,7 @@ void HGraphBuilder::LoopBuilder::EndBody() {
HGraph* HGraphBuilder::CreateGraph() {
DCHECK(!FLAG_minimal);
graph_ = new (zone()) HGraph(info_, descriptor_);
if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
if (!info_->IsStub() && info_->is_tracking_positions()) {
......
......@@ -491,6 +491,14 @@ DEFINE_BOOL(turbo_stress_instruction_scheduling, false,
DEFINE_BOOL(turbo_store_elimination, false,
"enable store-store elimination in TurboFan")
// Flags to help platform porters
DEFINE_BOOL(minimal, false,
"simplifies execution model to make porting "
"easier (e.g. always use Ignition, never use Crankshaft")
DEFINE_IMPLICATION(minimal, ignition)
DEFINE_NEG_IMPLICATION(minimal, crankshaft)
DEFINE_NEG_IMPLICATION(minimal, use_ic)
// Flags for native WebAssembly.
DEFINE_BOOL(expose_wasm, false, "expose WASM interface to JavaScript")
DEFINE_INT(wasm_num_compilation_tasks, 10,
......
......@@ -29,6 +29,7 @@ namespace internal {
bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
Isolate* isolate = info->isolate();
DCHECK(!FLAG_minimal);
RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileFullCode);
TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
......
......@@ -53,8 +53,12 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
isolate->factory()->NewJSObject(isolate->object_function());
InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
if (FLAG_minimal) {
InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
} else {
FastArrayPushStub stub(isolate);
InstallCode(isolate, holder, "push", stub.GetCode());
}
InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
......
......@@ -585,5 +585,12 @@ RUNTIME_FUNCTION(Runtime_IsWasmObject) {
return *isolate->factory()->ToBoolean(is_wasm_object);
}
RUNTIME_FUNCTION(Runtime_Typeof) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
return *Object::TypeOf(isolate, object);
}
} // namespace internal
} // namespace v8
......@@ -272,9 +272,15 @@ RUNTIME_FUNCTION(Runtime_SubString) {
RUNTIME_FUNCTION(Runtime_StringAdd) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, obj1, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, obj2, 1);
isolate->counters()->string_add_runtime()->Increment();
MaybeHandle<String> maybe_str1(Object::ToString(isolate, obj1));
MaybeHandle<String> maybe_str2(Object::ToString(isolate, obj2));
Handle<String> str1;
Handle<String> str2;
maybe_str1.ToHandle(&str1);
maybe_str2.ToHandle(&str2);
RETURN_RESULT_OR_FAILURE(isolate,
isolate->factory()->NewConsString(str1, str2));
}
......
......@@ -324,7 +324,8 @@ namespace internal {
F(EnqueueMicrotask, 1, 1) \
F(RunMicrotasks, 0, 1) \
F(OrdinaryHasInstance, 2, 1) \
F(IsWasmObject, 1, 1)
F(IsWasmObject, 1, 1) \
F(Typeof, 1, 1)
#define FOR_EACH_INTRINSIC_LITERALS(F) \
F(CreateRegExpLiteral, 4, 1) \
......
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