Revision: 12706
Author:   [email protected]
Date:     Thu Oct 11 08:57:38 2012
Log:      Version 3.14.3

Use native context to retrieve ErrorMessageForCodeGenerationFromStrings (Chromium issue 155076).

Bumped variable limit further to 2^17 (Chromium issue 151625).

Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=12706

Added:
 /trunk/test/mjsunit/regress/regress-convert-enum.js
Modified:
 /trunk/ChangeLog
 /trunk/src/arm/macro-assembler-arm.cc
 /trunk/src/flag-definitions.h
 /trunk/src/hydrogen-instructions.cc
 /trunk/src/hydrogen-instructions.h
 /trunk/src/hydrogen.cc
 /trunk/src/hydrogen.h
 /trunk/src/ia32/macro-assembler-ia32.cc
 /trunk/src/messages.js
 /trunk/src/mips/macro-assembler-mips.cc
 /trunk/src/objects-inl.h
 /trunk/src/objects-visiting-inl.h
 /trunk/src/objects.cc
 /trunk/src/objects.h
 /trunk/src/parser.h
 /trunk/src/profile-generator.cc
 /trunk/src/property-details.h
 /trunk/src/runtime.cc
 /trunk/src/transitions-inl.h
 /trunk/src/transitions.cc
 /trunk/src/transitions.h
 /trunk/src/utils.h
 /trunk/src/version.cc
 /trunk/src/x64/macro-assembler-x64.cc
 /trunk/test/mjsunit/limit-locals.js
 /trunk/tools/run-tests.py
 /trunk/tools/test.py

=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-convert-enum.js Thu Oct 11 08:57:38 2012
@@ -0,0 +1,60 @@
+// Copyright 2012 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.
+
+// Flags: --expose-gc
+
+// Create a transition tree A (no descriptors) -> B (descriptor for a) -> C
+// (descriptor for a and c), that all share the descriptor array [a,c]. C is the
+// owner of the descriptor array.
+var o = {};
+o.a = 1;
+o.c = 2;
+
+// Add a transition B -> D where D has its own descriptor array [a,b] where b is
+// a constant function.
+var o1 = {};
+o1.a = 1;
+
+// Install an enumeration cache in the descriptor array [a,c] at map B.
+for (var x in o1) { }
+o1.b = function() { return 1; };
+
+// Return ownership of the descriptor array [a,c] to B and trim it to [a].
+o = null;
+gc();
+
+// Convert the transition B -> D into a transition to B -> E so that E uses the
+// instance descriptors [a,b] with b being a field.
+var o2 = {};
+o2.a = 1;
+o2.b = 10;
+
+// Create an object with map B and iterate over it.
+var o3 = {};
+o3.a = 1;
+
+for (var y in o3) { }
=======================================
--- /trunk/ChangeLog    Wed Oct 10 10:07:22 2012
+++ /trunk/ChangeLog    Thu Oct 11 08:57:38 2012
@@ -1,3 +1,13 @@
+2012-10-11: Version 3.14.3
+
+ Use native context to retrieve ErrorMessageForCodeGenerationFromStrings
+        (Chromium issue 155076).
+
+        Bumped variable limit further to 2^17 (Chromium issue 151625).
+
+        Performance and stability improvements on all platforms.
+
+
 2012-10-10: Version 3.14.2

         ARM: allowed VFP3 instructions when hardfloat is enabled.
=======================================
--- /trunk/src/arm/macro-assembler-arm.cc       Wed Oct 10 10:07:22 2012
+++ /trunk/src/arm/macro-assembler-arm.cc       Thu Oct 11 08:57:38 2012
@@ -3727,8 +3727,7 @@
            isolate()->factory()->fixed_array_map(),
            &fail,
            DONT_DO_SMI_CHECK);
- ldr(temp, FieldMemOperand(temp, TransitionArray::kDescriptorsPointerOffset)); - ldr(descriptors, FieldMemOperand(temp, JSGlobalPropertyCell::kValueOffset)); + ldr(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));
   jmp(&ok);

   bind(&fail);
@@ -3739,8 +3738,7 @@

   bind(&load_from_back_pointer);
   ldr(temp, FieldMemOperand(temp, Map::kTransitionsOrBackPointerOffset));
- ldr(temp, FieldMemOperand(temp, TransitionArray::kDescriptorsPointerOffset)); - ldr(descriptors, FieldMemOperand(temp, JSGlobalPropertyCell::kValueOffset)); + ldr(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));

   bind(&ok);
 }
=======================================
--- /trunk/src/flag-definitions.h       Wed Oct 10 10:07:22 2012
+++ /trunk/src/flag-definitions.h       Thu Oct 11 08:57:38 2012
@@ -202,6 +202,8 @@
             "perform array bounds checks elimination")
 DEFINE_bool(array_index_dehoisting, true,
             "perform array index dehoisting")
+DEFINE_bool(dead_code_elimination, true, "use dead code elimination")
+DEFINE_bool(trace_dead_code_elimination, false, "trace dead code elimination")

 DEFINE_bool(trace_osr, false, "trace on-stack replacement")
 DEFINE_int(stress_runs, 0, "number of stress runs")
=======================================
--- /trunk/src/hydrogen-instructions.cc Wed Oct 10 10:07:22 2012
+++ /trunk/src/hydrogen-instructions.cc Thu Oct 11 08:57:38 2012
@@ -1854,7 +1854,7 @@
 }


