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") {
"src/transitions-inl.h",
"src/transitions.cc",
"src/transitions.h",
"src/type-feedback-vector.cc",
"src/type-feedback-vector.h",
"src/type-info.cc",
"src/type-info.h",
"src/types-inl.h",
......
......@@ -1960,7 +1960,8 @@ bool Genesis::InstallNatives() {
if (FLAG_vector_ics) {
// Apply embeds an IC, so we need a type vector of size 1 in the shared
// function info.
Handle<FixedArray> feedback_vector = factory()->NewTypeFeedbackVector(1);
Handle<TypeFeedbackVector> feedback_vector =
factory()->NewTypeFeedbackVector(1);
apply->shared()->set_feedback_vector(*feedback_vector);
}
......
......@@ -174,8 +174,8 @@ void CompilationInfo::Initialize(Isolate* isolate,
if (!shared_info().is_null() && shared_info()->is_compiled()) {
// We should initialize the CompilationInfo feedback vector from the
// passed in shared info, rather than creating a new one.
feedback_vector_ = Handle<FixedArray>(shared_info()->feedback_vector(),
isolate);
feedback_vector_ =
Handle<TypeFeedbackVector>(shared_info()->feedback_vector(), isolate);
}
}
......
......@@ -226,7 +226,7 @@ class CompilationInfo {
DCHECK(global_scope_ == NULL);
global_scope_ = global_scope;
}
Handle<FixedArray> feedback_vector() const {
Handle<TypeFeedbackVector> feedback_vector() const {
return feedback_vector_;
}
void SetCode(Handle<Code> code) { code_ = code; }
......@@ -451,7 +451,7 @@ class CompilationInfo {
Handle<Context> context_;
// 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.
Mode mode_;
......
......@@ -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
DCHECK_EQ(isolate()->heap()->uninitialized_symbol(),
*TypeFeedbackInfo::UninitializedSentinel(isolate()));
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateFixedArrayWithFiller(
slot_count,
TENURED,
*TypeFeedbackInfo::UninitializedSentinel(isolate())),
FixedArray);
if (slot_count == 0) {
return Handle<TypeFeedbackVector>::cast(empty_fixed_array());
}
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateFixedArrayWithFiller(
slot_count, TENURED,
*TypeFeedbackInfo::UninitializedSentinel(isolate())),
TypeFeedbackVector);
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info,
Handle<FixedArray> feedback_vector) {
Handle<TypeFeedbackVector> feedback_vector) {
DCHECK(IsValidFunctionKind(kind));
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name, code);
shared->set_scope_info(*scope_info);
......@@ -1972,7 +1974,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_script(*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_feedback_vector(*empty_fixed_array(), SKIP_WRITE_BARRIER);
share->set_feedback_vector(*NewTypeFeedbackVector(0), SKIP_WRITE_BARRIER);
share->set_profiler_ticks(0);
share->set_ast_node_count(0);
share->set_counters(0);
......
......@@ -600,12 +600,12 @@ class Factory FINAL {
Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info,
Handle<FixedArray> feedback_vector);
Handle<TypeFeedbackVector> feedback_vector);
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name,
MaybeHandle<Code> code);
// Allocate a new type feedback vector
Handle<FixedArray> NewTypeFeedbackVector(int slot_count);
Handle<TypeFeedbackVector> NewTypeFeedbackVector(int slot_count);
// Allocates a new JSMessageObject object.
Handle<JSMessageObject> NewJSMessageObject(
......
......@@ -1572,7 +1572,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
isolate()->factory()->NewSharedFunctionInfo(
name, literals, FunctionKind::kNormalFunction, code,
Handle<ScopeInfo>(fun->shared()->scope_info()),
Handle<FixedArray>(fun->shared()->feedback_vector()));
Handle<TypeFeedbackVector>(fun->shared()->feedback_vector()));
shared->set_construct_stub(*construct_stub);
// Copy the function data to the shared function info.
......
......@@ -649,15 +649,15 @@ Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
}
Handle<FixedArray> FunctionInfoWrapper::GetFeedbackVector() {
Handle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
Handle<FixedArray> result;
Handle<TypeFeedbackVector> result;
if (element->IsJSValue()) {
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
Handle<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>::cast(raw_result);
result = Handle<FixedArray>(shared->feedback_vector(), isolate());
result = Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
CHECK_EQ(result->length(), GetSlotCount());
} else {
// Scripts may never have a SharedFunctionInfo created, so
......@@ -1203,7 +1203,7 @@ void LiveEdit::ReplaceFunctionCode(
}
shared_info->DisableOptimization(kLiveEdit);
// Update the type feedback vector
Handle<FixedArray> feedback_vector =
Handle<TypeFeedbackVector> feedback_vector =
compile_info_wrapper.GetFeedbackVector();
shared_info->set_feedback_vector(*feedback_vector);
}
......
......@@ -307,7 +307,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
Handle<Code> GetFunctionCode();
Handle<FixedArray> GetFeedbackVector();
Handle<TypeFeedbackVector> GetFeedbackVector();
Handle<Object> GetCodeScopeInfo();
......
......@@ -31,6 +31,7 @@
#include "src/property.h"
#include "src/prototype.h"
#include "src/transitions-inl.h"
#include "src/type-feedback-vector.h"
#include "src/v8memory.h"
namespace v8 {
......@@ -708,6 +709,9 @@ bool Object::IsTransitionArray() const {
}
bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); }
bool Object::IsDeoptimizationInputData() const {
// Must be a fixed array.
if (!IsFixedArray()) return false;
......@@ -5400,7 +5404,7 @@ ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
kOptimizedCodeMapOffset)
ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
ACCESSORS(SharedFunctionInfo, feedback_vector, FixedArray,
ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
kFeedbackVectorOffset)
ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
kInstanceClassNameOffset)
......
......@@ -79,6 +79,7 @@
// - OrderedHashSet
// - OrderedHashMap
// - Context
// - TypeFeedbackVector
// - JSFunctionResultCache
// - ScopeInfo
// - TransitionArray
......@@ -850,6 +851,7 @@ class GlobalObject;
class ObjectVisitor;
class LookupIterator;
class StringStream;
class TypeFeedbackVector;
// We cannot just say "class HeapType;" if it is created from a template... =8-?
template<class> class TypeImpl;
struct HeapTypeConfig;
......@@ -924,6 +926,7 @@ template <class C> inline bool Is(Object* obj);
V(Map) \
V(DescriptorArray) \
V(TransitionArray) \
V(TypeFeedbackVector) \
V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \
V(DependentCode) \
......@@ -6975,9 +6978,8 @@ class SharedFunctionInfo: public HeapObject {
// [feedback_vector] - accumulates ast node feedback from full-codegen and
// (increasingly) from crankshafted code where sufficient feedback isn't
// available. Currently the field is duplicated in
// TypeFeedbackInfo::feedback_vector, but the allocation is done here.
DECL_ACCESSORS(feedback_vector, FixedArray)
// available.
DECL_ACCESSORS(feedback_vector, TypeFeedbackVector)
// [instance class name]: class name for instances.
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 {
namespace internal {
TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
Handle<FixedArray> feedback_vector,
Handle<Context> native_context,
Zone* zone)
: native_context_(native_context),
zone_(zone) {
TypeFeedbackOracle::TypeFeedbackOracle(
Handle<Code> code, Handle<TypeFeedbackVector> feedback_vector,
Handle<Context> native_context, Zone* zone)
: native_context_(native_context), zone_(zone) {
BuildDictionary(code);
DCHECK(dictionary_->IsDictionary());
// We make a copy of the feedback vector because a GC could clear
// the type feedback info contained therein.
// TODO(mvstanton): revisit the decision to copy when we weakly
// 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;
class TypeFeedbackOracle: public ZoneObject {
public:
TypeFeedbackOracle(Handle<Code> code,
Handle<FixedArray> feedback_vector,
Handle<Context> native_context,
Zone* zone);
Handle<TypeFeedbackVector> feedback_vector,
Handle<Context> native_context, Zone* zone);
bool LoadIsUninitialized(TypeFeedbackId id);
bool StoreIsUninitialized(TypeFeedbackId id);
......@@ -120,7 +119,7 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Context> native_context_;
Zone* zone_;
Handle<UnseededNumberDictionary> dictionary_;
Handle<FixedArray> feedback_vector_;
Handle<TypeFeedbackVector> feedback_vector_;
DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle);
};
......
......@@ -761,6 +761,8 @@
'../../src/transitions-inl.h',
'../../src/transitions.cc',
'../../src/transitions.h',
'../../src/type-feedback-vector.cc',
'../../src/type-feedback-vector.h',
'../../src/type-info.cc',
'../../src/type-info.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