Reapply revision 1949. Stupid error.
authorager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 14 May 2009 12:18:25 +0000 (12:18 +0000)
committerager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 14 May 2009 12:18:25 +0000 (12:18 +0000)
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

15 files changed:
src/arm/virtual-frame-arm.h
src/compiler.cc
src/compiler.h
src/frame-element.h [new file with mode: 0644]
src/ia32/virtual-frame-ia32.h
src/jump-target-inl.h [new file with mode: 0644]
src/jump-target.cc
src/jump-target.h
src/register-allocator-inl.h
src/register-allocator.h
src/virtual-frame.cc
src/virtual-frame.h
src/zone.h
tools/gyp/v8.gyp
tools/visual_studio/v8_base.vcproj

index f544378d60bdb7a37b11a4403060102d300d76a9..b6233e4b27d38b6d312b4f22bf1527561c770c94 100644 (file)
@@ -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;
 };
 
index 81433825c8dfd904ef53cc83ba97050155f91f84..a5d83fbc723c8f2e3698ba1c822e9657aefbcf6b 100644 (file)
@@ -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);
index 8abe130d839eeb889053d58b944cb1bda646b55d..8421cdaefc9a5a3bf19802c8377b2580d1b04e44 100644 (file)
@@ -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_
diff --git a/src/frame-element.h b/src/frame-element.h
new file mode 100644 (file)
index 0000000..8bfafad
--- /dev/null
@@ -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_
index 4ac882566090db263fff877f5fe9da3b15352f19..7878bfd2ab649719905b1f34d89e5e628b238df1 100644 (file)
@@ -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;
 };
 
diff --git a/src/jump-target-inl.h b/src/jump-target-inl.h
new file mode 100644 (file)
index 0000000..186ace3
--- /dev/null
@@ -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_
index 50ff78b9f991d398d769f3a4276475beac26297a..359783ecc8afe537d268d0bd7906819c44b303a2 100644 (file)
@@ -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);
     }
   }
 
index ea8b23fe9c1edfb8afa15a84c3a116dc8b6246e7..8ba8b1bfc706a877d04e863c2ea24a789bd051d6 100644 (file)
@@ -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.
index 9e745b52eac3d0a022c363a5b4f3d0002d597c51..f9dced31d92130ef1871fd0284c5a267db215345 100644 (file)
@@ -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"
 
index f79d6cfdfd2c827e3d5bee6d11cb2015ca7cda69..dfe1b55820b71c61362dbfb5359a52017a8c838f 100644 (file)
@@ -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;
 };
 
 
index 566fcdbc0e071d36530c841bec205edf5bea3313..db6b50d794ceab8d1a50979ce25e25d76dc8f292 100644 (file)
@@ -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
index 091e22ad47576823de1bf69e8d323a2bbed1a538..293f9e534fd8202c1fdbb90850e12b8413290595 100644 (file)
 #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
index df691555204c894eabf858c8e2df06058213e333..fe66caf2235ba814133be1ab1c52e6c49b1659f8 100644 (file)
@@ -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
index e980ff1671dacd6fc273a0ab7b42ce9a32bca383..1bae68be8a58095a38bc0a44d0fbc660e7881eb7 100644 (file)
       '../../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',
       '../../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',
index b1802eff7d7537b26bf7b2c2b98d65535d43e259..beeaff850a5183bfff6621e4440d96e976e2f8d4 100644 (file)
                                RelativePath="..\..\src\frames-inl.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\src\frame-element.h"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\src\frames.cc"
                                >
                                RelativePath="..\..\src\jump-target.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\src\jump-target-inl.h"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\src\jump-target.cc"
                                >