-bool HLoadKeyedFastElement::RequiresHoleCheck() {
+bool HLoadKeyedFastElement::RequiresHoleCheck() const {
   if (IsFastPackedElementsKind(elements_kind())) {
     return false;
   }
@@ -2090,7 +2090,7 @@
 }


-bool HLoadGlobalCell::RequiresHoleCheck() {
+bool HLoadGlobalCell::RequiresHoleCheck() const {
   if (details_.IsDontDelete() && !details_.IsReadOnly()) return false;
   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     HValue* use = it.value();
=======================================
--- /trunk/src/hydrogen-instructions.h  Wed Oct 10 10:07:22 2012
+++ /trunk/src/hydrogen-instructions.h  Thu Oct 11 08:57:38 2012
@@ -667,7 +667,7 @@

   // Operands.
   virtual int OperandCount() = 0;
-  virtual HValue* OperandAt(int index) = 0;
+  virtual HValue* OperandAt(int index) const = 0;
   void SetOperandAt(int index, HValue* value);

   void DeleteAndReplaceWith(HValue* other);
@@ -777,6 +777,10 @@
virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
     UNREACHABLE();
   }
+
+  bool IsDead() const {
+    return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
+  }

 #ifdef DEBUG
   virtual void Verify() = 0;
@@ -862,6 +866,8 @@
   GVNFlagSet gvn_flags_;

  private:
+  virtual bool IsDeletable() const { return false; }
+
   DISALLOW_COPY_AND_ASSIGN(HValue);
 };

@@ -930,7 +936,7 @@
 class HTemplateInstruction : public HInstruction {
  public:
   int OperandCount() { return V; }
-  HValue* OperandAt(int i) { return inputs_[i]; }
+  HValue* OperandAt(int i) const { return inputs_[i]; }

  protected:
   void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
@@ -982,7 +988,7 @@
void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }

   int OperandCount() { return V; }
-  HValue* OperandAt(int i) { return inputs_[i]; }
+  HValue* OperandAt(int i) const { return inputs_[i]; }


  protected:
@@ -1027,7 +1033,7 @@
   }

   virtual int OperandCount() { return values_.length(); }
-  virtual HValue* OperandAt(int index) { return values_[index]; }
+  virtual HValue* OperandAt(int index) const { return values_[index]; }
   virtual void PrintDataTo(StringStream* stream);

   virtual int SuccessorCount() { return 0; }
@@ -1188,7 +1194,7 @@
     return reinterpret_cast<HUnaryOperation*>(value);
   }

-  HValue* value() { return OperandAt(0); }
+  HValue* value() const { return OperandAt(0); }
   virtual void PrintDataTo(StringStream* stream);
 };

@@ -1264,8 +1270,8 @@
   virtual HType CalculateInferredType();
   virtual HValue* Canonicalize();

-  Representation from() { return value()->representation(); }
-  Representation to() { return representation(); }
+  Representation from() const { return value()->representation(); }
+  Representation to() const { return representation(); }
   bool deoptimize_on_undefined() const {
     return CheckFlag(kDeoptimizeOnUndefined);
   }
@@ -1284,6 +1290,11 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const {
+    return !from().IsTagged() || value()->type().IsSmi();
+  }
 };


@@ -1303,6 +1314,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1341,7 +1355,7 @@
     AddValue(kNoIndex, value);
   }
   virtual int OperandCount() { return values_.length(); }
-  virtual HValue* OperandAt(int index) { return values_[index]; }
+  virtual HValue* OperandAt(int index) const { return values_[index]; }

   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::None();
@@ -1514,6 +1528,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1532,6 +1549,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1550,6 +1570,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1595,6 +1618,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1614,6 +1640,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1899,6 +1928,9 @@

  protected:
   virtual bool DataEquals(HValue* other_raw) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1919,6 +1951,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1939,6 +1974,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1958,6 +1996,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -1980,6 +2021,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -2062,6 +2106,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return true; }
+
   BuiltinFunctionId op_;
 };

@@ -2086,6 +2132,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -2109,6 +2158,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -2408,7 +2460,7 @@
   }
   virtual HType CalculateInferredType();
   virtual int OperandCount() { return inputs_.length(); }
-  virtual HValue* OperandAt(int index) { return inputs_[index]; }
+  virtual HValue* OperandAt(int index) const { return inputs_[index]; }
   HValue* GetRedundantReplacement();
   void AddInput(HValue* value);
   bool HasRealUses();
@@ -2504,6 +2556,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -2632,6 +2687,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return true; }
+
   // If this is a numerical constant, handle_ either points to to the
   // HeapObject the constant originated from or is null.  If the
   // constant is non-numeric, handle_ always points to a valid
@@ -2753,6 +2810,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }

   bool from_inlined_;
 };
@@ -2773,6 +2833,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -2898,6 +2961,8 @@
   DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)

  private:
+  virtual bool IsDeletable() const { return true; }
+
   Representation observed_input_representation_[3];
 };

@@ -2921,6 +2986,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -2953,6 +3021,9 @@
     }
     return HValue::InferredRepresentation();
   }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -3238,6 +3309,9 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -3342,7 +3416,7 @@
   }

   HValue* left() { return OperandAt(0); }
-  HValue* right() { return OperandAt(1); }
+  HValue* right() const { return OperandAt(1); }

   virtual Representation RequiredInputRepresentation(int index) {
     return index == 0
@@ -3354,6 +3428,11 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+  virtual bool IsDeletable() const {
+    return !right()->representation().IsTagged();
+  }
 };


@@ -3371,6 +3450,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(Random)
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -3761,7 +3843,7 @@
   }

   Handle<JSGlobalPropertyCell>  cell() const { return cell_; }
-  bool RequiresHoleCheck();
+  bool RequiresHoleCheck() const;

   virtual void PrintDataTo(StringStream* stream);

@@ -3783,6 +3865,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
   Handle<JSGlobalPropertyCell> cell_;
   PropertyDetails details_;
 };
@@ -3943,7 +4027,7 @@
     return mode_ == kCheckDeoptimize;
   }

-  bool RequiresHoleCheck() {
+  bool RequiresHoleCheck() const {
     return mode_ != kNoCheck;
   }

@@ -3962,6 +4046,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
   int slot_index_;
   Mode mode_;
 };
@@ -4054,6 +4140,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return true; }
+
   bool is_in_object_;
   int offset_;
 };
@@ -4200,7 +4288,7 @@

   virtual void PrintDataTo(StringStream* stream);

-  bool RequiresHoleCheck();
+  bool RequiresHoleCheck() const;

   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)

@@ -4214,6 +4302,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
   class ElementsKindField:  public BitField<ElementsKind, 0, 4> {};
   class IndexOffsetField:   public BitField<uint32_t, 4, 27> {};
   class IsDehoistedField:   public BitField<bool, 31, 1> {};
@@ -4260,7 +4350,7 @@
     return Representation::None();
   }

-  bool RequiresHoleCheck() {
+  bool RequiresHoleCheck() const {
     return hole_check_mode_ == PERFORM_HOLE_CHECK;
   }

@@ -4277,6 +4367,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
+
   uint32_t index_offset_;
   bool is_dehoisted_;
   HoleCheckMode hole_check_mode_;
@@ -4341,6 +4433,8 @@
   }

  private:
+  virtual bool IsDeletable() const { return true; }
+
   ElementsKind elements_kind_;
   uint32_t index_offset_;
   bool is_dehoisted_;
@@ -4722,6 +4816,10 @@

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+  // private:
+  //  virtual bool IsDeletable() const { return true; }
 };


@@ -4756,6 +4854,10 @@
   virtual Range* InferRange(Zone* zone) {
     return new(zone) Range(0, String::kMaxUtf16CodeUnit);
   }
+
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+  // private:
+  //  virtual bool IsDeletable() const { return true; }
 };


@@ -4782,6 +4884,10 @@
   virtual bool DataEquals(HValue* other) { return true; }

   DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
+
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+  // private:
+  //  virtual bool IsDeletable() const { return true; }
 };


@@ -4810,6 +4916,9 @@
   virtual Range* InferRange(Zone* zone) {
     return new(zone) Range(0, String::kMaxLength);
   }
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -4836,6 +4945,9 @@
   DECLARE_CONCRETE_INSTRUCTION(AllocateObject)

  private:
+ // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
+  //  virtual bool IsDeletable() const { return true; }
+
   Handle<JSFunction> constructor_;
 };

@@ -4852,6 +4964,8 @@
   int depth() const { return depth_; }

  private:
+  virtual bool IsDeletable() const { return true; }
+
   int literal_index_;
   int depth_;
 };
@@ -5027,6 +5141,8 @@
   bool pretenure() const { return pretenure_; }

  private:
+  virtual bool IsDeletable() const { return true; }
+
   Handle<SharedFunctionInfo> shared_info_;
   bool pretenure_;
 };
@@ -5051,6 +5167,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(Typeof)
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -5069,6 +5188,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -5083,6 +5205,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(ValueOf)
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


@@ -5279,6 +5404,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
+
+ private:
+  virtual bool IsDeletable() const { return true; }
 };


=======================================
--- /trunk/src/hydrogen.cc      Wed Oct 10 10:07:22 2012
+++ /trunk/src/hydrogen.cc      Thu Oct 11 08:57:38 2012
@@ -3358,6 +3358,7 @@

   EliminateRedundantBoundsChecks();
   DehoistSimpleArrayIndexComputations();
+  if (FLAG_dead_code_elimination) DeadCodeElimination();

   return true;
 }
@@ -3785,6 +3786,36 @@
     }
   }
 }
+
+
+void HGraph::DeadCodeElimination() {
+  HPhase phase("H_Dead code elimination", this);
+  ZoneList<HInstruction*> worklist(blocks_.length(), zone());
+  for (int i = 0; i < blocks()->length(); ++i) {
+    for (HInstruction* instr = blocks()->at(i)->first();
+         instr != NULL;
+         instr = instr->next()) {
+      if (instr->IsDead()) worklist.Add(instr, zone());
+    }
+  }
+
+  while (!worklist.is_empty()) {
+    HInstruction* instr = worklist.RemoveLast();
+    if (FLAG_trace_dead_code_elimination) {
+      HeapStringAllocator allocator;
+      StringStream stream(&allocator);
+      instr->PrintNameTo(&stream);
+      stream.Add(" = ");
+      instr->PrintTo(&stream);
+      PrintF("[removing dead instruction %s]\n", *stream.ToCString());
+    }
+    instr->DeleteAndReplaceWith(NULL);
+    for (int i = 0; i < instr->OperandCount(); ++i) {
+      HValue* operand = instr->OperandAt(i);
+ if (operand->IsDead()) worklist.Add(HInstruction::cast(operand), zone());
+    }
+  }
+}


 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
=======================================
--- /trunk/src/hydrogen.h       Thu Sep 20 05:51:09 2012
+++ /trunk/src/hydrogen.h       Thu Oct 11 08:57:38 2012
@@ -268,6 +268,7 @@
   void ReplaceCheckedValues();
   void EliminateRedundantBoundsChecks();
   void DehoistSimpleArrayIndexComputations();
+  void DeadCodeElimination();
   void PropagateDeoptimizingMark();

   // Returns false if there are phi-uses of the arguments-object
=======================================
--- /trunk/src/ia32/macro-assembler-ia32.cc     Tue Oct  9 10:00:13 2012
+++ /trunk/src/ia32/macro-assembler-ia32.cc     Thu Oct 11 08:57:38 2012
@@ -2581,8 +2581,7 @@
            isolate()->factory()->fixed_array_map(),
            &fail,
            DONT_DO_SMI_CHECK);
- mov(temp, FieldOperand(temp, TransitionArray::kDescriptorsPointerOffset));
-  mov(descriptors, FieldOperand(temp, JSGlobalPropertyCell::kValueOffset));
+ mov(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));
   jmp(&ok);

   bind(&fail);
@@ -2593,8 +2592,7 @@

   bind(&load_from_back_pointer);
   mov(temp, FieldOperand(temp, Map::kTransitionsOrBackPointerOffset));
- mov(temp, FieldOperand(temp, TransitionArray::kDescriptorsPointerOffset));
-  mov(descriptors, FieldOperand(temp, JSGlobalPropertyCell::kValueOffset));
+ mov(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));

   bind(&ok);
 }
=======================================
--- /trunk/src/messages.js      Wed Oct 10 10:07:22 2012
+++ /trunk/src/messages.js      Thu Oct 11 08:57:38 2012
@@ -229,7 +229,7 @@
"strict_catch_variable", ["Catch variable may not be eval or arguments in strict mode"], "too_many_arguments", ["Too many arguments in function call (only 32766 allowed)"], "too_many_parameters", ["Too many parameters in function definition (only 32766 allowed)"], - "too_many_variables", ["Too many variables declared (only 65535 allowed)"], + "too_many_variables", ["Too many variables declared (only 131071 allowed)"], "strict_param_name", ["Parameter name eval or arguments is not allowed in strict mode"], "strict_param_dupe", ["Strict mode function may not have duplicate parameter names"], "strict_var_name", ["Variable name may not be eval or arguments in strict mode"],
=======================================
--- /trunk/src/mips/macro-assembler-mips.cc     Wed Oct 10 10:07:22 2012
+++ /trunk/src/mips/macro-assembler-mips.cc     Thu Oct 11 08:57:38 2012
@@ -5305,8 +5305,7 @@
            isolate()->factory()->fixed_array_map(),
            &fail,
            DONT_DO_SMI_CHECK);
