Skip to content

Commit d8f564e

Browse files
LeszekSwirskiCommit Bot
authored andcommitted
Reland: Remove SFI code field
Remove the SharedFunctionInfo code field, inferring the code object from the function_data field instead. In some cases, the function_data field can now hold a Code object (e.g. some WASM cases). (Reland of https://chromium-review.googlesource.com/952452) [email protected] Bug: chromium:783853 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: I10ea5be7ceed1b51362a2fad9be7397624d69343 Reviewed-on: https://chromium-review.googlesource.com/970649 Commit-Queue: Leszek Swirski <[email protected]> Reviewed-by: Yang Guo <[email protected]> Reviewed-by: Jakob Gruber <[email protected]> Reviewed-by: Leszek Swirski <[email protected]> Cr-Commit-Position: refs/heads/master@{#52136}
1 parent eefc6cf commit d8f564e

58 files changed

Lines changed: 907 additions & 525 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/api.cc

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -729,15 +729,33 @@ StartupData SnapshotCreator::CreateBlob(
729729
i::SerializedHandleChecker handle_checker(isolate, &contexts);
730730
CHECK(handle_checker.CheckGlobalAndEternalHandles());
731731

732-
// Complete in-object slack tracking for all functions.
733732
i::HeapIterator heap_iterator(isolate->heap());
734733
while (i::HeapObject* current_obj = heap_iterator.next()) {
735-
if (!current_obj->IsJSFunction()) continue;
736-
i::JSFunction* fun = i::JSFunction::cast(current_obj);
737-
fun->CompleteInobjectSlackTrackingIfActive();
734+
// Complete in-object slack tracking for all functions.
735+
if (current_obj->IsJSFunction()) {
736+
i::JSFunction* fun = i::JSFunction::cast(current_obj);
737+
fun->CompleteInobjectSlackTrackingIfActive();
738+
}
739+
740+
// Clear out re-compilable data from all shared function infos. Any
741+
// JSFunctions using these SFIs will have their code pointers reset by the
742+
// partial serializer.
743+
if (current_obj->IsSharedFunctionInfo() &&
744+
function_code_handling == FunctionCodeHandling::kClear) {
745+
i::SharedFunctionInfo* shared = i::SharedFunctionInfo::cast(current_obj);
746+
if (shared->HasBytecodeArray()) {
747+
shared->ClearBytecodeArray();
748+
} else if (shared->HasAsmWasmData()) {
749+
shared->ClearAsmWasmData();
750+
} else if (shared->HasPreParsedScopeData()) {
751+
shared->ClearPreParsedScopeData();
752+
}
753+
DCHECK(shared->HasCodeObject() || shared->HasBuiltinId() ||
754+
shared->IsApiFunction());
755+
}
738756
}
739757

740-
i::StartupSerializer startup_serializer(isolate, function_code_handling);
758+
i::StartupSerializer startup_serializer(isolate);
741759
startup_serializer.SerializeStrongReferences();
742760

743761
// Serialize each context with a new partial serializer.
@@ -9689,9 +9707,8 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
96899707
}
96909708

96919709
i::Handle<i::String> name = isolate->factory()->empty_string();
9692-
i::Handle<i::Code> code(isolate->builtins()->builtin(builtin_id));
96939710
i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype(
9694-
name, code, builtin_id, i::LanguageMode::kSloppy);
9711+
name, builtin_id, i::LanguageMode::kSloppy);
96959712
i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args);
96969713

96979714
fun->shared()->DontAdaptArguments();

