Add a bit to a virtual frame element telling if it's been copied. Set
it when a copy is made, clear it when the element is next written. Review URL: http://codereview.chromium.org/42324 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1529 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
10be4f7ffd
commit
a0a3388363
@ -550,6 +550,7 @@ FrameElement VirtualFrame::AdjustCopies(int index) {
|
||||
return copy;
|
||||
}
|
||||
|
||||
elements_[index].clear_copied();
|
||||
return FrameElement::InvalidElement();
|
||||
}
|
||||
|
||||
@ -569,7 +570,9 @@ void VirtualFrame::TakeFrameSlotAt(int index) {
|
||||
// push that register on top of the frame. If it is copied,
|
||||
// make the first copy the backing store and push a fresh copy
|
||||
// on top of the frame.
|
||||
FrameElement copy = AdjustCopies(index);
|
||||
FrameElement copy = original.is_copied()
|
||||
? AdjustCopies(index)
|
||||
: FrameElement::InvalidElement();
|
||||
if (copy.is_valid()) {
|
||||
// The original element was a copy. Push the copy of the new
|
||||
// backing store.
|
||||
@ -593,7 +596,9 @@ void VirtualFrame::TakeFrameSlotAt(int index) {
|
||||
// If the element is not copied, push it on top of the frame.
|
||||
// If it is copied, make the first copy be the new backing store
|
||||
// and push a fresh copy on top of the frame.
|
||||
FrameElement copy = AdjustCopies(index);
|
||||
FrameElement copy = original.is_copied()
|
||||
? AdjustCopies(index)
|
||||
: FrameElement::InvalidElement();
|
||||
if (copy.is_valid()) {
|
||||
// The original element was a copy. Push the copy of the new
|
||||
// backing store.
|
||||
@ -634,7 +639,8 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
|
||||
FrameElement original = elements_[index];
|
||||
// If the stored-to slot may be copied, adjust to preserve the
|
||||
// copy-on-write semantics of copied elements.
|
||||
if (original.is_register() || original.is_memory()) {
|
||||
if (original.is_copied() &&
|
||||
(original.is_register() || original.is_memory())) {
|
||||
FrameElement ignored = AdjustCopies(index);
|
||||
}
|
||||
|
||||
|
@ -93,9 +93,11 @@ FrameElement VirtualFrame::CopyElementAt(int index) {
|
||||
case FrameElement::REGISTER:
|
||||
// All copies are backed by memory or register locations.
|
||||
result.type_ =
|
||||
FrameElement::TypeField::encode(FrameElement::COPY) |
|
||||
FrameElement::SyncField::encode(FrameElement::NOT_SYNCED);
|
||||
FrameElement::TypeField::encode(FrameElement::COPY)
|
||||
| FrameElement::IsCopiedField::encode(false)
|
||||
| FrameElement::SyncField::encode(FrameElement::NOT_SYNCED);
|
||||
result.data_.index_ = index;
|
||||
elements_[index].set_copied();
|
||||
break;
|
||||
|
||||
case FrameElement::INVALID:
|
||||
@ -367,7 +369,8 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
|
||||
|
||||
// If the original may be a copy, adjust to preserve the copy-on-write
|
||||
// semantics of copied elements.
|
||||
if (original.is_register() || original.is_memory()) {
|
||||
if (original.is_copied() &&
|
||||
(original.is_register() || original.is_memory())) {
|
||||
FrameElement ignored = AdjustCopies(frame_index);
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,16 @@ class FrameElement BASE_EMBEDDED {
|
||||
bool is_constant() const { return type() == CONSTANT; }
|
||||
bool is_copy() const { return type() == COPY; }
|
||||
|
||||
bool is_copied() const { return IsCopiedField::decode(type_); }
|
||||
|
||||
void set_copied() {
|
||||
type_ = (type_ & ~IsCopiedField::mask()) | IsCopiedField::encode(true);
|
||||
}
|
||||
|
||||
void clear_copied() {
|
||||
type_ = (type_ & ~IsCopiedField::mask()) | IsCopiedField::encode(false);
|
||||
}
|
||||
|
||||
Register reg() const {
|
||||
ASSERT(is_register());
|
||||
return data_.reg_;
|
||||
@ -129,7 +139,8 @@ class FrameElement BASE_EMBEDDED {
|
||||
|
||||
// BitField is <type, shift, size>.
|
||||
class SyncField : public BitField<SyncFlag, 0, 1> {};
|
||||
class TypeField : public BitField<Type, 1, 32 - 1> {};
|
||||
class IsCopiedField : public BitField<bool, 1, 1> {};
|
||||
class TypeField : public BitField<Type, 2, 32 - 2> {};
|
||||
|
||||
Type type() const { return TypeField::decode(type_); }
|
||||
|
||||
@ -144,10 +155,6 @@ class FrameElement BASE_EMBEDDED {
|
||||
int index_;
|
||||
} data_;
|
||||
|
||||
// The index of the next element in a list of copies, or the frame's
|
||||
// illegal index if there is no next element.
|
||||
int next_;
|
||||
|
||||
// Used to construct memory and register elements.
|
||||
FrameElement(Type type, Register reg, SyncFlag is_synced) {
|
||||
Initialize(type, reg, is_synced);
|
||||
@ -175,16 +182,18 @@ class FrameElement BASE_EMBEDDED {
|
||||
namespace v8 { namespace internal {
|
||||
|
||||
FrameElement::FrameElement(Handle<Object> value, SyncFlag is_synced) {
|
||||
type_ = TypeField::encode(CONSTANT) | SyncField::encode(is_synced);
|
||||
type_ = TypeField::encode(CONSTANT)
|
||||
| IsCopiedField::encode(false)
|
||||
| SyncField::encode(is_synced);
|
||||
data_.handle_ = value.location();
|
||||
next_ = VirtualFrame::kIllegalIndex;
|
||||
}
|
||||
|
||||
|
||||
void FrameElement::Initialize(Type type, Register reg, SyncFlag is_synced) {
|
||||
type_ = TypeField::encode(type) | SyncField::encode(is_synced);
|
||||
type_ = TypeField::encode(type)
|
||||
| IsCopiedField::encode(false)
|
||||
| SyncField::encode(is_synced);
|
||||
data_.reg_ = reg;
|
||||
next_ = VirtualFrame::kIllegalIndex;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user