- lw(temp, FieldMemOperand(temp, TransitionArray::kDescriptorsPointerOffset)); - lw(descriptors, FieldMemOperand(temp, JSGlobalPropertyCell::kValueOffset)); + lw(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));
   jmp(&ok);

   bind(&fail);
@@ -5317,8 +5316,7 @@

   bind(&load_from_back_pointer);
   lw(temp, FieldMemOperand(temp, Map::kTransitionsOrBackPointerOffset));
- lw(temp, FieldMemOperand(temp, TransitionArray::kDescriptorsPointerOffset)); - lw(descriptors, FieldMemOperand(temp, JSGlobalPropertyCell::kValueOffset)); + lw(descriptors, FieldMemOperand(temp, TransitionArray::kDescriptorsOffset));

   bind(&ok);
 }
=======================================
--- /trunk/src/objects-inl.h    Wed Oct 10 10:07:22 2012
+++ /trunk/src/objects-inl.h    Thu Oct 11 08:57:38 2012
@@ -2163,12 +2163,6 @@
   set(ToValueIndex(descriptor_number), desc->GetValue());
   set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
 }
-
-
-void DescriptorArray::EraseDescriptor(Heap* heap, int descriptor_number) {
-  set_null_unchecked(heap, ToKeyIndex(descriptor_number));
-  set_null_unchecked(heap, ToValueIndex(descriptor_number));
-}


 void DescriptorArray::Append(Descriptor* desc,
@@ -3552,12 +3546,6 @@
   WRITE_FIELD(this, kPrototypeOffset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
 }
-
-
-JSGlobalPropertyCell* Map::descriptors_pointer() {
-  ASSERT(HasTransitionArray());
-  return transitions()->descriptors_pointer();
-}


 DescriptorArray* Map::instance_descriptors() {
@@ -3576,22 +3564,20 @@
static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) {
   TransitionArray* transitions;
   MaybeObject* maybe_transitions;
-  if (map->HasTransitionArray()) {
-    if (kind != FULL_TRANSITION_ARRAY ||
-        map->transitions()->IsFullTransitionArray()) {
-      return map;
-    }
-    maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
-    if (!maybe_transitions->To(&transitions)) return maybe_transitions;
-  } else {
-    JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer();
+  if (!map->HasTransitionArray()) {
     if (kind == FULL_TRANSITION_ARRAY) {
-      maybe_transitions = TransitionArray::Allocate(0, pointer);
+      maybe_transitions = TransitionArray::Allocate(0);
     } else {
- maybe_transitions = TransitionArray::AllocateDescriptorsHolder(pointer);
+      maybe_transitions = TransitionArray::AllocateDescriptorsHolder();
     }
     if (!maybe_transitions->To(&transitions)) return maybe_transitions;
     transitions->set_back_pointer_storage(map->GetBackPointer());
+  } else if (kind == FULL_TRANSITION_ARRAY &&
+             !map->transitions()->IsFullTransitionArray()) {
+    maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
+    if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+  } else {
+    return map;
   }
   map->set_transitions(transitions);
   return transitions;
@@ -3699,25 +3685,14 @@
                              TransitionArray::kTransitionSize)
       <= Page::kMaxNonCodeHeapObjectSize;
 }
-
-
-JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() {
-  if (!owns_descriptors()) return NULL;
-  Object* back_pointer = GetBackPointer();
-  if (back_pointer->IsUndefined()) return NULL;
-  Map* map = Map::cast(back_pointer);
-  ASSERT(map->HasTransitionArray());
-  return map->transitions()->descriptors_pointer();
-}


 MaybeObject* Map::AddTransition(String* key,
                                 Map* target,
                                 SimpleTransitionFlag flag) {
   if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
-  JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer();
   return TransitionArray::NewWith(
-      flag, key, target, descriptors_pointer, GetBackPointer());
+      flag, key, target, instance_descriptors(), GetBackPointer());
 }


@@ -3732,9 +3707,11 @@


 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
+  DescriptorArray* descriptors = instance_descriptors();
   MaybeObject* allow_elements =
       EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY);
   if (allow_elements->IsFailure()) return allow_elements;
+  transitions()->set_descriptors(descriptors);
   transitions()->set_elements_transition(transitioned_map);
   return this;
 }
@@ -3750,6 +3727,7 @@


 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
+  DescriptorArray* descriptors = instance_descriptors();
   MaybeObject* allow_prototype =
       EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY);
   if (allow_prototype->IsFailure()) return allow_prototype;
@@ -3759,6 +3737,7 @@
     ZapPrototypeTransitions();
   }
 #endif
+  transitions()->set_descriptors(descriptors);
   transitions()->SetPrototypeTransitions(proto_transitions);
   return this;
 }
=======================================
--- /trunk/src/objects-visiting-inl.h   Wed Oct 10 10:07:22 2012
+++ /trunk/src/objects-visiting-inl.h   Thu Oct 11 08:57:38 2012
@@ -328,7 +328,11 @@

   // Skip recording the descriptors_pointer slot since the cell space
   // is not compacted and descriptors are referenced through a cell.
-  StaticVisitor::MarkObject(heap, transitions->descriptors_pointer());
+  Object** descriptors_slot = transitions->GetDescriptorsSlot();
+  HeapObject* descriptors = HeapObject::cast(*descriptors_slot);
+  StaticVisitor::MarkObject(heap, descriptors);
+  heap->mark_compact_collector()->RecordSlot(
+      descriptors_slot, descriptors_slot, descriptors);

   // Simple transitions do not have keys nor prototype transitions.
   if (transitions->IsSimpleTransition()) return;
=======================================
--- /trunk/src/objects.cc       Wed Oct 10 10:07:22 2012
+++ /trunk/src/objects.cc       Thu Oct 11 08:57:38 2012
@@ -1777,13 +1777,7 @@
   // allocation that may fail.
   if (!old_target->StoresOwnDescriptors()) {
     DescriptorArray* old_descriptors = old_map->instance_descriptors();
-
-    old_target->SetBackPointer(GetHeap()->undefined_value());
MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors); - // Reset the backpointer before returning failure, otherwise the map ends up
-    // with an undefined backpointer and no descriptors, losing its own
-    // descriptors. Setting the backpointer always succeeds.
-    old_target->SetBackPointer(old_map);
     if (maybe_failure->IsFailure()) return maybe_failure;
   }