src/asmjs/asm-js.cc

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,20 @@ bool AreStdlibMembersValid(Isolate* isolate, Handle<JSReceiver> stdlib,
6565
Handle<Object> value = JSReceiver::GetDataProperty(stdlib, name);
6666
if (!value->IsNaN()) return false;
6767
}
68-
#define STDLIB_MATH_FUNC(fname, FName, ignore1, ignore2) \
69-
if (members.Contains(wasm::AsmJsParser::StandardMember::kMath##FName)) { \
70-
members.Remove(wasm::AsmJsParser::StandardMember::kMath##FName); \
71-
Handle<Name> name(isolate->factory()->InternalizeOneByteString( \
72-
STATIC_CHAR_VECTOR(#fname))); \
73-
Handle<Object> value = StdlibMathMember(isolate, stdlib, name); \
74-
if (!value->IsJSFunction()) return false; \
75-
SharedFunctionInfo* shared = Handle<JSFunction>::cast(value)->shared(); \
76-
if (shared->HasLazyDeserializationBuiltinId()) { \
77-
if (shared->lazy_deserialization_builtin_id() != Builtins::kMath##FName) \
78-
return false; \
79-
} else if (shared->code() != \
80-
isolate->builtins()->builtin(Builtins::kMath##FName)) { \
81-
return false; \
82-
} \
68+
#define STDLIB_MATH_FUNC(fname, FName, ignore1, ignore2) \
69+
if (members.Contains(wasm::AsmJsParser::StandardMember::kMath##FName)) { \
70+
members.Remove(wasm::AsmJsParser::StandardMember::kMath##FName); \
71+
Handle<Name> name(isolate->factory()->InternalizeOneByteString( \
72+
STATIC_CHAR_VECTOR(#fname))); \
73+
Handle<Object> value = StdlibMathMember(isolate, stdlib, name); \
74+
if (!value->IsJSFunction()) return false; \
75+
SharedFunctionInfo* shared = Handle<JSFunction>::cast(value)->shared(); \
76+
if (!shared->HasBuiltinId() || \
77+
shared->builtin_id() != Builtins::kMath##FName) { \
78+
return false; \
79+
} \
80+
DCHECK_EQ(shared->GetCode(), \
81+
isolate->builtins()->builtin(Builtins::kMath##FName)); \
8382
}
8483
STDLIB_MATH_FUNCTION_LIST(STDLIB_MATH_FUNC)
8584
#undef STDLIB_MATH_FUNC
@@ -302,7 +301,6 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl(Isolate* isolate) {
302301
result->set(kWasmDataCompiledModule, *compiled);
303302
result->set(kWasmDataUsesBitSet, *uses_bitset);
304303
compilation_info()->SetAsmWasmData(result);
305-
compilation_info()->SetCode(BUILTIN_CODE(isolate, InstantiateAsmJs));
306304

307305
RecordHistograms(isolate);
308306
ReportCompilationSuccess(parse_info()->script(),

src/bailout-reason.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace internal {
3232
V(kInvalidHandleScopeLevel, "Invalid HandleScope level") \
3333
V(kInvalidJumpTableIndex, "Invalid jump table index") \
3434
V(kInvalidRegisterFileInGenerator, "invalid register file in generator") \
35+
V(kInvalidSharedFunctionInfoData, "Invalid SharedFunctionInfo data") \
3536
V(kMissingBytecodeArray, "Missing bytecode array from function") \
3637
V(kObjectNotTagged, "The object is not tagged") \
3738
V(kObjectTagged, "The object is tagged") \

src/bootstrapper.cc

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,10 @@ namespace {
359359
// Non-construct case.
360360
V8_NOINLINE Handle<SharedFunctionInfo> SimpleCreateSharedFunctionInfo(
361361
Isolate* isolate, Builtins::Name builtin_id, Handle<String> name, int len) {
362-
Handle<Code> code = isolate->builtins()->builtin_handle(builtin_id);
363362
const bool kNotConstructor = false;
364-
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
365-
name, code, kNotConstructor, kNormalFunction, builtin_id);
363+
Handle<SharedFunctionInfo> shared =
364+
isolate->factory()->NewSharedFunctionInfoForBuiltin(
365+
name, builtin_id, kNotConstructor, kNormalFunction);
366366
shared->set_internal_formal_parameter_count(len);
367367
shared->set_length(len);
368368
return shared;
@@ -373,10 +373,10 @@ V8_NOINLINE Handle<SharedFunctionInfo>
373373
SimpleCreateConstructorSharedFunctionInfo(Isolate* isolate,
374374
Builtins::Name builtin_id,
375375
Handle<String> name, int len) {
376-
Handle<Code> code = isolate->builtins()->builtin_handle(builtin_id);
377376
const bool kIsConstructor = true;
378-
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
379-
name, code, kIsConstructor, kNormalFunction, builtin_id);
377+
Handle<SharedFunctionInfo> shared =
378+
isolate->factory()->NewSharedFunctionInfoForBuiltin(
379+
name, builtin_id, kIsConstructor, kNormalFunction);
380380
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
381381
shared->set_internal_formal_parameter_count(len);
382382
shared->set_length(len);
@@ -402,22 +402,21 @@ V8_NOINLINE Handle<JSFunction> CreateFunction(
402402
Isolate* isolate, Handle<String> name, InstanceType type, int instance_size,
403403
int inobject_properties, MaybeHandle<Object> maybe_prototype,
404404
Builtins::Name builtin_id) {
405-
Handle<Code> code(isolate->builtins()->builtin(builtin_id));
406405
Handle<Object> prototype;
407406
Handle<JSFunction> result;
408407

409408
if (maybe_prototype.ToHandle(&prototype)) {
410409
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype(
411-
name, code, prototype, type, instance_size, inobject_properties,
412-
builtin_id, IMMUTABLE);
410+
name, prototype, type, instance_size, inobject_properties, builtin_id,
411+
IMMUTABLE);
413412

414413
result = isolate->factory()->NewFunction(args);
415414
// Make the JSFunction's prototype object fast.
416415
JSObject::MakePrototypesFast(handle(result->prototype(), isolate),
417416
kStartAtReceiver, isolate);
418417
} else {
419418
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype(
420-
name, code, builtin_id, LanguageMode::kStrict);
419+
name, builtin_id, LanguageMode::kStrict);
421420
result = isolate->factory()->NewFunction(args);
422421
}
423422

@@ -608,10 +607,8 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
608607

609608
// Allocate the empty function as the prototype for function according to
610609
// ES#sec-properties-of-the-function-prototype-object
611-
Handle<Code> code(BUILTIN_CODE(isolate, EmptyFunction));
612-
NewFunctionArgs args =
613-
NewFunctionArgs::ForBuiltin(factory->empty_string(), code,
614-
empty_function_map, Builtins::kEmptyFunction);
610+
NewFunctionArgs args = NewFunctionArgs::ForBuiltin(
611+
factory->empty_string(), empty_function_map, Builtins::kEmptyFunction);
615612
Handle<JSFunction> empty_function = factory->NewFunction(args);
616613

617614
// --- E m p t y ---
@@ -663,9 +660,8 @@ Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic() {
663660
return restricted_properties_thrower_;
664661
}
665662
Handle<String> name(factory()->empty_string());
666-
Handle<Code> code = BUILTIN_CODE(isolate(), StrictPoisonPillThrower);
667663
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype(
668-
name, code, Builtins::kStrictPoisonPillThrower, i::LanguageMode::kStrict);
664+
name, Builtins::kStrictPoisonPillThrower, i::LanguageMode::kStrict);
669665
Handle<JSFunction> function = factory()->NewFunction(args);
670666
function->shared()->DontAdaptArguments();
671667

@@ -1228,11 +1224,10 @@ Handle<JSGlobalObject> Genesis::CreateNewGlobals(
12281224

12291225
if (js_global_object_template.is_null()) {
12301226
Handle<String> name(factory()->empty_string());
1231-
Handle<Code> code = BUILTIN_CODE(isolate(), Illegal);
12321227
Handle<JSObject> prototype =
12331228
factory()->NewFunctionPrototype(isolate()->object_function());
12341229
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype(
1235-
name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize, 0,
1230+
name, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize, 0,
12361231
Builtins::kIllegal, MUTABLE);
12371232
js_global_object_function = factory()->NewFunction(args);
12381233
#ifdef DEBUG
@@ -1261,9 +1256,8 @@ Handle<JSGlobalObject> Genesis::CreateNewGlobals(
12611256
Handle<JSFunction> global_proxy_function;
12621257
if (global_proxy_template.IsEmpty()) {
12631258
Handle<String> name(factory()->empty_string());
1264-
Handle<Code> code = BUILTIN_CODE(isolate(), Illegal);
12651259
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype(
1266-
name, code, factory()->the_hole_value(), JS_GLOBAL_PROXY_TYPE,
1260+
name, factory()->the_hole_value(), JS_GLOBAL_PROXY_TYPE,
12671261
JSGlobalProxy::SizeWithEmbedderFields(0), 0, Builtins::kIllegal,
12681262
MUTABLE);
12691263
global_proxy_function = factory()->NewFunction(args);
@@ -1399,11 +1393,9 @@ static void InstallError(Isolate* isolate, Handle<JSObject> global,
13991393
namespace {
14001394

14011395
void InstallMakeError(Isolate* isolate, int builtin_id, int context_index) {
1402-
Handle<Code> code(isolate->builtins()->builtin(builtin_id));
14031396
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype(
1404-
isolate->factory()->empty_string(), code,
1405-
isolate->factory()->the_hole_value(), JS_OBJECT_TYPE,
1406-
JSObject::kHeaderSize, 0, builtin_id, MUTABLE);
1397+
isolate->factory()->empty_string(), isolate->factory()->the_hole_value(),
1398+
JS_OBJECT_TYPE, JSObject::kHeaderSize, 0, builtin_id, MUTABLE);
14071399

14081400
Handle<JSFunction> function = isolate->factory()->NewFunction(args);
14091401
function->shared()->DontAdaptArguments();
@@ -3282,10 +3274,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
32823274
proxy_function_map->SetInObjectUnusedPropertyFields(unused_property_fields);
32833275

32843276
Handle<String> name = factory->Proxy_string();
3285-
Handle<Code> code(BUILTIN_CODE(isolate, ProxyConstructor));
32863277

32873278
NewFunctionArgs args = NewFunctionArgs::ForBuiltin(
3288-
name, code, proxy_function_map, Builtins::kProxyConstructor);
3279+
name, proxy_function_map, Builtins::kProxyConstructor);
32893280
Handle<JSFunction> proxy_function = factory->NewFunction(args);
32903281

32913282
JSFunction::SetInitialMap(proxy_function, isolate->proxy_map(),
@@ -3389,9 +3380,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
33893380
{ // --- sloppy arguments map
33903381
Handle<String> arguments_string = factory->Arguments_string();
33913382
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype(
3392-
arguments_string, BUILTIN_CODE(isolate, Illegal),
3393-
isolate->initial_object_prototype(), JS_ARGUMENTS_TYPE,
3394-
JSSloppyArgumentsObject::kSize, 2, Builtins::kIllegal, MUTABLE);
3383+
arguments_string, isolate->initial_object_prototype(),
3384+
JS_ARGUMENTS_TYPE, JSSloppyArgumentsObject::kSize, 2,
3385+
Builtins::kIllegal, MUTABLE);
33953386
Handle<JSFunction> function = factory->NewFunction(args);
33963387
Handle<Map> map(function->initial_map());
33973388

src/builtins/arm/builtins-arm.cc

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,17 +1252,75 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
12521252
}
12531253

12541254
void Builtins::Generate_CompileLazyDeoptimizedCode(MacroAssembler* masm) {
1255-
// Set the code slot inside the JSFunction to the trampoline to the
1256-
// interpreter entry.
1257-
__ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1258-
__ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset));
1255+
// Set the code slot inside the JSFunction to CompileLazy.
1256+
__ Move(r2, BUILTIN_CODE(masm->isolate(), CompileLazy));
12591257
__ str(r2, FieldMemOperand(r1, JSFunction::kCodeOffset));
12601258
__ RecordWriteField(r1, JSFunction::kCodeOffset, r2, r4, kLRHasNotBeenSaved,
12611259
kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
12621260
// Jump to compile lazy.
12631261
Generate_CompileLazy(masm);
12641262
}
12651263

1264+
static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
1265+
Register scratch1) {
1266+
// Figure out the SFI's code object.
1267+
Label done;
1268+
Label check_is_bytecode_array;
1269+
Label check_is_code;
1270+
Label check_is_fixed_array;
1271+
Label check_is_pre_parsed_scope_data;
1272+
Label check_is_function_template_info;
1273+
1274+
Register data_type = scratch1;
1275+
1276+
// IsSmi: Is builtin
1277+
__ JumpIfNotSmi(sfi_data, &check_is_bytecode_array);
1278+
__ Move(scratch1,
1279+
Operand(ExternalReference::builtins_address(masm->isolate())));
1280+
__ ldr(sfi_data, MemOperand::PointerAddressFromSmiKey(scratch1, sfi_data));
1281+
__ b(&done);
1282+
1283+
// Get map for subsequent checks.
1284+
__ bind(&check_is_bytecode_array);
1285+
__ ldr(data_type, FieldMemOperand(sfi_data, HeapObject::kMapOffset));
1286+
__ ldrh(data_type, FieldMemOperand(data_type, Map::kInstanceTypeOffset));
1287+
1288+
// IsBytecodeArray: Interpret bytecode
1289+
__ cmp(data_type, Operand(BYTECODE_ARRAY_TYPE));
1290+
__ b(ne, &check_is_code);
1291+
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline));
1292+
__ b(&done);
1293+
1294+
// IsCode: Run code
1295+
__ bind(&check_is_code);
1296+
__ cmp(data_type, Operand(CODE_TYPE));
1297+
__ b(eq, &done);
1298+
1299+
// IsFixedArray: Instantiate using AsmWasmData,
1300+
__ bind(&check_is_fixed_array);
1301+
__ cmp(data_type, Operand(FIXED_ARRAY_TYPE));
1302+
__ b(ne, &check_is_pre_parsed_scope_data);
1303+
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), InstantiateAsmJs));
1304+
__ b(&done);
1305+
1306+
// IsPreParsedScopeData: Compile lazy
1307+
__ bind(&check_is_pre_parsed_scope_data);
1308+
__ cmp(data_type, Operand(TUPLE2_TYPE));
1309+
__ b(ne, &check_is_function_template_info);
1310+
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), CompileLazy));
1311+
__ b(&done);
1312+
1313+
// IsFunctionTemplateInfo: API call
1314+
__ bind(&check_is_function_template_info);
1315+
if (FLAG_debug_code) {
1316+
__ cmp(data_type, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
1317+
__ Assert(eq, AbortReason::kInvalidSharedFunctionInfoData);
1318+
}
1319+
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
1320+
1321+
__ bind(&done);
1322+
}
1323+
12661324
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
12671325
// ----------- S t a t e -------------
12681326
// -- r0 : argument count (preserved for callee)
@@ -1285,13 +1343,15 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
12851343
// Is there an optimization marker or optimized code in the feedback vector?
12861344
MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r4, r6, r5);
12871345

1288-
// We found no optimized code.
1346+
// We found no optimized code. Infer the code object needed for the SFI.
12891347
Register entry = r4;
12901348
__ ldr(entry,
12911349
FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1350+
__ ldr(entry,
1351+
FieldMemOperand(entry, SharedFunctionInfo::kFunctionDataOffset));
1352+
GetSharedFunctionInfoCode(masm, entry, r5);
12921353

1293-
// If SFI points to anything other than CompileLazy, install that.
1294-
__ ldr(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
1354+
// If code entry points to anything other than CompileLazy, install that.
12951355
__ Move(r5, masm->CodeObject());
12961356
__ cmp(entry, r5);
12971357
__ b(eq, &gotta_call_runtime);
@@ -1361,25 +1421,9 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
13611421

13621422
{
13631423
// If we've reached this spot, the target builtin has been deserialized and
1364-
// we simply need to copy it over. First to the shared function info.
1424+
// we simply need to copy it over to the target function.
13651425

13661426
Register target_builtin = scratch1;
1367-
Register shared = scratch0;
1368-
1369-
__ ldr(shared,
1370-
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
1371-
1372-
CHECK(r5 != target && r5 != scratch0 && r5 != scratch1);
1373-
CHECK(r9 != target && r9 != scratch0 && r9 != scratch1);
1374-
1375-
__ str(target_builtin,
1376-
FieldMemOperand(shared, SharedFunctionInfo::kCodeOffset));
1377-
__ mov(r9, target_builtin); // Write barrier clobbers r9 below.
1378-
__ RecordWriteField(shared, SharedFunctionInfo::kCodeOffset, r9, r5,
1379-
kLRHasNotBeenSaved, kDontSaveFPRegs,
1380-
OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
1381-
1382-
// And second to the target function.
13831427

13841428
__ str(target_builtin, FieldMemOperand(target, JSFunction::kCodeOffset));
13851429
__ mov(r9, target_builtin); // Write barrier clobbers r9 below.

0 commit comments

Comments
 (0)