blob: 4d1c345e6800f6e627ada4db940b21057003e244 [file] [log] [blame]
// Copyright 2012 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_INL_H_
#define V8_TYPE_FEEDBACK_VECTOR_INL_H_
#include "src/type-feedback-vector.h"
namespace v8 {
namespace internal {
// static
TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
DCHECK(obj->IsTypeFeedbackVector());
return reinterpret_cast<TypeFeedbackVector*>(obj);
}
int TypeFeedbackVector::first_ic_slot_index() const {
DCHECK(length() >= kReservedIndexCount);
return Smi::cast(get(kFirstICSlotIndex))->value();
}
int TypeFeedbackVector::ic_with_type_info_count() {
return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0;
}
void TypeFeedbackVector::change_ic_with_type_info_count(int delta) {
if (delta == 0) return;
int value = ic_with_type_info_count() + delta;
// Could go negative because of the debugger.
if (value >= 0) {
set(kWithTypesIndex, Smi::FromInt(value));
}
}
int TypeFeedbackVector::ic_generic_count() {
return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0;
}
void TypeFeedbackVector::change_ic_generic_count(int delta) {
if (delta == 0) return;
int value = ic_generic_count() + delta;
if (value >= 0) {
set(kGenericCountIndex, Smi::FromInt(value));
}
}
int TypeFeedbackVector::Slots() const {
if (length() == 0) return 0;
return Max(
0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount);
}
int TypeFeedbackVector::ICSlots() const {
if (length() == 0) return 0;
return (length() - first_ic_slot_index()) / elements_per_ic_slot();
}
int TypeFeedbackVector::ic_metadata_length() const {
return VectorICComputer::word_count(ICSlots());
}
// Conversion from a slot or ic slot to an integer index to the underlying
// array.
int TypeFeedbackVector::GetIndex(FeedbackVectorSlot slot) const {
DCHECK(slot.ToInt() < first_ic_slot_index());
return kReservedIndexCount + ic_metadata_length() + slot.ToInt();
}
int TypeFeedbackVector::GetIndex(FeedbackVectorICSlot slot) const {
int first_ic_slot = first_ic_slot_index();
DCHECK(slot.ToInt() < ICSlots());
return first_ic_slot + slot.ToInt() * elements_per_ic_slot();
}
// Conversion from an integer index to either a slot or an ic slot. The caller
// should know what kind she expects.
FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const {
DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index());
return FeedbackVectorSlot(index - ic_metadata_length() - kReservedIndexCount);
}
FeedbackVectorICSlot TypeFeedbackVector::ToICSlot(int index) const {
DCHECK(index >= first_ic_slot_index() && index < length());
int ic_slot = (index - first_ic_slot_index()) / elements_per_ic_slot();
return FeedbackVectorICSlot(ic_slot);
}
Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const {
return get(GetIndex(slot));
}
void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value,
WriteBarrierMode mode) {
set(GetIndex(slot), value, mode);
}
Object* TypeFeedbackVector::Get(FeedbackVectorICSlot slot) const {
return get(GetIndex(slot));
}
void TypeFeedbackVector::Set(FeedbackVectorICSlot slot, Object* value,
WriteBarrierMode mode) {
set(GetIndex(slot), value, mode);
}
Handle<Object> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) {
return isolate->factory()->uninitialized_symbol();
}
Handle<Object> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) {
return isolate->factory()->megamorphic_symbol();
}
Handle<Object> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
return isolate->factory()->premonomorphic_symbol();
}
Object* TypeFeedbackVector::RawUninitializedSentinel(Heap* heap) {
return heap->uninitialized_symbol();
}
Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
Object* FeedbackNexus::GetFeedbackExtra() const {
DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1);
int extra_index = vector()->GetIndex(slot()) + 1;
return vector()->get(extra_index);
}
void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
vector()->Set(slot(), feedback, mode);
}
void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
WriteBarrierMode mode) {
DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1);
int index = vector()->GetIndex(slot()) + 1;
vector()->set(index, feedback_extra, mode);
}
Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
}
} // namespace v8::internal
#endif // V8_TYPE_FEEDBACK_VECTOR_INL_H_