@@ -1802,36 +1796,29 @@
   // invalid back pointers. This will change once we can store multiple
   // transitions with the same key.

-  if (old_map->owns_descriptors()) {
-    // If the old map owns its own descriptors, transfer ownership to the
- // new_map and install its descriptors in the old_map. Since the old_map - // stores the descriptors for the new_map, remove the transition array of
-    // the new_map that is only in place to store the descriptors.
-    old_map->transitions()->descriptors_pointer()->set_value(
-        new_map->instance_descriptors());
-    new_map->ClearTransitions(GetHeap());
-    old_map->set_owns_descriptors(false);
-  } else if (old_target->instance_descriptors() ==
-             old_map->instance_descriptors()) {
+  bool owned_descriptors = old_map->owns_descriptors();
+  if (owned_descriptors ||
+ old_target->instance_descriptors() == old_map->instance_descriptors()) { // Since the conversion above generated a new fast map with an additional // property which can be shared as well, install this descriptor pointer // along the entire chain of smaller maps; and remove the transition array
     // that is only in place to hold the descriptor array in the new map.
     Map* map;
-    JSGlobalPropertyCell* new_pointer =
-        new_map->transitions()->descriptors_pointer();
-    JSGlobalPropertyCell* old_pointer =
-        old_map->transitions()->descriptors_pointer();
+    DescriptorArray* new_descriptors = new_map->instance_descriptors();
+    DescriptorArray* old_descriptors = old_map->instance_descriptors();
+    if (old_descriptors->HasEnumCache()) {
+      new_descriptors->CopyEnumCacheFrom(old_descriptors);
+    }
     for (Object* current = old_map;
          !current->IsUndefined();
          current = map->GetBackPointer()) {
       map = Map::cast(current);
       if (!map->HasTransitionArray()) break;
       TransitionArray* transitions = map->transitions();
-      if (transitions->descriptors_pointer() != old_pointer) break;
-      map->SetEnumLength(Map::kInvalidEnumCache);
-      transitions->set_descriptors_pointer(new_pointer);
+      if (transitions->descriptors() != old_descriptors) break;
+      transitions->set_descriptors(new_descriptors);
     }
+    old_map->set_owns_descriptors(false);
     new_map->ClearTransitions(GetHeap());
   }

@@ -4975,15 +4962,13 @@
 }


-MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
+MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
+                                  Descriptor* descriptor) {
// Sanity check. This path is only to be taken if the map owns its descriptor
   // array, implying that its NumberOfOwnDescriptors equals the number of
   // descriptors in the descriptor array.
-  if (NumberOfOwnDescriptors() !=
-      instance_descriptors()->number_of_descriptors()) {
-    Isolate::Current()->PushStackTraceAndDie(
-          0xDEAD0002, GetBackPointer(), this, 0xDEAD0003);
-  }
+  ASSERT(NumberOfOwnDescriptors() ==
+         instance_descriptors()->number_of_descriptors());
   Map* result;
   MaybeObject* maybe_result = CopyDropDescriptors();
   if (!maybe_result->To(&result)) return maybe_result;
@@ -4995,7 +4980,6 @@
       AddTransition(name, result, SIMPLE_TRANSITION);
   if (!maybe_transitions->To(&transitions)) return maybe_transitions;

-  DescriptorArray* descriptors = instance_descriptors();
   int old_size = descriptors->number_of_descriptors();

   DescriptorArray* new_descriptors;
@@ -5026,9 +5010,21 @@
     if (descriptors->HasEnumCache()) {
       new_descriptors->CopyEnumCacheFrom(descriptors);
     }
-  }

-  transitions->set_descriptors(new_descriptors);
+    Map* map;
+    // Replace descriptors by new_descriptors in all maps that share it.
+    for (Object* current = GetBackPointer();
+         !current->IsUndefined();
+         current = map->GetBackPointer()) {
+      map = Map::cast(current);
+      if (!map->HasTransitionArray()) break;
+      TransitionArray* transitions = map->transitions();
+      if (transitions->descriptors() != descriptors) break;
+      transitions->set_descriptors(new_descriptors);
+    }
+
+    transitions->set_descriptors(new_descriptors);
+  }

   set_transitions(transitions);
   result->SetBackPointer(this);
@@ -5073,7 +5069,7 @@
// If the copied map has no added fields, and the parent map owns its
         // descriptors, those descriptors have to be empty. In that case,
         // transfer ownership of the descriptors to the new child.
-        CHECK(instance_descriptors()->IsEmpty());
+        ASSERT(instance_descriptors()->IsEmpty());
         set_owns_descriptors(false);
       } else {
// If the parent did not own its own descriptors, it may share a larger
@@ -5201,7 +5197,7 @@
   if (flag == INSERT_TRANSITION &&
       owns_descriptors() &&
       CanHaveMoreTransitions()) {
-    return ShareDescriptor(descriptor);
+    return ShareDescriptor(descriptors, descriptor);
   }

   DescriptorArray* new_descriptors;
@@ -5241,7 +5237,7 @@
   // We replace the key if it is already present.
   int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this);
   if (index != DescriptorArray::kNotFound) {
-    return CopyReplaceDescriptor(descriptor, index, flag);
+    return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag);
   }
   return CopyAddDescriptor(descriptor, flag);
 }
@@ -5267,15 +5263,14 @@
 }


-MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor,
+MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors,
+                                        Descriptor* descriptor,
                                         int insertion_index,
                                         TransitionFlag flag) {
   // Ensure the key is a symbol.
   MaybeObject* maybe_failure = descriptor->KeyToSymbol();
   if (maybe_failure->IsFailure()) return maybe_failure;

-  DescriptorArray* descriptors = instance_descriptors();
-
   String* key = descriptor->GetKey();
   ASSERT(key == descriptors->GetKey(insertion_index));

@@ -7458,17 +7453,7 @@
   int to_trim = number_of_descriptors - number_of_own_descriptors;
   if (to_trim <= 0) return;

-  // Maximally keep 50% of unused descriptors.
-  int keep = Min(to_trim, number_of_own_descriptors / 2);
-  for (int i = number_of_own_descriptors;
-       i < number_of_own_descriptors + keep;
-       ++i) {
-    descriptors->EraseDescriptor(heap, i);
-  }
-
-  if (to_trim > keep) {
-    RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep);
-  }
+  RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim);
   descriptors->SetNumberOfDescriptors(number_of_own_descriptors);

   if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
