[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:
mstarzinger 2016-02-25 08:06:01 -08:00 committed by Commit bot
parent ac9f182746
commit 6acee6ee59
8 changed files with 32 additions and 14 deletions

View File

@ -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();

View File

@ -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);
}

View File

@ -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);

View File

@ -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());

View File

@ -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)

View File

@ -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());

View File

@ -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],

View File

@ -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");
}