Reapply revision 1949. Stupid error.
Add virtual destructor to jump targets to make compiler happy. Review URL: http://codereview.chromium.org/113396 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1951 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c9eda02def
commit
af59c3d68f
@ -471,18 +471,6 @@ class VirtualFrame : public ZoneObject {
|
||||
|
||||
bool Equals(VirtualFrame* other);
|
||||
|
||||
// Perform initialization required during entry frame computation
|
||||
// after setting the virtual frame element at index in frame to be
|
||||
// target.
|
||||
void InitializeEntryElement(int index, FrameElement* target) {
|
||||
elements_[index].clear_copied();
|
||||
if (target->is_register()) {
|
||||
register_locations_[target->reg().code()] = index;
|
||||
} else if (target->is_copy()) {
|
||||
elements_[target->index()].set_copied();
|
||||
}
|
||||
}
|
||||
|
||||
friend class JumpTarget;
|
||||
};
|
||||
|
||||
|
@ -101,7 +101,7 @@ static Handle<JSFunction> MakeFunction(bool is_global,
|
||||
Handle<Context> context,
|
||||
v8::Extension* extension,
|
||||
ScriptDataImpl* pre_data) {
|
||||
ZoneScope zone_scope(DELETE_ON_EXIT);
|
||||
CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
||||
|
||||
// Make sure we have an initial stack limit.
|
||||
StackGuard guard;
|
||||
@ -306,7 +306,7 @@ Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
|
||||
|
||||
bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
|
||||
int loop_nesting) {
|
||||
ZoneScope zone_scope(DELETE_ON_EXIT);
|
||||
CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
||||
|
||||
// The VM is in the COMPILER state until exiting this function.
|
||||
VMState state(COMPILER);
|
||||
|
@ -28,7 +28,9 @@
|
||||
#ifndef V8_COMPILER_H_
|
||||
#define V8_COMPILER_H_
|
||||
|
||||
#include "frame-element.h"
|
||||
#include "parser.h"
|
||||
#include "zone.h"
|
||||
|
||||
namespace v8 { namespace internal {
|
||||
|
||||
@ -69,6 +71,19 @@ class Compiler : public AllStatic {
|
||||
static bool CompileLazy(Handle<SharedFunctionInfo> shared, int loop_nesting);
|
||||
};
|
||||
|
||||
|
||||
// During compilation we need a global list of handles to constants
|
||||
// for frame elements. When the zone gets deleted, we make sure to
|
||||
// clear this list of handles as well.
|
||||
class CompilationZoneScope : public ZoneScope {
|
||||
public:
|
||||
explicit CompilationZoneScope(ZoneScopeMode mode) : ZoneScope(mode) { }
|
||||
virtual ~CompilationZoneScope() {
|
||||
if (ShouldDeleteOnExit()) FrameElement::ClearConstantList();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_COMPILER_H_
|
||||
|
265
src/frame-element.h
Normal file
265
src/frame-element.h
Normal file
@ -0,0 +1,265 @@
|
||||
// Copyright 2009 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef V8_FRAME_ELEMENT_H_
|
||||
#define V8_FRAME_ELEMENT_H_
|
||||
|
||||
#include "register-allocator-inl.h"
|
||||
|
||||
namespace v8 { namespace internal {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Virtual frame elements
|
||||
//
|
||||
// The internal elements of the virtual frames. There are several kinds of
|
||||
// elements:
|
||||
// * Invalid: elements that are uninitialized or not actually part
|
||||
// of the virtual frame. They should not be read.
|
||||
// * Memory: an element that resides in the actual frame. Its address is
|
||||
// given by its position in the virtual frame.
|
||||
// * Register: an element that resides in a register.
|
||||
// * Constant: an element whose value is known at compile time.
|
||||
|
||||
class FrameElement BASE_EMBEDDED {
|
||||
public:
|
||||
enum SyncFlag {
|
||||
NOT_SYNCED,
|
||||
SYNCED
|
||||
};
|
||||
|
||||
// The default constructor creates an invalid frame element.
|
||||
FrameElement() {
|
||||
value_ = StaticTypeField::encode(StaticType::UNKNOWN_TYPE)
|
||||
| TypeField::encode(INVALID)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(false)
|
||||
| DataField::encode(0);
|
||||
}
|
||||
|
||||
// Factory function to construct an invalid frame element.
|
||||
static FrameElement InvalidElement() {
|
||||
FrameElement result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Factory function to construct an in-memory frame element.
|
||||
static FrameElement MemoryElement() {
|
||||
FrameElement result(MEMORY, no_reg, SYNCED);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Factory function to construct an in-register frame element.
|
||||
static FrameElement RegisterElement(Register reg,
|
||||
SyncFlag is_synced,
|
||||
StaticType static_type = StaticType()) {
|
||||
return FrameElement(REGISTER, reg, is_synced, static_type);
|
||||
}
|
||||
|
||||
// Factory function to construct a frame element whose value is known at
|
||||
// compile time.
|
||||
static FrameElement ConstantElement(Handle<Object> value,
|
||||
SyncFlag is_synced) {
|
||||
FrameElement result(value, is_synced);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Static indirection table for handles to constants. If a frame
|
||||
// element represents a constant, the data contains an index into
|
||||
// this table of handles to the actual constants.
|
||||
typedef ZoneList<Handle<Object> > ZoneObjectList;
|
||||
|
||||
static ZoneObjectList* ConstantList() {
|
||||
static ZoneObjectList list(10);
|
||||
return &list;
|
||||
}
|
||||
|
||||
// Clear the constants indirection table.
|
||||
static void ClearConstantList() {
|
||||
ConstantList()->Clear();
|
||||
}
|
||||
|
||||
bool is_synced() const { return SyncedField::decode(value_); }
|
||||
|
||||
void set_sync() {
|
||||
ASSERT(type() != MEMORY);
|
||||
value_ = value_ | SyncedField::encode(true);
|
||||
}
|
||||
|
||||
void clear_sync() {
|
||||
ASSERT(type() != MEMORY);
|
||||
value_ = value_ & ~SyncedField::mask();
|
||||
}
|
||||
|
||||
bool is_valid() const { return type() != INVALID; }
|
||||
bool is_memory() const { return type() == MEMORY; }
|
||||
bool is_register() const { return type() == REGISTER; }
|
||||
bool is_constant() const { return type() == CONSTANT; }
|
||||
bool is_copy() const { return type() == COPY; }
|
||||
|
||||
bool is_copied() const { return CopiedField::decode(value_); }
|
||||
void set_copied() { value_ = value_ | CopiedField::encode(true); }
|
||||
void clear_copied() { value_ = value_ & ~CopiedField::mask(); }
|
||||
|
||||
Register reg() const {
|
||||
ASSERT(is_register());
|
||||
uint32_t reg = DataField::decode(value_);
|
||||
Register result;
|
||||
result.code_ = reg;
|
||||
return result;
|
||||
}
|
||||
|
||||
Handle<Object> handle() const {
|
||||
ASSERT(is_constant());
|
||||
return ConstantList()->at(DataField::decode(value_));
|
||||
}
|
||||
|
||||
int index() const {
|
||||
ASSERT(is_copy());
|
||||
return DataField::decode(value_);
|
||||
}
|
||||
|
||||
StaticType static_type() {
|
||||
return StaticType(StaticTypeField::decode(value_));
|
||||
}
|
||||
|
||||
void set_static_type(StaticType static_type) {
|
||||
value_ = value_ & ~StaticTypeField::mask();
|
||||
value_ = value_ | StaticTypeField::encode(static_type.static_type_);
|
||||
}
|
||||
|
||||
bool Equals(FrameElement other) {
|
||||
if (value_ == other.value_) return true;
|
||||
|
||||
if (type() != other.type() ||
|
||||
is_copied() != other.is_copied() ||
|
||||
is_synced() != other.is_synced()) return false;
|
||||
|
||||
if (is_register()) {
|
||||
if (!reg().is(other.reg())) return false;
|
||||
} else if (is_constant()) {
|
||||
if (!handle().is_identical_to(other.handle())) return false;
|
||||
} else if (is_copy()) {
|
||||
if (index() != other.index()) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Given a pair of non-null frame element pointers, return one of them
|
||||
// as an entry frame candidate or null if they are incompatible.
|
||||
FrameElement* Combine(FrameElement* other) {
|
||||
// If either is invalid, the result is.
|
||||
if (!is_valid()) return this;
|
||||
if (!other->is_valid()) return other;
|
||||
|
||||
// If they do not have the exact same location we reallocate.
|
||||
bool not_same_location =
|
||||
(type() != other->type()) ||
|
||||
(is_register() && !reg().is(other->reg())) ||
|
||||
(is_constant() && !handle().is_identical_to(other->handle())) ||
|
||||
(is_copy() && index() != other->index());
|
||||
if (not_same_location) return NULL;
|
||||
|
||||
// If either is unsynced, the result is. The result static type is
|
||||
// the merge of the static types. It's safe to set it on one of the
|
||||
// frame elements, and harmless too (because we are only going to
|
||||
// merge the reaching frames and will ensure that the types are
|
||||
// coherent, and changing the static type does not emit code).
|
||||
FrameElement* result = is_synced() ? other : this;
|
||||
result->set_static_type(static_type().merge(other->static_type()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
INVALID,
|
||||
MEMORY,
|
||||
REGISTER,
|
||||
CONSTANT,
|
||||
COPY
|
||||
};
|
||||
|
||||
// Used to construct memory and register elements.
|
||||
FrameElement(Type type, Register reg, SyncFlag is_synced) {
|
||||
value_ = StaticTypeField::encode(StaticType::UNKNOWN_TYPE)
|
||||
| TypeField::encode(type)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(is_synced != NOT_SYNCED)
|
||||
| DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
|
||||
}
|
||||
|
||||
FrameElement(Type type, Register reg, SyncFlag is_synced, StaticType stype) {
|
||||
value_ = StaticTypeField::encode(stype.static_type_)
|
||||
| TypeField::encode(type)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(is_synced != NOT_SYNCED)
|
||||
| DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
|
||||
}
|
||||
|
||||
// Used to construct constant elements.
|
||||
FrameElement(Handle<Object> value, SyncFlag is_synced) {
|
||||
value_ = StaticTypeField::encode(StaticType::TypeOf(*value).static_type_)
|
||||
| TypeField::encode(CONSTANT)
|
||||
| CopiedField::encode(false)
|
||||
| SyncedField::encode(is_synced != NOT_SYNCED)
|
||||
| DataField::encode(ConstantList()->length());
|
||||
ConstantList()->Add(value);
|
||||
}
|
||||
|
||||
Type type() const { return TypeField::decode(value_); }
|
||||
void set_type(Type type) {
|
||||
value_ = value_ & ~TypeField::mask();
|
||||
value_ = value_ | TypeField::encode(type);
|
||||
}
|
||||
|
||||
void set_index(int new_index) {
|
||||
ASSERT(is_copy());
|
||||
value_ = value_ & ~DataField::mask();
|
||||
value_ = value_ | DataField::encode(new_index);
|
||||
}
|
||||
|
||||
void set_reg(Register new_reg) {
|
||||
ASSERT(is_register());
|
||||
value_ = value_ & ~DataField::mask();
|
||||
value_ = value_ | DataField::encode(new_reg.code_);
|
||||
}
|
||||
|
||||
// Encode static type, type, copied, synced and data in one 32 bit integer.
|
||||
uint32_t value_;
|
||||
|
||||
class StaticTypeField: public BitField<StaticType::StaticTypeEnum, 0, 3> {};
|
||||
class TypeField: public BitField<Type, 3, 3> {};
|
||||
class CopiedField: public BitField<uint32_t, 6, 1> {};
|
||||
class SyncedField: public BitField<uint32_t, 7, 1> {};
|
||||
class DataField: public BitField<uint32_t, 8, 32 - 9> {};
|
||||
|
||||
friend class VirtualFrame;
|
||||
};
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_FRAME_ELEMENT_H_
|
@ -485,18 +485,6 @@ class VirtualFrame : public ZoneObject {
|
||||
|
||||
bool Equals(VirtualFrame* other);
|
||||
|
||||
// Perform initialization required during entry frame computation
|
||||
// after setting the virtual frame element at index in frame to be
|
||||
// target.
|
||||
void InitializeEntryElement(int index, FrameElement* target) {
|
||||
elements_[index].clear_copied();
|
||||
if (target->is_register()) {
|
||||
register_locations_[target->reg().code()] = index;
|
||||
} else if (target->is_copy()) {
|
||||
elements_[target->index()].set_copied();
|
||||
}
|
||||
}
|
||||
|
||||
friend class JumpTarget;
|
||||
};
|
||||
|
||||
|
44
src/jump-target-inl.h
Normal file
44
src/jump-target-inl.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2009 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef V8_JUMP_TARGET_INL_H_
|
||||
#define V8_JUMP_TARGET_INL_H_
|
||||
|
||||
namespace v8 { namespace internal {
|
||||
|
||||
void JumpTarget::InitializeEntryElement(int index, FrameElement* target) {
|
||||
entry_frame_->elements_[index].clear_copied();
|
||||
if (target->is_register()) {
|
||||
entry_frame_->register_locations_[target->reg().code()] = index;
|
||||
} else if (target->is_copy()) {
|
||||
entry_frame_->elements_[target->index()].set_copied();
|
||||
}
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_JUMP_TARGET_INL_H_
|
@ -28,6 +28,7 @@
|
||||
#include "v8.h"
|
||||
|
||||
#include "codegen-inl.h"
|
||||
#include "jump-target-inl.h"
|
||||
#include "register-allocator-inl.h"
|
||||
|
||||
namespace v8 { namespace internal {
|
||||
@ -165,7 +166,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
|
||||
// elements are initially recorded as if in memory.
|
||||
if (target != NULL) {
|
||||
entry_frame_->elements_[index] = *target;
|
||||
entry_frame_->InitializeEntryElement(index, target);
|
||||
InitializeEntryElement(index, target);
|
||||
}
|
||||
}
|
||||
// Then fill in the rest of the frame with new elements.
|
||||
@ -175,7 +176,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
|
||||
entry_frame_->elements_.Add(FrameElement::MemoryElement());
|
||||
} else {
|
||||
entry_frame_->elements_.Add(*target);
|
||||
entry_frame_->InitializeEntryElement(index, target);
|
||||
InitializeEntryElement(index, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@ class FrameElement;
|
||||
class Result;
|
||||
class VirtualFrame;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Jump targets
|
||||
//
|
||||
@ -68,6 +67,8 @@ class JumpTarget : public ZoneObject { // Shadows are dynamically allocated.
|
||||
// AST nodes.
|
||||
JumpTarget();
|
||||
|
||||
virtual ~JumpTarget() {}
|
||||
|
||||
// Supply a code generator and directionality to an already
|
||||
// constructed jump target. This function expects to be given a
|
||||
// non-null code generator, and to be called only when the code
|
||||
@ -199,8 +200,13 @@ class JumpTarget : public ZoneObject { // Shadows are dynamically allocated.
|
||||
// and a corresponding merge code label.
|
||||
void AddReachingFrame(VirtualFrame* frame);
|
||||
|
||||
// Compute a frame to use for entry to this block. Mergable elements
|
||||
// is as described for the Bind function.
|
||||
// Perform initialization required during entry frame computation
|
||||
// after setting the virtual frame element at index in frame to be
|
||||
// target.
|
||||
inline void InitializeEntryElement(int index, FrameElement* target);
|
||||
|
||||
// Compute a frame to use for entry to this block. Mergable
|
||||
// elements is as described for the Bind function.
|
||||
void ComputeEntryFrame(int mergable_elements);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(JumpTarget);
|
||||
@ -225,6 +231,8 @@ class BreakTarget : public JumpTarget {
|
||||
// nodes.
|
||||
BreakTarget() {}
|
||||
|
||||
virtual ~BreakTarget() {}
|
||||
|
||||
// Supply a code generator, expected expression stack height, and
|
||||
// directionality to an already constructed break target. This
|
||||
// function expects to be given a non-null code generator, and to be
|
||||
@ -287,6 +295,8 @@ class ShadowTarget : public BreakTarget {
|
||||
// flow intended for the shadowed one.
|
||||
explicit ShadowTarget(BreakTarget* shadowed);
|
||||
|
||||
virtual ~ShadowTarget() {}
|
||||
|
||||
// End shadowing. After shadowing ends, the original jump target
|
||||
// again gives access to the formerly shadowed target and the shadow
|
||||
// target object gives access to the formerly shadowing target.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#ifndef V8_REGISTER_ALLOCATOR_INL_H_
|
||||
#define V8_REGISTER_ALLOCATOR_INL_H_
|
||||
|
||||
#include "codegen.h"
|
||||
#include "register-allocator.h"
|
||||
#include "virtual-frame.h"
|
||||
|
||||
|
@ -100,7 +100,9 @@ class StaticType BASE_EMBEDDED {
|
||||
explicit StaticType(StaticTypeEnum static_type) : static_type_(static_type) {}
|
||||
|
||||
// StaticTypeEnum static_type_;
|
||||
byte static_type_;
|
||||
StaticTypeEnum static_type_;
|
||||
|
||||
friend class FrameElement;
|
||||
};
|
||||
|
||||
|
||||
|
@ -94,10 +94,10 @@ FrameElement VirtualFrame::CopyElementAt(int index) {
|
||||
case FrameElement::REGISTER:
|
||||
// All copies are backed by memory or register locations.
|
||||
result.set_static_type(target.static_type());
|
||||
result.type_ = FrameElement::COPY;
|
||||
result.copied_ = false;
|
||||
result.synced_ = false;
|
||||
result.data_.index_ = index;
|
||||
result.set_type(FrameElement::COPY);
|
||||
result.clear_copied();
|
||||
result.clear_sync();
|
||||
result.set_index(index);
|
||||
elements_[index].set_copied();
|
||||
break;
|
||||
|
||||
@ -465,23 +465,6 @@ void VirtualFrame::Nip(int num_dropped) {
|
||||
}
|
||||
|
||||
|
||||
bool FrameElement::Equals(FrameElement other) {
|
||||
if (type_ != other.type_ ||
|
||||
copied_ != other.copied_ ||
|
||||
synced_ != other.synced_) return false;
|
||||
|
||||
if (is_register()) {
|
||||
if (!reg().is(other.reg())) return false;
|
||||
} else if (is_constant()) {
|
||||
if (!handle().is_identical_to(other.handle())) return false;
|
||||
} else if (is_copy()) {
|
||||
if (index() != other.index()) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool VirtualFrame::Equals(VirtualFrame* other) {
|
||||
#ifdef DEBUG
|
||||
// These are sanity checks in debug builds, but we do not need to
|
||||
|
@ -28,206 +28,9 @@
|
||||
#ifndef V8_VIRTUAL_FRAME_H_
|
||||
#define V8_VIRTUAL_FRAME_H_
|
||||
|
||||
#include "frame-element.h"
|
||||
#include "macro-assembler.h"
|
||||
|
||||
namespace v8 { namespace internal {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Virtual frame elements
|
||||
//
|
||||
// The internal elements of the virtual frames. There are several kinds of
|
||||
// elements:
|
||||
// * Invalid: elements that are uninitialized or not actually part
|
||||
// of the virtual frame. They should not be read.
|
||||
// * Memory: an element that resides in the actual frame. Its address is
|
||||
// given by its position in the virtual frame.
|
||||
// * Register: an element that resides in a register.
|
||||
// * Constant: an element whose value is known at compile time.
|
||||
|
||||
class FrameElement BASE_EMBEDDED {
|
||||
public:
|
||||
enum SyncFlag {
|
||||
NOT_SYNCED,
|
||||
SYNCED
|
||||
};
|
||||
|
||||
// The default constructor creates an invalid frame element.
|
||||
FrameElement()
|
||||
: static_type_(), type_(INVALID), copied_(false), synced_(false) {
|
||||
data_.reg_ = no_reg;
|
||||
}
|
||||
|
||||
// Factory function to construct an invalid frame element.
|
||||
static FrameElement InvalidElement() {
|
||||
FrameElement result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Factory function to construct an in-memory frame element.
|
||||
static FrameElement MemoryElement() {
|
||||
FrameElement result(MEMORY, no_reg, SYNCED);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Factory function to construct an in-register frame element.
|
||||
static FrameElement RegisterElement(Register reg,
|
||||
SyncFlag is_synced,
|
||||
StaticType static_type = StaticType()) {
|
||||
return FrameElement(REGISTER, reg, is_synced, static_type);
|
||||
}
|
||||
|
||||
// Factory function to construct a frame element whose value is known at
|
||||
// compile time.
|
||||
static FrameElement ConstantElement(Handle<Object> value,
|
||||
SyncFlag is_synced) {
|
||||
FrameElement result(value, is_synced);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_synced() const { return synced_; }
|
||||
|
||||
void set_sync() {
|
||||
ASSERT(type() != MEMORY);
|
||||
synced_ = true;
|
||||
}
|
||||
|
||||
void clear_sync() {
|
||||
ASSERT(type() != MEMORY);
|
||||
synced_ = false;
|
||||
}
|
||||
|
||||
bool is_valid() const { return type() != INVALID; }
|
||||
bool is_memory() const { return type() == MEMORY; }
|
||||
bool is_register() const { return type() == REGISTER; }
|
||||
bool is_constant() const { return type() == CONSTANT; }
|
||||
bool is_copy() const { return type() == COPY; }
|
||||
|
||||
bool is_copied() const { return copied_; }
|
||||
void set_copied() { copied_ = true; }
|
||||
void clear_copied() { copied_ = false; }
|
||||
|
||||
Register reg() const {
|
||||
ASSERT(is_register());
|
||||
return data_.reg_;
|
||||
}
|
||||
|
||||
Handle<Object> handle() const {
|
||||
ASSERT(is_constant());
|
||||
return Handle<Object>(data_.handle_);
|
||||
}
|
||||
|
||||
int index() const {
|
||||
ASSERT(is_copy());
|
||||
return data_.index_;
|
||||
}
|
||||
|
||||
StaticType static_type() { return static_type_; }
|
||||
|
||||
void set_static_type(StaticType static_type) {
|
||||
// TODO(lrn): If it's s copy, it would be better to update the real one,
|
||||
// but we can't from here. The caller must handle this.
|
||||
static_type_ = static_type;
|
||||
}
|
||||
|
||||
// True if the frame elements are identical (all data members).
|
||||
bool Equals(FrameElement other);
|
||||
|
||||
// Given a pair of non-null frame element pointers, return one of them
|
||||
// as an entry frame candidate or null if they are incompatible.
|
||||
FrameElement* Combine(FrameElement* other) {
|
||||
// If either is invalid, the result is.
|
||||
if (!is_valid()) return this;
|
||||
if (!other->is_valid()) return other;
|
||||
|
||||
// If they do not have the exact same location we reallocate.
|
||||
bool not_same_location =
|
||||
(type_ != other->type_) ||
|
||||
(is_register() && !reg().is(other->reg())) ||
|
||||
(is_constant() && !handle().is_identical_to(other->handle())) ||
|
||||
(is_copy() && index() != other->index());
|
||||
if (not_same_location) return NULL;
|
||||
|
||||
// If either is unsynced, the result is. The result static type is
|
||||
// the merge of the static types. It's safe to set it on one of the
|
||||
// frame elements, and harmless too (because we are only going to
|
||||
// merge the reaching frames and will ensure that the types are
|
||||
// coherent, and changing the static type does not emit code).
|
||||
FrameElement* result = is_synced() ? other : this;
|
||||
result->set_static_type(static_type().merge(other->static_type()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
INVALID,
|
||||
MEMORY,
|
||||
REGISTER,
|
||||
CONSTANT,
|
||||
COPY
|
||||
};
|
||||
|
||||
Type type() const { return static_cast<Type>(type_); }
|
||||
|
||||
StaticType static_type_;
|
||||
|
||||
// The element's type.
|
||||
byte type_;
|
||||
|
||||
bool copied_;
|
||||
|
||||
// The element's dirty-bit. The dirty bit can be cleared
|
||||
// for non-memory elements to indicate that the element agrees with
|
||||
// the value in memory in the actual frame.
|
||||
bool synced_;
|
||||
|
||||
union {
|
||||
Register reg_;
|
||||
Object** handle_;
|
||||
int index_;
|
||||
} data_;
|
||||
|
||||
// Used to construct memory and register elements.
|
||||
FrameElement(Type type, Register reg, SyncFlag is_synced)
|
||||
: static_type_(),
|
||||
type_(type),
|
||||
copied_(false),
|
||||
synced_(is_synced != NOT_SYNCED) {
|
||||
data_.reg_ = reg;
|
||||
}
|
||||
|
||||
FrameElement(Type type, Register reg, SyncFlag is_synced, StaticType stype)
|
||||
: static_type_(stype),
|
||||
type_(type),
|
||||
copied_(false),
|
||||
synced_(is_synced != NOT_SYNCED) {
|
||||
data_.reg_ = reg;
|
||||
}
|
||||
|
||||
// Used to construct constant elements.
|
||||
FrameElement(Handle<Object> value, SyncFlag is_synced)
|
||||
: static_type_(StaticType::TypeOf(*value)),
|
||||
type_(CONSTANT),
|
||||
copied_(false),
|
||||
synced_(is_synced != NOT_SYNCED) {
|
||||
data_.handle_ = value.location();
|
||||
}
|
||||
|
||||
void set_index(int new_index) {
|
||||
ASSERT(is_copy());
|
||||
data_.index_ = new_index;
|
||||
}
|
||||
|
||||
void set_reg(Register new_reg) {
|
||||
ASSERT(is_register());
|
||||
data_.reg_ = new_reg;
|
||||
}
|
||||
|
||||
friend class VirtualFrame;
|
||||
};
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
#include "ia32/virtual-frame-ia32.h"
|
||||
#elif V8_TARGET_ARCH_X64
|
||||
|
@ -180,8 +180,13 @@ class ZoneScope BASE_EMBEDDED {
|
||||
nesting_++;
|
||||
}
|
||||
|
||||
~ZoneScope() {
|
||||
if (--nesting_ == 0 && mode_ == DELETE_ON_EXIT) Zone::DeleteAll();
|
||||
virtual ~ZoneScope() {
|
||||
if (ShouldDeleteOnExit()) Zone::DeleteAll();
|
||||
--nesting_;
|
||||
}
|
||||
|
||||
bool ShouldDeleteOnExit() {
|
||||
return nesting_ == 1 && mode_ == DELETE_ON_EXIT;
|
||||
}
|
||||
|
||||
// For ZoneScopes that do not delete on exit by default, call this
|
||||
|
@ -135,6 +135,7 @@
|
||||
'../../src/frames-inl.h',
|
||||
'../../src/frames.cc',
|
||||
'../../src/frames.h',
|
||||
'../../src/frame-element.h',
|
||||
'../../src/func-name-inferrer.cc',
|
||||
'../../src/func-name-inferrer.h',
|
||||
'../../src/global-handles.cc',
|
||||
@ -155,6 +156,7 @@
|
||||
'../../src/interpreter-irregexp.h',
|
||||
'../../src/jump-target.cc',
|
||||
'../../src/jump-target.h',
|
||||
'../../src/jump-target-inl.h',
|
||||
'../../src/jsregexp-inl.h',
|
||||
'../../src/jsregexp.cc',
|
||||
'../../src/jsregexp.h',
|
||||
|
@ -408,6 +408,10 @@
|
||||
RelativePath="..\..\src\frames-inl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\frame-element.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\frames.cc"
|
||||
>
|
||||
@ -500,6 +504,10 @@
|
||||
RelativePath="..\..\src\jump-target.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\jump-target-inl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\jump-target.cc"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user