@@ -7546,7 +7531,6 @@
     } else {
       t->set_descriptors(heap->empty_descriptor_array());
     }
-    set_owns_descriptors(true);
   }

   int trim = t->number_of_transitions() - transition_index;
=======================================
--- /trunk/src/objects.h        Wed Oct 10 10:07:22 2012
+++ /trunk/src/objects.h        Thu Oct 11 08:57:38 2012
@@ -2573,7 +2573,6 @@
                   Descriptor* desc,
                   const WhitenessWitness&);
   inline void Set(int descriptor_number, Descriptor* desc);
-  inline void EraseDescriptor(Heap* heap, int descriptor_number);

// Append automatically sets the enumeration index. This should only be used // to add descriptors in bulk at the end, followed by sorting the descriptor
@@ -4890,7 +4889,6 @@

   // [instance descriptors]: describes the object.
   inline DescriptorArray* instance_descriptors();
-  inline JSGlobalPropertyCell* descriptors_pointer();
   MUST_USE_RESULT inline MaybeObject* SetDescriptors(
       DescriptorArray* descriptors);
   static void SetDescriptors(Handle<Map> map,
@@ -5004,14 +5002,17 @@
       String* name,
       TransitionFlag flag,
       int descriptor_index);
-  MUST_USE_RESULT MaybeObject* ShareDescriptor(Descriptor* descriptor);
+ MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
+                                               Descriptor* descriptor);
   MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
                                                  TransitionFlag flag);
   MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
                                                     TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(Descriptor* descriptor,
-                                                     int index,
-                                                     TransitionFlag flag);
+  MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
+      DescriptorArray* descriptors,
+      Descriptor* descriptor,
+      int index,
+      TransitionFlag flag);
   MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
                                                   TransitionFlag flag);

=======================================
--- /trunk/src/parser.h Wed Oct 10 10:07:22 2012
+++ /trunk/src/parser.h Thu Oct 11 08:57:38 2012
@@ -454,7 +454,7 @@
   // construct a hashable id, so if more than 2^17 are allowed, this
   // should be checked.
   static const int kMaxNumFunctionParameters = 32766;
-  static const int kMaxNumFunctionLocals = 65535;
+  static const int kMaxNumFunctionLocals = 131071;  // 2^17-1

   enum Mode {
     PARSE_LAZILY,
=======================================
--- /trunk/src/profile-generator.cc     Tue Oct  9 10:00:13 2012
+++ /trunk/src/profile-generator.cc     Thu Oct 11 08:57:38 2012
@@ -2009,14 +2009,11 @@
                        Map::kConstructorOffset);
   if (map->HasTransitionArray()) {
     TransitionArray* transitions = map->transitions();
-    JSGlobalPropertyCell* pointer = transitions->descriptors_pointer();
     DescriptorArray* descriptors = transitions->descriptors();
     TagObject(descriptors, "(map descriptors)");
-    SetInternalReference(pointer, entry,
+    SetInternalReference(transitions, entry,
                          "descriptors", descriptors,
-                         JSGlobalPropertyCell::kValueOffset);
-    IndexedReferencesExtractor pointer_refs(this, pointer, entry);
-    pointer->Iterate(&pointer_refs);
+                         TransitionArray::kDescriptorsOffset);

     Object* back_pointer = transitions->back_pointer_storage();
     TagObject(transitions->back_pointer_storage(), "(back pointer)");
=======================================
--- /trunk/src/property-details.h       Tue Aug 28 02:06:19 2012
+++ /trunk/src/property-details.h       Thu Oct 11 08:57:38 2012
@@ -96,7 +96,9 @@

   PropertyType type() { return TypeField::decode(value_); }

- PropertyAttributes attributes() { return AttributesField::decode(value_); }
+  PropertyAttributes attributes() const {
+    return AttributesField::decode(value_);
+  }

   int dictionary_index() {
     return DictionaryStorageField::decode(value_);
@@ -112,10 +114,10 @@
     return DictionaryStorageField::is_valid(index);
   }

-  bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; }
-  bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; }
-  bool IsDontEnum() { return (attributes() & DONT_ENUM) != 0; }
-  bool IsDeleted() { return DeletedField::decode(value_) != 0;}
+  bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
+  bool IsDontDelete() const { return (attributes() & DONT_DELETE) != 0; }
+  bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
+  bool IsDeleted() const { return DeletedField::decode(value_) != 0;}

   // Bit fields in value_ (type, shift, size). Must be public so the
   // constants can be embedded in generated code.
=======================================
--- /trunk/src/runtime.cc       Wed Oct 10 10:07:22 2012
+++ /trunk/src/runtime.cc       Thu Oct 11 08:57:38 2012
@@ -2179,7 +2179,7 @@
     Map* new_map;
     MaybeObject* maybe_map =
         function->map()->CopyReplaceDescriptor(
-            &new_desc, index, OMIT_TRANSITION);
+            instance_desc, &new_desc, index, OMIT_TRANSITION);
     if (!maybe_map->To(&new_map)) return maybe_map;

     function->set_map(new_map);
@@ -9083,7 +9083,7 @@
   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
     Handle<Object> error_message =
