[interpreter] Make setting of function data more resilient.
This adds explicit setters for the SharedFunctionInfo::function_data field. Such setters are safer because they allow for explicit checking of which values are allowed, and they improve readability because the intended semantics become clear for each call-site. Also fix a cctest case along the way. R=rmcilroy@chromium.org Review URL: https://codereview.chromium.org/1730853005 Cr-Commit-Position: refs/heads/master@{#34297}
This commit is contained in:
parent
ac9f182746
commit
6acee6ee59
@ -564,7 +564,7 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
|
||||
result->shared()->set_instance_class_name(*class_name);
|
||||
result->shared()->set_name(*class_name);
|
||||
}
|
||||
result->shared()->set_function_data(*obj);
|
||||
result->shared()->set_api_func_data(*obj);
|
||||
result->shared()->set_construct_stub(*construct_stub);
|
||||
result->shared()->DontAdaptArguments();
|
||||
|
||||
|
@ -1180,7 +1180,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
isolate->initial_object_prototype(),
|
||||
Builtins::kArrayCode);
|
||||
array_function->shared()->DontAdaptArguments();
|
||||
array_function->shared()->set_function_data(Smi::FromInt(kArrayCode));
|
||||
array_function->shared()->set_builtin_function_id(kArrayCode);
|
||||
|
||||
// This seems a bit hackish, but we need to make sure Array.length
|
||||
// is 1.
|
||||
@ -3082,7 +3082,7 @@ static void InstallBuiltinFunctionId(Handle<JSObject> holder,
|
||||
Handle<Object> function_object =
|
||||
Object::GetProperty(isolate, holder, function_name).ToHandleChecked();
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
|
||||
function->shared()->set_function_data(Smi::FromInt(id));
|
||||
function->shared()->set_builtin_function_id(id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -838,8 +838,8 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
|
||||
shared->ReplaceCode(*info->code());
|
||||
shared->set_feedback_vector(*info->feedback_vector());
|
||||
if (info->has_bytecode_array()) {
|
||||
DCHECK(shared->function_data()->IsUndefined());
|
||||
shared->set_function_data(*info->bytecode_array());
|
||||
DCHECK(!shared->HasBytecodeArray()); // Only compiled once.
|
||||
shared->set_bytecode_array(*info->bytecode_array());
|
||||
}
|
||||
|
||||
return info->code();
|
||||
@ -1308,8 +1308,8 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
ScopeInfo::Create(info->isolate(), info->zone(), info->scope()),
|
||||
info->feedback_vector());
|
||||
if (info->has_bytecode_array()) {
|
||||
DCHECK(result->function_data()->IsUndefined());
|
||||
result->set_function_data(*info->bytecode_array());
|
||||
DCHECK(!result->HasBytecodeArray()); // Only compiled once.
|
||||
result->set_bytecode_array(*info->bytecode_array());
|
||||
}
|
||||
|
||||
DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
|
||||
@ -1669,8 +1669,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
literal->name(), literal->materialized_literal_count(),
|
||||
literal->kind(), info.code(), scope_info, info.feedback_vector());
|
||||
if (info.has_bytecode_array()) {
|
||||
DCHECK(result->function_data()->IsUndefined());
|
||||
result->set_function_data(*info.bytecode_array());
|
||||
DCHECK(!result->HasBytecodeArray()); // Only compiled once.
|
||||
result->set_bytecode_array(*info.bytecode_array());
|
||||
}
|
||||
|
||||
SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
|
||||
|
@ -5817,6 +5817,10 @@ FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
|
||||
return FunctionTemplateInfo::cast(function_data());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_api_func_data(FunctionTemplateInfo* data) {
|
||||
DCHECK(function_data()->IsUndefined());
|
||||
set_function_data(data);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasBuiltinFunctionId() {
|
||||
return function_data()->IsSmi();
|
||||
@ -5828,6 +5832,10 @@ BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
|
||||
return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_builtin_function_id(BuiltinFunctionId id) {
|
||||
DCHECK(function_data()->IsUndefined() || HasBuiltinFunctionId());
|
||||
set_function_data(Smi::FromInt(id));
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasBytecodeArray() {
|
||||
return function_data()->IsBytecodeArray();
|
||||
@ -5839,6 +5847,15 @@ BytecodeArray* SharedFunctionInfo::bytecode_array() {
|
||||
return BytecodeArray::cast(function_data());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_bytecode_array(BytecodeArray* bytecode) {
|
||||
DCHECK(function_data()->IsUndefined());
|
||||
set_function_data(bytecode);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ClearBytecodeArray() {
|
||||
DCHECK(function_data()->IsUndefined() || HasBytecodeArray());
|
||||
set_function_data(GetHeap()->undefined_value());
|
||||
}
|
||||
|
||||
int SharedFunctionInfo::ic_age() {
|
||||
return ICAgeBits::decode(counters());
|
||||
|
@ -6728,10 +6728,14 @@ class SharedFunctionInfo: public HeapObject {
|
||||
|
||||
inline bool IsApiFunction();
|
||||
inline FunctionTemplateInfo* get_api_func_data();
|
||||
inline void set_api_func_data(FunctionTemplateInfo* data);
|
||||
inline bool HasBuiltinFunctionId();
|
||||
inline BuiltinFunctionId builtin_function_id();
|
||||
inline void set_builtin_function_id(BuiltinFunctionId id);
|
||||
inline bool HasBytecodeArray();
|
||||
inline BytecodeArray* bytecode_array();
|
||||
inline void set_bytecode_array(BytecodeArray* bytecode);
|
||||
inline void ClearBytecodeArray();
|
||||
|
||||
// [script info]: Script from which the function originates.
|
||||
DECL_ACCESSORS(script, Object)
|
||||
|
@ -168,7 +168,7 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
||||
// of the target shared function info.
|
||||
target_shared->ReplaceCode(source_shared->code());
|
||||
if (source_shared->HasBytecodeArray()) {
|
||||
target_shared->set_function_data(source_shared->bytecode_array());
|
||||
target_shared->set_bytecode_array(source_shared->bytecode_array());
|
||||
}
|
||||
target_shared->set_scope_info(source_shared->scope_info());
|
||||
target_shared->set_length(source_shared->length());
|
||||
|
@ -540,10 +540,6 @@
|
||||
# TODO(rmcilroy,4680): The function_data field should be a BytecodeArray on interpreter entry
|
||||
'test-api/SetFunctionEntryHook': [FAIL],
|
||||
|
||||
# TODO(rmcilroy,4680): Fail on shared_function_data()->IsUndefined in
|
||||
#compiler.cc
|
||||
'test-heap/CanonicalSharedFunctionInfo': [PASS, ['mode == debug or dcheck_always_on == True', FAIL]],
|
||||
|
||||
# TODO(rmcilroy,4680): Check failed: !function->shared()->is_compiled() || function->IsOptimized().
|
||||
'test-heap/TestCodeFlushingPreAged': [FAIL],
|
||||
'test-heap/TestCodeFlushingIncrementalScavenge': [FAIL],
|
||||
|
@ -6278,6 +6278,7 @@ static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
|
||||
fun->ReplaceCode(*isolate->builtins()->CompileLazy());
|
||||
fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy());
|
||||
fun->shared()->ClearBytecodeArray(); // Bytecode is code too.
|
||||
isolate->heap()->CollectAllAvailableGarbage("remove code and gc");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user