Introduce TypeFeedbackVector, as FixedArray grew constrictive.

The TypeFeedbackVector is poised to host significant functionality. While it
remains a FixedArray under the covers, we need a place to hold logic and
definitions unique to its function.

BUG=
R=ishell@chromium.org

Review URL: https://codereview.chromium.org/581993002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24027 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 80d9d6df
...@@ -848,6 +848,8 @@ source_set("v8_base") { ...@@ -848,6 +848,8 @@ source_set("v8_base") {
"src/transitions-inl.h", "src/transitions-inl.h",
"src/transitions.cc", "src/transitions.cc",
"src/transitions.h", "src/transitions.h",
"src/type-feedback-vector.cc",
"src/type-feedback-vector.h",
"src/type-info.cc", "src/type-info.cc",
"src/type-info.h", "src/type-info.h",
"src/types-inl.h", "src/types-inl.h",
......
...@@ -1960,7 +1960,8 @@ bool Genesis::InstallNatives() { ...@@ -1960,7 +1960,8 @@ bool Genesis::InstallNatives() {
if (FLAG_vector_ics) { if (FLAG_vector_ics) {
// Apply embeds an IC, so we need a type vector of size 1 in the shared // Apply embeds an IC, so we need a type vector of size 1 in the shared
// function info. // function info.
Handle<FixedArray> feedback_vector = factory()->NewTypeFeedbackVector(1); Handle<TypeFeedbackVector> feedback_vector =
factory()->NewTypeFeedbackVector(1);
apply->shared()->set_feedback_vector(*feedback_vector); apply->shared()->set_feedback_vector(*feedback_vector);
} }
......
...@@ -174,8 +174,8 @@ void CompilationInfo::Initialize(Isolate* isolate, ...@@ -174,8 +174,8 @@ void CompilationInfo::Initialize(Isolate* isolate,
if (!shared_info().is_null() && shared_info()->is_compiled()) { if (!shared_info().is_null() && shared_info()->is_compiled()) {
// We should initialize the CompilationInfo feedback vector from the // We should initialize the CompilationInfo feedback vector from the
// passed in shared info, rather than creating a new one. // passed in shared info, rather than creating a new one.
feedback_vector_ = Handle<FixedArray>(shared_info()->feedback_vector(), feedback_vector_ =
isolate); Handle<TypeFeedbackVector>(shared_info()->feedback_vector(), isolate);
} }
} }
......
...@@ -226,7 +226,7 @@ class CompilationInfo { ...@@ -226,7 +226,7 @@ class CompilationInfo {
DCHECK(global_scope_ == NULL); DCHECK(global_scope_ == NULL);
global_scope_ = global_scope; global_scope_ = global_scope;
} }
Handle<FixedArray> feedback_vector() const { Handle<TypeFeedbackVector> feedback_vector() const {
return feedback_vector_; return feedback_vector_;
} }
void SetCode(Handle<Code> code) { code_ = code; } void SetCode(Handle<Code> code) { code_ = code; }
...@@ -451,7 +451,7 @@ class CompilationInfo { ...@@ -451,7 +451,7 @@ class CompilationInfo {
Handle<Context> context_; Handle<Context> context_;
// Used by codegen, ultimately kept rooted by the SharedFunctionInfo. // Used by codegen, ultimately kept rooted by the SharedFunctionInfo.
Handle<FixedArray> feedback_vector_; Handle<TypeFeedbackVector> feedback_vector_;
// Compilation mode flag and whether deoptimization is allowed. // Compilation mode flag and whether deoptimization is allowed.
Mode mode_; Mode mode_;
......
...@@ -1886,25 +1886,27 @@ void Factory::BecomeJSFunction(Handle<JSProxy> proxy) { ...@@ -1886,25 +1886,27 @@ void Factory::BecomeJSFunction(Handle<JSProxy> proxy) {
} }
Handle<FixedArray> Factory::NewTypeFeedbackVector(int slot_count) { Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(int slot_count) {
// Ensure we can skip the write barrier // Ensure we can skip the write barrier
DCHECK_EQ(isolate()->heap()->uninitialized_symbol(), DCHECK_EQ(isolate()->heap()->uninitialized_symbol(),
*TypeFeedbackInfo::UninitializedSentinel(isolate())); *TypeFeedbackInfo::UninitializedSentinel(isolate()));
CALL_HEAP_FUNCTION( if (slot_count == 0) {
isolate(), return Handle<TypeFeedbackVector>::cast(empty_fixed_array());
isolate()->heap()->AllocateFixedArrayWithFiller( }
slot_count,
TENURED, CALL_HEAP_FUNCTION(isolate(),
*TypeFeedbackInfo::UninitializedSentinel(isolate())), isolate()->heap()->AllocateFixedArrayWithFiller(
FixedArray); slot_count, TENURED,
*TypeFeedbackInfo::UninitializedSentinel(isolate())),
TypeFeedbackVector);
} }
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind, Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info, Handle<Code> code, Handle<ScopeInfo> scope_info,
Handle<FixedArray> feedback_vector) { Handle<TypeFeedbackVector> feedback_vector) {
DCHECK(IsValidFunctionKind(kind)); DCHECK(IsValidFunctionKind(kind));
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name, code); Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name, code);
shared->set_scope_info(*scope_info); shared->set_scope_info(*scope_info);
...@@ -1972,7 +1974,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( ...@@ -1972,7 +1974,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER); share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER); share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER); share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
share->set_feedback_vector(*empty_fixed_array(), SKIP_WRITE_BARRIER); share->set_feedback_vector(*NewTypeFeedbackVector(0), SKIP_WRITE_BARRIER);
share->set_profiler_ticks(0); share->set_profiler_ticks(0);
share->set_ast_node_count(0); share->set_ast_node_count(0);
share->set_counters(0); share->set_counters(0);
......
...@@ -600,12 +600,12 @@ class Factory FINAL { ...@@ -600,12 +600,12 @@ class Factory FINAL {
Handle<SharedFunctionInfo> NewSharedFunctionInfo( Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind, Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info, Handle<Code> code, Handle<ScopeInfo> scope_info,
Handle<FixedArray> feedback_vector); Handle<TypeFeedbackVector> feedback_vector);
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name, Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name,
MaybeHandle<Code> code); MaybeHandle<Code> code);
// Allocate a new type feedback vector // Allocate a new type feedback vector
Handle<FixedArray> NewTypeFeedbackVector(int slot_count); Handle<TypeFeedbackVector> NewTypeFeedbackVector(int slot_count);
// Allocates a new JSMessageObject object. // Allocates a new JSMessageObject object.
Handle<JSMessageObject> NewJSMessageObject( Handle<JSMessageObject> NewJSMessageObject(
......
...@@ -1572,7 +1572,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral( ...@@ -1572,7 +1572,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
isolate()->factory()->NewSharedFunctionInfo( isolate()->factory()->NewSharedFunctionInfo(
name, literals, FunctionKind::kNormalFunction, code, name, literals, FunctionKind::kNormalFunction, code,
Handle<ScopeInfo>(fun->shared()->scope_info()), Handle<ScopeInfo>(fun->shared()->scope_info()),
Handle<FixedArray>(fun->shared()->feedback_vector())); Handle<TypeFeedbackVector>(fun->shared()->feedback_vector()));
shared->set_construct_stub(*construct_stub); shared->set_construct_stub(*construct_stub);
// Copy the function data to the shared function info. // Copy the function data to the shared function info.
......
...@@ -649,15 +649,15 @@ Handle<Code> FunctionInfoWrapper::GetFunctionCode() { ...@@ -649,15 +649,15 @@ Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
} }
Handle<FixedArray> FunctionInfoWrapper::GetFeedbackVector() { Handle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_); Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
Handle<FixedArray> result; Handle<TypeFeedbackVector> result;
if (element->IsJSValue()) { if (element->IsJSValue()) {
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element); Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
Handle<Object> raw_result = UnwrapJSValue(value_wrapper); Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>::cast(raw_result); Handle<SharedFunctionInfo>::cast(raw_result);
result = Handle<FixedArray>(shared->feedback_vector(), isolate()); result = Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
CHECK_EQ(result->length(), GetSlotCount()); CHECK_EQ(result->length(), GetSlotCount());
} else { } else {
// Scripts may never have a SharedFunctionInfo created, so // Scripts may never have a SharedFunctionInfo created, so
...@@ -1203,7 +1203,7 @@ void LiveEdit::ReplaceFunctionCode( ...@@ -1203,7 +1203,7 @@ void LiveEdit::ReplaceFunctionCode(
} }
shared_info->DisableOptimization(kLiveEdit); shared_info->DisableOptimization(kLiveEdit);
// Update the type feedback vector // Update the type feedback vector
Handle<FixedArray> feedback_vector = Handle<TypeFeedbackVector> feedback_vector =
compile_info_wrapper.GetFeedbackVector(); compile_info_wrapper.GetFeedbackVector();
shared_info->set_feedback_vector(*feedback_vector); shared_info->set_feedback_vector(*feedback_vector);
} }
......
...@@ -307,7 +307,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> { ...@@ -307,7 +307,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
Handle<Code> GetFunctionCode(); Handle<Code> GetFunctionCode();
Handle<FixedArray> GetFeedbackVector(); Handle<TypeFeedbackVector> GetFeedbackVector();
Handle<Object> GetCodeScopeInfo(); Handle<Object> GetCodeScopeInfo();
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "src/property.h" #include "src/property.h"
#include "src/prototype.h" #include "src/prototype.h"
#include "src/transitions-inl.h" #include "src/transitions-inl.h"
#include "src/type-feedback-vector.h"
#include "src/v8memory.h" #include "src/v8memory.h"
namespace v8 { namespace v8 {
...@@ -708,6 +709,9 @@ bool Object::IsTransitionArray() const { ...@@ -708,6 +709,9 @@ bool Object::IsTransitionArray() const {
} }
bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); }
bool Object::IsDeoptimizationInputData() const { bool Object::IsDeoptimizationInputData() const {
// Must be a fixed array. // Must be a fixed array.
if (!IsFixedArray()) return false; if (!IsFixedArray()) return false;
...@@ -5400,7 +5404,7 @@ ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset) ...@@ -5400,7 +5404,7 @@ ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
ACCESSORS(SharedFunctionInfo, optimized_code_map, Object, ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
kOptimizedCodeMapOffset) kOptimizedCodeMapOffset)
ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset) ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
ACCESSORS(SharedFunctionInfo, feedback_vector, FixedArray, ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
kFeedbackVectorOffset) kFeedbackVectorOffset)
ACCESSORS(SharedFunctionInfo, instance_class_name, Object, ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
kInstanceClassNameOffset) kInstanceClassNameOffset)
......
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
// - OrderedHashSet // - OrderedHashSet
// - OrderedHashMap // - OrderedHashMap
// - Context // - Context
// - TypeFeedbackVector
// - JSFunctionResultCache // - JSFunctionResultCache
// - ScopeInfo // - ScopeInfo
// - TransitionArray // - TransitionArray
...@@ -850,6 +851,7 @@ class GlobalObject; ...@@ -850,6 +851,7 @@ class GlobalObject;
class ObjectVisitor; class ObjectVisitor;
class LookupIterator; class LookupIterator;
class StringStream; class StringStream;
class TypeFeedbackVector;
// We cannot just say "class HeapType;" if it is created from a template... =8-? // We cannot just say "class HeapType;" if it is created from a template... =8-?
template<class> class TypeImpl; template<class> class TypeImpl;
struct HeapTypeConfig; struct HeapTypeConfig;
...@@ -924,6 +926,7 @@ template <class C> inline bool Is(Object* obj); ...@@ -924,6 +926,7 @@ template <class C> inline bool Is(Object* obj);
V(Map) \ V(Map) \
V(DescriptorArray) \ V(DescriptorArray) \
V(TransitionArray) \ V(TransitionArray) \
V(TypeFeedbackVector) \
V(DeoptimizationInputData) \ V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \ V(DeoptimizationOutputData) \
V(DependentCode) \ V(DependentCode) \
...@@ -6975,9 +6978,8 @@ class SharedFunctionInfo: public HeapObject { ...@@ -6975,9 +6978,8 @@ class SharedFunctionInfo: public HeapObject {
// [feedback_vector] - accumulates ast node feedback from full-codegen and // [feedback_vector] - accumulates ast node feedback from full-codegen and
// (increasingly) from crankshafted code where sufficient feedback isn't // (increasingly) from crankshafted code where sufficient feedback isn't
// available. Currently the field is duplicated in // available.
// TypeFeedbackInfo::feedback_vector, but the allocation is done here. DECL_ACCESSORS(feedback_vector, TypeFeedbackVector)
DECL_ACCESSORS(feedback_vector, FixedArray)
// [instance class name]: class name for instances. // [instance class name]: class name for instances.
DECL_ACCESSORS(instance_class_name, Object) DECL_ACCESSORS(instance_class_name, Object)
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#include "src/objects.h"
#include "src/type-feedback-vector.h"
namespace v8 {
namespace internal {
// static
Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
Isolate* isolate, Handle<TypeFeedbackVector> vector) {
Handle<TypeFeedbackVector> result;
result = Handle<TypeFeedbackVector>::cast(
isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector)));
return result;
}
}
} // namespace v8::internal
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_TYPE_FEEDBACK_VECTOR_H_
#define V8_TYPE_FEEDBACK_VECTOR_H_
#include "src/checks.h"
#include "src/elements-kind.h"
#include "src/heap/heap.h"
#include "src/isolate.h"
#include "src/objects.h"
namespace v8 {
namespace internal {
class TypeFeedbackVector : public FixedArray {
public:
// Casting.
static TypeFeedbackVector* cast(Object* obj) {
DCHECK(obj->IsTypeFeedbackVector());
return reinterpret_cast<TypeFeedbackVector*>(obj);
}
static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
Handle<TypeFeedbackVector> vector);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
};
}
} // namespace v8::internal
#endif // V8_TRANSITIONS_H_
...@@ -18,19 +18,17 @@ namespace v8 { ...@@ -18,19 +18,17 @@ namespace v8 {
namespace internal { namespace internal {
TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, TypeFeedbackOracle::TypeFeedbackOracle(
Handle<FixedArray> feedback_vector, Handle<Code> code, Handle<TypeFeedbackVector> feedback_vector,
Handle<Context> native_context, Handle<Context> native_context, Zone* zone)
Zone* zone) : native_context_(native_context), zone_(zone) {
: native_context_(native_context),
zone_(zone) {
BuildDictionary(code); BuildDictionary(code);
DCHECK(dictionary_->IsDictionary()); DCHECK(dictionary_->IsDictionary());
// We make a copy of the feedback vector because a GC could clear // We make a copy of the feedback vector because a GC could clear
// the type feedback info contained therein. // the type feedback info contained therein.
// TODO(mvstanton): revisit the decision to copy when we weakly // TODO(mvstanton): revisit the decision to copy when we weakly
// traverse the feedback vector at GC time. // traverse the feedback vector at GC time.
feedback_vector_ = isolate()->factory()->CopyFixedArray(feedback_vector); feedback_vector_ = TypeFeedbackVector::Copy(isolate(), feedback_vector);
} }
......
...@@ -20,9 +20,8 @@ class SmallMapList; ...@@ -20,9 +20,8 @@ class SmallMapList;
class TypeFeedbackOracle: public ZoneObject { class TypeFeedbackOracle: public ZoneObject {
public: public:
TypeFeedbackOracle(Handle<Code> code, TypeFeedbackOracle(Handle<Code> code,
Handle<FixedArray> feedback_vector, Handle<TypeFeedbackVector> feedback_vector,
Handle<Context> native_context, Handle<Context> native_context, Zone* zone);
Zone* zone);
bool LoadIsUninitialized(TypeFeedbackId id); bool LoadIsUninitialized(TypeFeedbackId id);
bool StoreIsUninitialized(TypeFeedbackId id); bool StoreIsUninitialized(TypeFeedbackId id);
...@@ -120,7 +119,7 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -120,7 +119,7 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Context> native_context_; Handle<Context> native_context_;
Zone* zone_; Zone* zone_;
Handle<UnseededNumberDictionary> dictionary_; Handle<UnseededNumberDictionary> dictionary_;
Handle<FixedArray> feedback_vector_; Handle<TypeFeedbackVector> feedback_vector_;
DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle); DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle);
}; };
......
...@@ -761,6 +761,8 @@ ...@@ -761,6 +761,8 @@
'../../src/transitions-inl.h', '../../src/transitions-inl.h',
'../../src/transitions.cc', '../../src/transitions.cc',
'../../src/transitions.h', '../../src/transitions.h',
'../../src/type-feedback-vector.cc',
'../../src/type-feedback-vector.h',
'../../src/type-info.cc', '../../src/type-info.cc',
'../../src/type-info.h', '../../src/type-info.h',
'../../src/types-inl.h', '../../src/types-inl.h',
......
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