-        context->ErrorMessageForCodeGenerationFromStrings();
+        native_context->ErrorMessageForCodeGenerationFromStrings();
     isolate->Throw(*isolate->factory()->NewEvalError(
         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
     return MakePair(Failure::Exception(), NULL);
=======================================
--- /trunk/src/transitions-inl.h        Wed Oct 10 10:07:22 2012
+++ /trunk/src/transitions-inl.h        Thu Oct 11 08:57:38 2012
@@ -84,27 +84,20 @@
 }


-DescriptorArray* TransitionArray::descriptors() {
-  return DescriptorArray::cast(descriptors_pointer()->value());
+Object** TransitionArray::GetDescriptorsSlot() {
+  return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
+                              kDescriptorsOffset);
 }


-void TransitionArray::set_descriptors(DescriptorArray* descriptors) {
-  ASSERT(!this->descriptors()->IsDescriptorArray() ||
-         descriptors->number_of_descriptors() == 0 ||
-         descriptors->HasEnumCache() ||
-         !this->descriptors()->HasEnumCache());
-  descriptors_pointer()->set_value(descriptors);
-}
-
-
-JSGlobalPropertyCell* TransitionArray::descriptors_pointer() {
-  return JSGlobalPropertyCell::cast(get(kDescriptorsPointerIndex));
+DescriptorArray* TransitionArray::descriptors() {
+  return DescriptorArray::cast(get(kDescriptorsIndex));
 }


-void TransitionArray::set_descriptors_pointer(JSGlobalPropertyCell* pointer) {
-  set(kDescriptorsPointerIndex, pointer);
+void TransitionArray::set_descriptors(DescriptorArray* descriptors) {
+  ASSERT(descriptors->IsDescriptorArray());
+  set(kDescriptorsIndex, descriptors);
 }


=======================================
--- /trunk/src/transitions.cc   Wed Oct 10 10:07:22 2012
+++ /trunk/src/transitions.cc   Thu Oct 11 08:57:38 2012
@@ -35,31 +35,20 @@
 namespace internal {


-static MaybeObject* AllocateRaw(int length,
-                                JSGlobalPropertyCell* descriptors_cell) {
+static MaybeObject* AllocateRaw(int length) {
   Heap* heap = Isolate::Current()->heap();

-  if (descriptors_cell == NULL) {
-    MaybeObject* maybe_cell =
-        heap->AllocateJSGlobalPropertyCell(heap->empty_descriptor_array());
-    if (!maybe_cell->To(&descriptors_cell)) return maybe_cell;
-  }
-
   // Use FixedArray to not use TransitionArray::cast on incomplete object.
   FixedArray* array;
   MaybeObject* maybe_array = heap->AllocateFixedArray(length);
   if (!maybe_array->To(&array)) return maybe_array;
-
-  array->set(TransitionArray::kDescriptorsPointerIndex, descriptors_cell);
   return array;
 }


-MaybeObject* TransitionArray::Allocate(int number_of_transitions,
- JSGlobalPropertyCell* descriptors_cell) {
+MaybeObject* TransitionArray::Allocate(int number_of_transitions) {
   FixedArray* array;
-  MaybeObject* maybe_array =
-      AllocateRaw(ToKeyIndex(number_of_transitions), descriptors_cell);
+ MaybeObject* maybe_array = AllocateRaw(ToKeyIndex(number_of_transitions));
   if (!maybe_array->To(&array)) return maybe_array;
   array->set(kElementsTransitionIndex, Smi::FromInt(0));
   array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
@@ -84,28 +73,28 @@
 MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
                                       String* key,
                                       Map* target,
- JSGlobalPropertyCell* descriptors_pointer,
+                                      DescriptorArray* descriptors,
                                       Object* back_pointer) {
   TransitionArray* result;
   MaybeObject* maybe_result;

   if (flag == SIMPLE_TRANSITION) {
-    maybe_result = AllocateRaw(kSimpleTransitionSize, descriptors_pointer);
+    maybe_result = AllocateRaw(kSimpleTransitionSize);
     if (!maybe_result->To(&result)) return maybe_result;
     result->set(kSimpleTransitionTarget, target);
   } else {
-    maybe_result = Allocate(1, descriptors_pointer);
+    maybe_result = Allocate(1);
     if (!maybe_result->To(&result)) return maybe_result;
     result->NoIncrementalWriteBarrierSet(0, key, target);
   }
   result->set_back_pointer_storage(back_pointer);
+  result->set_descriptors(descriptors);
   return result;
 }


-MaybeObject* TransitionArray::AllocateDescriptorsHolder(
-    JSGlobalPropertyCell* descriptors_pointer) {
-  return AllocateRaw(kDescriptorsHolderSize, descriptors_pointer);
+MaybeObject* TransitionArray::AllocateDescriptorsHolder() {
+  return AllocateRaw(kDescriptorsHolderSize);
 }


@@ -113,13 +102,14 @@
   ASSERT(!IsFullTransitionArray());
   int nof = number_of_transitions();
   TransitionArray* result;
-  MaybeObject* maybe_result = Allocate(nof, descriptors_pointer());
+  MaybeObject* maybe_result = Allocate(nof);
   if (!maybe_result->To(&result)) return maybe_result;

   if (nof == 1) {
result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
   }

+  result->set_descriptors(descriptors());
   result->set_back_pointer_storage(back_pointer_storage());
   return result;
 }
@@ -135,9 +125,11 @@
   if (insertion_index == kNotFound) ++new_size;

   MaybeObject* maybe_array;
-  maybe_array = TransitionArray::Allocate(new_size, descriptors_pointer());
+  maybe_array = TransitionArray::Allocate(new_size);
   if (!maybe_array->To(&result)) return maybe_array;

+  result->set_descriptors(descriptors());
+
   if (HasElementsTransition()) {
     result->set_elements_transition(elements_transition());
   }
=======================================
--- /trunk/src/transitions.h    Wed Oct 10 10:07:22 2012
+++ /trunk/src/transitions.h    Thu Oct 11 08:57:38 2012
@@ -71,10 +71,9 @@
   inline bool HasElementsTransition();
   inline void ClearElementsTransition();

+  inline Object** GetDescriptorsSlot();
   inline DescriptorArray* descriptors();
   inline void set_descriptors(DescriptorArray* descriptors);
-  inline JSGlobalPropertyCell* descriptors_pointer();
-  inline void set_descriptors_pointer(JSGlobalPropertyCell* pointer);

   inline Object* back_pointer_storage();
   inline void set_back_pointer_storage(
@@ -103,11 +102,10 @@
       SimpleTransitionFlag flag,
       String* key,
       Map* target,
-      JSGlobalPropertyCell* descriptor_pointer,
+      DescriptorArray* descriptors,
       Object* back_pointer);

-  static MUST_USE_RESULT MaybeObject* AllocateDescriptorsHolder(
-      JSGlobalPropertyCell* descriptor_pointer);
+  static MUST_USE_RESULT MaybeObject* AllocateDescriptorsHolder();

   MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();

@@ -125,9 +123,7 @@
   inline int Search(String* name);

   // Allocates a TransitionArray.
-  MUST_USE_RESULT static MaybeObject* Allocate(
-      int number_of_transitions,
-      JSGlobalPropertyCell* descriptors_cell);
+  MUST_USE_RESULT static MaybeObject* Allocate(int number_of_transitions);

   bool IsDescriptorsHolder() { return length() == kDescriptorsHolderSize; }
   bool IsSimpleTransition() { return length() == kSimpleTransitionSize; }
@@ -139,7 +135,7 @@
   // Constant for denoting key was not found.
   static const int kNotFound = -1;

-  static const int kDescriptorsPointerIndex = 0;
+  static const int kDescriptorsIndex = 0;
   static const int kBackPointerStorageIndex = 1;
   static const int kDescriptorsHolderSize = 2;

@@ -154,8 +150,8 @@
   static const int kSimpleTransitionIndex = 0;
   STATIC_ASSERT(kSimpleTransitionIndex != kNotFound);

-  static const int kDescriptorsPointerOffset = FixedArray::kHeaderSize;
-  static const int kBackPointerStorageOffset = kDescriptorsPointerOffset +
+  static const int kDescriptorsOffset = FixedArray::kHeaderSize;
+  static const int kBackPointerStorageOffset = kDescriptorsOffset +
                                                kPointerSize;

   // Layout for the full transition array header.
=======================================
--- /trunk/src/utils.h  Wed Oct 10 10:07:22 2012
+++ /trunk/src/utils.h  Thu Oct 11 08:57:38 2012
@@ -862,7 +862,11 @@
  public:
   EmbeddedContainer() : elems_() { }

-  int length() { return NumElements; }
+  int length() const { return NumElements; }
+  const ElementType& operator[](int i) const {
+    ASSERT(i < length());
+    return elems_[i];
+  }
   ElementType& operator[](int i) {
     ASSERT(i < length());
     return elems_[i];
@@ -876,7 +880,12 @@
 template<typename ElementType>
 class EmbeddedContainer<ElementType, 0> {
  public:
-  int length() { return 0; }
+  int length() const { return 0; }
+  const ElementType& operator[](int i) const {
+    UNREACHABLE();
+    static ElementType t = 0;
+    return t;
+  }
   ElementType& operator[](int i) {
     UNREACHABLE();
     static ElementType t = 0;
=======================================
--- /trunk/src/version.cc       Wed Oct 10 10:07:22 2012
+++ /trunk/src/version.cc       Thu Oct 11 08:57:38 2012
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     14
-#define BUILD_NUMBER      2
+#define BUILD_NUMBER      3
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x64/macro-assembler-x64.cc       Tue Oct  9 10:00:13 2012
+++ /trunk/src/x64/macro-assembler-x64.cc       Thu Oct 11 08:57:38 2012
@@ -2925,8 +2925,7 @@
            isolate()->factory()->fixed_array_map(),
            &fail,
            DONT_DO_SMI_CHECK);
- movq(temp, FieldOperand(temp, TransitionArray::kDescriptorsPointerOffset)); - movq(descriptors, FieldOperand(temp, JSGlobalPropertyCell::kValueOffset)); + movq(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));
   jmp(&ok);

   bind(&fail);
@@ -2937,8 +2936,7 @@

   bind(&load_from_back_pointer);
   movq(temp, FieldOperand(temp, Map::kTransitionsOrBackPointerOffset));
- movq(temp, FieldOperand(temp, TransitionArray::kDescriptorsPointerOffset)); - movq(descriptors, FieldOperand(temp, JSGlobalPropertyCell::kValueOffset)); + movq(descriptors, FieldOperand(temp, TransitionArray::kDescriptorsOffset));

   bind(&ok);
 }
=======================================
--- /trunk/test/mjsunit/limit-locals.js Wed Oct 10 10:07:22 2012
+++ /trunk/test/mjsunit/limit-locals.js Thu Oct 11 08:57:38 2012
@@ -25,7 +25,9 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Test that there is a limit of 65535 locals.
+// Test that there is a limit of 131071 locals.
+
+// Flags: --stack-size=1200

 function function_with_n_locals(n) {
   test_prefix = "prefix ";
@@ -40,8 +42,6 @@

 assertEquals("prefix 0 suffix", function_with_n_locals(0));
 assertEquals("prefix 16000 suffix", function_with_n_locals(16000));
-assertEquals("prefix 32767 suffix", function_with_n_locals(32767));
-assertEquals("prefix 65535 suffix", function_with_n_locals(65535));
+assertEquals("prefix 131071 suffix", function_with_n_locals(131071));

-assertThrows("function_with_n_locals(65536)");
-assertThrows("function_with_n_locals(100000)");
+assertThrows("function_with_n_locals(131072)");
=======================================
--- /trunk/tools/run-tests.py   Wed Oct 10 10:07:22 2012
+++ /trunk/tools/run-tests.py   Thu Oct 11 08:57:38 2012
@@ -56,9 +56,9 @@
                  ["--stress-opt", "--always-opt"],
                  ["--nocrankshaft"]]
 MODE_FLAGS = {
-    "debug"   : ["--nobreak-on-abort", "--enable-slow-asserts",
-                 "--debug-code", "--verify-heap"],
-    "release" : ["--nobreak-on-abort"]}
+    "debug"   : ["--nobreak-on-abort", "--nodead-code-elimination",
+                 "--enable-slow-asserts", "--debug-code", "--verify-heap"],
+    "release" : ["--nobreak-on-abort", "--nodead-code-elimination"]}


 def BuildOptions():
=======================================
--- /trunk/tools/test.py        Mon Jul 30 06:05:33 2012
+++ /trunk/tools/test.py        Thu Oct 11 08:57:38 2012
@@ -684,8 +684,9 @@
     'debug'   : '_g',
     'release' : '' }
 FLAGS = {
- 'debug' : ['--nobreak-on-abort', '--enable-slow-asserts', '--debug-code', '--verify-heap'],
-    'release' : ['--nobreak-on-abort']}
+    'debug'   : ['--nobreak-on-abort', '--nodead-code-elimination',
+                 '--enable-slow-asserts', '--debug-code', '--verify-heap'],
+    'release' : ['--nobreak-on-abort', '--nodead-code-elimination']}
 TIMEOUT_SCALEFACTOR = {
     'debug'   : 4,
     'release' : 1 }

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to