Version 3.21.2

Stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@16271 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 0f08575..89b875f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-22: Version 3.21.2
+
+        Stability improvements on all platforms.
+
+
 2013-08-21: Version 3.21.1
 
         Promoted ArrayBuffer, DataView and typed arrays to non-experimental.
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 4f6db35..9bbab9a 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -352,7 +352,7 @@
   HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
   HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
   if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) {
-    HValue* elements = AddLoadElements(boilerplate, NULL);
+    HValue* elements = AddLoadElements(boilerplate);
 
     IfBuilder if_fixed_cow(this);
     if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
@@ -513,7 +513,7 @@
   HObjectAccess access = casted_stub()->is_inobject() ?
       HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
       HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
-  return AddInstruction(BuildLoadNamedField(GetParameter(0), access, NULL));
+  return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
 }
 
 
@@ -528,7 +528,7 @@
   HObjectAccess access = casted_stub()->is_inobject() ?
       HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
       HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
-  return AddInstruction(BuildLoadNamedField(GetParameter(0), access, NULL));
+  return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
 }
 
 
diff --git a/src/debug.cc b/src/debug.cc
index 4966713..990a9a5 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1627,7 +1627,7 @@
 // object.
 bool Debug::IsDebugBreak(Address addr) {
   Code* code = Code::GetCodeFromTargetAddress(addr);
-  return code->is_debug_break();
+  return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
 }
 
 
diff --git a/src/elements.cc b/src/elements.cc
index 77abf4e..5cef12b 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -581,14 +581,8 @@
     // When objects are first allocated, its elements are Failures.
     if (fixed_array_base->IsFailure()) return;
     if (!fixed_array_base->IsHeapObject()) return;
-    Map* map = fixed_array_base->map();
     // Arrays that have been shifted in place can't be verified.
-    Heap* heap = holder->GetHeap();
-    if (map == heap->one_pointer_filler_map() ||
-        map == heap->two_pointer_filler_map() ||
-        map == heap->free_space_map()) {
-      return;
-    }
+    if (fixed_array_base->IsFiller()) return;
     int length = 0;
     if (holder->IsJSArray()) {
       Object* length_obj = JSArray::cast(holder)->length();
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index f5f2ef3..aed8591 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -356,8 +356,6 @@
             "enable use of SSE4.1 instructions if available")
 DEFINE_bool(enable_cmov, true,
             "enable use of CMOV instruction if available")
-DEFINE_bool(enable_rdtsc, true,
-            "enable use of RDTSC instruction if available")
 DEFINE_bool(enable_sahf, true,
             "enable use of SAHF instruction if available (X64 only)")
 DEFINE_bool(enable_vfp3, ENABLE_VFP3_DEFAULT,
diff --git a/src/flags.cc b/src/flags.cc
index 855e207..4e18cc8 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -268,6 +268,11 @@
 }
 
 
+inline char NormalizeChar(char ch) {
+  return ch == '_' ? '-' : ch;
+}
+
+
 // Helper function to parse flags: Takes an argument arg and splits it into
 // a flag name and flag value (or NULL if they are missing). is_bool is set
 // if the arg started with "-no" or "--no". The buffer may be used to NUL-
@@ -295,6 +300,7 @@
     }
     if (arg[0] == 'n' && arg[1] == 'o') {
       arg += 2;  // remove "no"
+      if (NormalizeChar(arg[0]) == '-') arg++;  // remove dash after "no".
       *is_bool = true;
     }
     *name = arg;
@@ -318,11 +324,6 @@
 }
 
 
-inline char NormalizeChar(char ch) {
-  return ch == '_' ? '-' : ch;
-}
-
-
 static bool EqualNames(const char* a, const char* b) {
   for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
     if (a[i] == '\0') {
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 3c1d4d2..6caa742 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -439,6 +439,43 @@
 }
 
 
+bool Heap::AllowedToBeMigrated(HeapObject* object, AllocationSpace dst) {
+  // Object migration is governed by the following rules:
+  //
+  // 1) Objects in new-space can be migrated to one of the old spaces
+  //    that matches their target space or they stay in new-space.
+  // 2) Objects in old-space stay in the same space when migrating.
+  // 3) Fillers (two or more words) can migrate due to left-trimming of
+  //    fixed arrays in new-space, old-data-space and old-pointer-space.
+  // 4) Fillers (one word) can never migrate, they are skipped by
+  //    incremental marking explicitly to prevent invalid pattern.
+  //
+  // Since this function is used for debugging only, we do not place
+  // asserts here, but check everything explicitly.
+  if (object->map() == one_pointer_filler_map()) return false;
+  InstanceType type = object->map()->instance_type();
+  MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
+  AllocationSpace src = chunk->owner()->identity();
+  switch (src) {
+    case NEW_SPACE:
+      return dst == src || dst == TargetSpaceId(type);
+    case OLD_POINTER_SPACE:
+      return dst == src && (dst == TargetSpaceId(type) || object->IsFiller());
+    case OLD_DATA_SPACE:
+      return dst == src && dst == TargetSpaceId(type);
+    case CODE_SPACE:
+      return dst == src && type == CODE_TYPE;
+    case MAP_SPACE:
+    case CELL_SPACE:
+    case PROPERTY_CELL_SPACE:
+    case LO_SPACE:
+      return false;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
 void Heap::CopyBlock(Address dst, Address src, int byte_size) {
   CopyWords(reinterpret_cast<Object**>(dst),
             reinterpret_cast<Object**>(src),
diff --git a/src/heap.cc b/src/heap.cc
index 623ec31..450c1c3 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2088,10 +2088,13 @@
       MaybeObject* maybe_result;
 
       if (object_contents == DATA_OBJECT) {
+        // TODO(mstarzinger): Turn this check into a regular assert soon!
+        CHECK(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE));
         maybe_result = heap->old_data_space()->AllocateRaw(allocation_size);
       } else {
-        maybe_result =
-            heap->old_pointer_space()->AllocateRaw(allocation_size);
+        // TODO(mstarzinger): Turn this check into a regular assert soon!
+        CHECK(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE));
+        maybe_result = heap->old_pointer_space()->AllocateRaw(allocation_size);
       }
 
       Object* result = NULL;  // Initialization to please compiler.
@@ -2121,6 +2124,8 @@
         return;
       }
     }
+    // TODO(mstarzinger): Turn this check into a regular assert soon!
+    CHECK(heap->AllowedToBeMigrated(object, NEW_SPACE));
     MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size);
     heap->promotion_queue()->SetNewLimit(heap->new_space()->top());
     Object* result = allocation->ToObjectUnchecked();
diff --git a/src/heap.h b/src/heap.h
index e0ffa63..3472ec0 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1391,6 +1391,10 @@
   inline OldSpace* TargetSpace(HeapObject* object);
   static inline AllocationSpace TargetSpaceId(InstanceType type);
 
+  // Checks whether the given object is allowed to be migrated from it's
+  // current space into the given destination space. Used for debugging.
+  inline bool AllowedToBeMigrated(HeapObject* object, AllocationSpace dest);
+
   // Sets the stub_cache_ (only used when expanding the dictionary).
   void public_set_code_stubs(UnseededNumberDictionary* value) {
     roots_[kCodeStubsRootIndex] = value;
diff --git a/src/hydrogen-escape-analysis.cc b/src/hydrogen-escape-analysis.cc
index 0359678..af77c16 100644
--- a/src/hydrogen-escape-analysis.cc
+++ b/src/hydrogen-escape-analysis.cc
@@ -215,7 +215,6 @@
           for (HUseIterator it(mapcheck->uses()); !it.Done(); it.Advance()) {
             if (!it.value()->IsLoadNamedField()) continue;
             HLoadNamedField* load = HLoadNamedField::cast(it.value());
-            ASSERT(load->typecheck() == mapcheck);
             load->ClearTypeCheck();
           }
           ASSERT(mapcheck->HasNoUses());
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 28101d8..8a1652a 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -2849,10 +2849,6 @@
 void HLoadNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   access_.PrintTo(stream);
-  if (HasTypeCheck()) {
-    stream->Add(" ");
-    typecheck()->PrintNameTo(stream);
-  }
 }
 
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index bef46df..86bc654 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1371,6 +1371,9 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CompareMap)
 
+ protected:
+  virtual int RedefinedOperandIndex() { return 0; }
+
  private:
   Handle<Map> map_;
 };
@@ -2575,6 +2578,8 @@
     return true;
   }
 
+  virtual int RedefinedOperandIndex() { return 0; }
+
  private:
   void Add(Handle<Map> map, Zone* zone) {
     map_set_.Add(map, zone);
@@ -2699,6 +2704,8 @@
     return check_ == b->check_;
   }
 
+  virtual int RedefinedOperandIndex() { return 0; }
+
  private:
   enum Check {
     IS_SPEC_OBJECT,
@@ -5585,20 +5592,13 @@
 };
 
 
-class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
+class HLoadNamedField V8_FINAL : public HTemplateInstruction<1> {
  public:
   DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess);
-  DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess,
-                                 HValue*);
 
   HValue* object() { return OperandAt(0); }
-  HValue* typecheck() {
-    ASSERT(HasTypeCheck());
-    return OperandAt(1);
-  }
-
-  bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
-  void ClearTypeCheck() { SetOperandAt(1, object()); }
+  bool HasTypeCheck() { return object()->IsCheckMaps(); }
+  void ClearTypeCheck() { SetOperandAt(0, object()->ActualValue()); }
   HObjectAccess access() const { return access_; }
   Representation field_representation() const {
       return access_.representation();
@@ -5624,13 +5624,9 @@
   }
 
  private:
-  HLoadNamedField(HValue* object,
-                  HObjectAccess access,
-                  HValue* typecheck = NULL)
-      : access_(access) {
+  HLoadNamedField(HValue* object, HObjectAccess access) : access_(access) {
     ASSERT(object != NULL);
     SetOperandAt(0, object);
-    SetOperandAt(1, typecheck != NULL ? typecheck : object);
 
     Representation representation = access.representation();
     if (representation.IsSmi()) {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 9abca53..d77147b 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1191,7 +1191,7 @@
   }
 
   if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
-    HInstruction* elements = AddLoadElements(object, NULL);
+    HInstruction* elements = AddLoadElements(object);
 
     HInstruction* empty_fixed_array = Add<HConstant>(
         isolate()->factory()->empty_fixed_array());
@@ -1222,7 +1222,7 @@
     HValue* object,
     HValue* key,
     HValue* val,
-    HCheckMaps* mapcheck,
+    HCheckMaps* checked_object,
     bool is_js_array,
     ElementsKind elements_kind,
     bool is_store,
@@ -1237,13 +1237,14 @@
   // generated store code.
   if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
       (elements_kind == FAST_ELEMENTS && is_store)) {
-    if (mapcheck != NULL) {
-      mapcheck->ClearGVNFlag(kDependsOnElementsKind);
+    if (checked_object != NULL) {
+      checked_object->ClearGVNFlag(kDependsOnElementsKind);
     }
   }
+  if (checked_object != NULL) object = checked_object;
   bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
   bool fast_elements = IsFastObjectElementsKind(elements_kind);
-  HValue* elements = AddLoadElements(object, mapcheck);
+  HValue* elements = AddLoadElements(object);
   if (is_store && (fast_elements || fast_smi_only_elements) &&
       store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
     HCheckMaps* check_cow_map = Add<HCheckMaps>(
@@ -1252,8 +1253,8 @@
   }
   HInstruction* length = NULL;
   if (is_js_array) {
-    length = Add<HLoadNamedField>(object,
-        HObjectAccess::ForArrayLength(elements_kind), mapcheck);
+    length = Add<HLoadNamedField>(
+        object, HObjectAccess::ForArrayLength(elements_kind));
   } else {
     length = AddLoadFixedArrayLength(elements);
   }
@@ -1283,7 +1284,7 @@
           Add<HLoadExternalArrayPointer>(elements);
       return AddExternalArrayElementAccess(
           external_elements, checked_key, val,
-          mapcheck, elements_kind, is_store);
+          checked_object, elements_kind, is_store);
     }
   }
   ASSERT(fast_smi_only_elements ||
@@ -1320,7 +1321,7 @@
       }
     }
   }
-  return AddFastElementAccess(elements, checked_key, val, mapcheck,
+  return AddFastElementAccess(elements, checked_key, val, checked_object,
                               elements_kind, is_store, load_mode, store_mode);
 }
 
@@ -1493,11 +1494,8 @@
 }
 
 
-HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
-                                                HValue* typecheck) {
-  return Add<HLoadNamedField>(object,
-                              HObjectAccess::ForElementsPointer(),
-                              typecheck);
+HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) {
+  return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer());
 }
 
 
@@ -1713,7 +1711,7 @@
   if (length > 0) {
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
-    HValue* boilerplate_elements = AddLoadElements(boilerplate, NULL);
+    HValue* boilerplate_elements = AddLoadElements(boilerplate);
     HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
     Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
                           object_elements);
@@ -1747,22 +1745,35 @@
     int position,
     HIfContinuation* continuation) {
   IfBuilder if_nil(this, position);
-  bool needs_or = false;
+  bool some_case_handled = false;
+  bool some_case_missing = false;
+
   if (type->Maybe(Type::Null())) {
-    if (needs_or) if_nil.Or();
+    if (some_case_handled) if_nil.Or();
     if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
-    needs_or = true;
+    some_case_handled = true;
+  } else {
+    some_case_missing = true;
   }
+
   if (type->Maybe(Type::Undefined())) {
-    if (needs_or) if_nil.Or();
+    if (some_case_handled) if_nil.Or();
     if_nil.If<HCompareObjectEqAndBranch>(value,
                                          graph()->GetConstantUndefined());
-    needs_or = true;
-  }
-  if (type->Maybe(Type::Undetectable())) {
-    if (needs_or) if_nil.Or();
-    if_nil.If<HIsUndetectableAndBranch>(value);
+    some_case_handled = true;
   } else {
+    some_case_missing = true;
+  }
+
+  if (type->Maybe(Type::Undetectable())) {
+    if (some_case_handled) if_nil.Or();
+    if_nil.If<HIsUndetectableAndBranch>(value);
+    some_case_handled = true;
+  } else {
+    some_case_missing = true;
+  }
+
+  if (some_case_missing) {
     if_nil.Then();
     if_nil.Else();
     if (type->NumClasses() == 1) {
@@ -1846,7 +1857,7 @@
     // map, because we can just load the map in that case.
     HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
     return builder()->AddInstruction(
-        builder()->BuildLoadNamedField(constructor_function_, access, NULL));
+        builder()->BuildLoadNamedField(constructor_function_, access));
   }
 
   HInstruction* native_context = builder()->BuildGetNativeContext();
@@ -1867,7 +1878,7 @@
   // Find the map near the constructor function
   HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
   return builder()->AddInstruction(
-      builder()->BuildLoadNamedField(constructor_function_, access, NULL));
+      builder()->BuildLoadNamedField(constructor_function_, access));
 }
 
 
@@ -4312,7 +4323,6 @@
   int data_size = 0;
   int pointer_size = 0;
   int max_properties = kMaxFastLiteralProperties;
-  HCheckMaps* type_check = NULL;
   if (IsFastLiteral(original_boilerplate_object,
                     kMaxFastLiteralDepth,
                     &max_properties,
@@ -4350,7 +4360,7 @@
     // De-opt if elements kind changed from boilerplate_elements_kind.
     Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
                                   isolate());
-    type_check = Add<HCheckMaps>(literal, map, top_info());
+    literal = Add<HCheckMaps>(literal, map, top_info());
   }
 
   // The array is expected in the bailout environment during computation
@@ -4371,7 +4381,7 @@
     HValue* value = Pop();
     if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral);
 
-    elements = AddLoadElements(literal, type_check);
+    elements = AddLoadElements(literal);
 
     HValue* key = Add<HConstant>(i);
 
@@ -4594,8 +4604,8 @@
   if (count == types->length()) {
     // Everything matched; can use monomorphic load.
     BuildCheckHeapObject(object);
-    HCheckMaps* type_check = Add<HCheckMaps>(object, types);
-    return BuildLoadNamedField(object, access, type_check);
+    HCheckMaps* checked_object = Add<HCheckMaps>(object, types);
+    return BuildLoadNamedField(checked_object, access);
   }
 
   if (count != 0) return NULL;
@@ -4616,14 +4626,14 @@
   if (!lookup.IsField()) return NULL;
 
   BuildCheckHeapObject(object);
-  HCheckMaps* type_check = Add<HCheckMaps>(object, types);
+  Add<HCheckMaps>(object, types);
 
   Handle<JSObject> holder(lookup.holder());
   Handle<Map> holder_map(holder->map());
-  BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder);
-  HValue* holder_value = Add<HConstant>(holder);
-  return BuildLoadNamedField(holder_value,
-      HObjectAccess::ForField(holder_map, &lookup, name), type_check);
+  HValue* checked_holder = BuildCheckPrototypeMaps(
+      Handle<JSObject>::cast(prototype), holder);
+  return BuildLoadNamedField(checked_holder,
+      HObjectAccess::ForField(holder_map, &lookup, name));
 }
 
 
@@ -4698,7 +4708,7 @@
       // TODO(verwaest): Merge logic with BuildLoadNamedMonomorphic.
       if (lookup.IsField()) {
         HObjectAccess access = HObjectAccess::ForField(map, &lookup, name);
-        HLoadNamedField* load = BuildLoadNamedField(object, access, compare);
+        HLoadNamedField* load = BuildLoadNamedField(compare, access);
         load->set_position(expr->position());
         AddInstruction(load);
         if (!ast_context()->IsEffect()) Push(load);
@@ -5371,32 +5381,29 @@
 
 
 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
-                                                    HObjectAccess access,
-                                                    HValue* typecheck) {
+                                                    HObjectAccess access) {
   if (FLAG_track_double_fields && access.representation().IsDouble()) {
     // load the heap number
     HLoadNamedField* heap_number = Add<HLoadNamedField>(
         object, access.WithRepresentation(Representation::Tagged()));
     heap_number->set_type(HType::HeapNumber());
     // load the double value from it
-    return New<HLoadNamedField>(heap_number,
-                                HObjectAccess::ForHeapNumberValue(),
-                                typecheck);
+    return New<HLoadNamedField>(
+        heap_number, HObjectAccess::ForHeapNumberValue());
   }
-  return New<HLoadNamedField>(object, access, typecheck);
+  return New<HLoadNamedField>(object, access);
 }
 
 
 HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
-                                                   HValue* typecheck) {
+                                                   HValue* checked_string) {
   if (FLAG_fold_constants && object->IsConstant()) {
     HConstant* constant = HConstant::cast(object);
     if (constant->HasStringValue()) {
       return New<HConstant>(constant->StringValue()->length());
     }
   }
-  return BuildLoadNamedField(
-      object, HObjectAccess::ForStringLength(), typecheck);
+  return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength());
 }
 
 
@@ -5435,18 +5442,18 @@
   // Handle access to various length properties
   if (name->Equals(isolate()->heap()->length_string())) {
     if (map->instance_type() == JS_ARRAY_TYPE) {
-      HCheckMaps* type_check = AddCheckMap(object, map);
-      return New<HLoadNamedField>(object,
-          HObjectAccess::ForArrayLength(map->elements_kind()), type_check);
+      HCheckMaps* checked_object = AddCheckMap(object, map);
+      return New<HLoadNamedField>(
+          checked_object, HObjectAccess::ForArrayLength(map->elements_kind()));
     }
   }
 
   LookupResult lookup(isolate());
   map->LookupDescriptor(NULL, *name, &lookup);
   if (lookup.IsField()) {
-    HCheckMaps* type_check = AddCheckMap(object, map);
-    return BuildLoadNamedField(object,
-        HObjectAccess::ForField(map, &lookup, name), type_check);
+    HCheckMaps* checked_object = AddCheckMap(object, map);
+    return BuildLoadNamedField(
+        checked_object, HObjectAccess::ForField(map, &lookup, name));
   }
 
   // Handle a load of a constant known function.
@@ -5462,11 +5469,10 @@
     Handle<JSObject> prototype(JSObject::cast(map->prototype()));
     Handle<JSObject> holder(lookup.holder());
     Handle<Map> holder_map(holder->map());
-    HCheckMaps* type_check = AddCheckMap(object, map);
-    BuildCheckPrototypeMaps(prototype, holder);
-    HValue* holder_value = Add<HConstant>(holder);
-    return BuildLoadNamedField(holder_value,
-        HObjectAccess::ForField(holder_map, &lookup, name), type_check);
+    AddCheckMap(object, map);
+    HValue* checked_holder = BuildCheckPrototypeMaps(prototype, holder);
+    return BuildLoadNamedField(
+        checked_holder, HObjectAccess::ForField(holder_map, &lookup, name));
   }
 
   // Handle a load of a constant function somewhere in the prototype chain.
@@ -5536,6 +5542,7 @@
   bool has_smi_or_object_maps = false;
   bool has_js_array_access = false;
   bool has_non_js_array_access = false;
+  bool has_seen_holey_elements = false;
   Handle<Map> most_general_consolidated_map;
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
@@ -5558,6 +5565,10 @@
     } else {
       return NULL;
     }
+    // Remember if we've ever seen holey elements.
+    if (IsHoleyElementsKind(map->elements_kind())) {
+      has_seen_holey_elements = true;
+    }
     // Remember the most general elements kind, the code for its load will
     // properly handle all of the more specific cases.
     if ((i == 0) || IsMoreGeneralElementsKindTransition(
@@ -5569,10 +5580,15 @@
   if (!has_double_maps && !has_smi_or_object_maps) return NULL;
 
   HCheckMaps* check_maps = Add<HCheckMaps>(object, maps);
+  // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS.
+  // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS.
+  ElementsKind consolidated_elements_kind = has_seen_holey_elements
+      ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind())
+      : most_general_consolidated_map->elements_kind();
   HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
       object, key, val, check_maps,
       most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
-      most_general_consolidated_map->elements_kind(),
+      consolidated_elements_kind,
       false, NEVER_RETURN_HOLE, STANDARD_STORE);
   return instr;
 }
@@ -5659,11 +5675,11 @@
     return is_store ? NULL : instr;
   }
 
-  HInstruction* checkspec =
+  HInstruction* checked_object =
       AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
   HBasicBlock* join = graph()->CreateBasicBlock();
 
-  HInstruction* elements = AddLoadElements(object, checkspec);
+  HInstruction* elements = AddLoadElements(checked_object);
 
   for (int i = 0; i < untransitionable_maps.length(); ++i) {
     Handle<Map> map = untransitionable_maps[i];
@@ -5685,7 +5701,7 @@
       }
       if (map->instance_type() == JS_ARRAY_TYPE) {
         HInstruction* length = Add<HLoadNamedField>(
-            object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
+            mapcompare, HObjectAccess::ForArrayLength(elements_kind));
         checked_key = Add<HBoundsCheck>(key, length);
       } else {
         HInstruction* length = AddLoadFixedArrayLength(elements);
@@ -5961,30 +5977,34 @@
 }
 
 
-void HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
-                                          CompilationInfo* info) {
+HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
+                                                   CompilationInfo* info) {
   HConstant* constant_value = New<HConstant>(constant);
 
   if (constant->map()->CanOmitMapChecks()) {
     constant->map()->AddDependentCompilationInfo(
         DependentCode::kPrototypeCheckGroup, info);
-    return;
+    return constant_value;
   }
 
   AddInstruction(constant_value);
   HCheckMaps* check =
       Add<HCheckMaps>(constant_value, handle(constant->map()), info);
   check->ClearGVNFlag(kDependsOnElementsKind);
+  return check;
 }
 
 
-void HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
-                                            Handle<JSObject> holder) {
-  BuildConstantMapCheck(prototype, top_info());
+HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
+                                                     Handle<JSObject> holder) {
   while (!prototype.is_identical_to(holder)) {
-    prototype = handle(JSObject::cast(prototype->GetPrototype()));
     BuildConstantMapCheck(prototype, top_info());
+    prototype = handle(JSObject::cast(prototype->GetPrototype()));
   }
+
+  HInstruction* checked_object = BuildConstantMapCheck(prototype, top_info());
+  if (!checked_object->IsLinked()) AddInstruction(checked_object);
+  return checked_object;
 }
 
 
@@ -8202,21 +8222,23 @@
   ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
   CHECK_ALIVE(VisitForValue(sub_expr));
   HValue* value = Pop();
-  HIfContinuation continuation;
   if (expr->op() == Token::EQ_STRICT) {
-    IfBuilder if_nil(this);
-    if_nil.If<HCompareObjectEqAndBranch>(
-        value, (nil == kNullValue) ? graph()->GetConstantNull()
-                                   : graph()->GetConstantUndefined());
-    if_nil.Then();
-    if_nil.Else();
-    if_nil.CaptureContinuation(&continuation);
+    HConstant* nil_constant = nil == kNullValue
+        ? graph()->GetConstantNull()
+        : graph()->GetConstantUndefined();
+    HCompareObjectEqAndBranch* instr =
+        New<HCompareObjectEqAndBranch>(value, nil_constant);
+    instr->set_position(expr->position());
+    return ast_context()->ReturnControl(instr, expr->id());
+  } else {
+    ASSERT_EQ(Token::EQ, expr->op());
+    Handle<Type> type = expr->combined_type()->Is(Type::None())
+        ? handle(Type::Any(), isolate_)
+        : expr->combined_type();
+    HIfContinuation continuation;
+    BuildCompareNil(value, type, expr->position(), &continuation);
     return ast_context()->ReturnContinuation(&continuation, expr->id());
   }
-  Handle<Type> type = expr->combined_type()->Is(Type::None())
-      ? handle(Type::Any(), isolate_) : expr->combined_type();
-  BuildCompareNil(value, type, expr->position(), &continuation);
-  return ast_context()->ReturnContinuation(&continuation, expr->id());
 }
 
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index af31b60..326b7a4 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1257,13 +1257,10 @@
       LoadKeyedHoleMode load_mode,
       KeyedAccessStoreMode store_mode);
 
-  HLoadNamedField* BuildLoadNamedField(
-      HValue* object,
-      HObjectAccess access,
-      HValue* typecheck);
-  HInstruction* BuildLoadStringLength(HValue* object, HValue* typecheck);
-  HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>);
-  HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck);
+  HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access);
+  HInstruction* BuildLoadStringLength(HValue* object, HValue* checked_value);
+  HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map>);
+  HLoadNamedField* AddLoadElements(HValue* object);
   HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
 
   HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin);
@@ -1549,9 +1546,10 @@
                                        int previous_object_size,
                                        HValue* payload);
 
-  void BuildConstantMapCheck(Handle<JSObject> constant, CompilationInfo* info);
-  void BuildCheckPrototypeMaps(Handle<JSObject> prototype,
-                               Handle<JSObject> holder);
+  HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
+                                      CompilationInfo* info);
+  HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
+                                        Handle<JSObject> holder);
 
   HInstruction* BuildGetNativeContext();
   HInstruction* BuildGetArrayFunction();
@@ -1605,22 +1603,6 @@
 
 
 template<>
-inline HInstruction* HGraphBuilder::NewUncasted<HLoadNamedField>(
-    HValue* object, HObjectAccess access) {
-  return NewUncasted<HLoadNamedField>(object, access,
-                                      static_cast<HValue*>(NULL));
-}
-
-
-template<>
-inline HInstruction* HGraphBuilder::AddUncasted<HLoadNamedField>(
-    HValue* object, HObjectAccess access) {
-  return AddUncasted<HLoadNamedField>(object, access,
-                                      static_cast<HValue*>(NULL));
-}
-
-
-template<>
 inline HInstruction* HGraphBuilder::AddUncasted<HSimulate>(BailoutId id) {
   return AddUncasted<HSimulate>(id, FIXED_SIMULATE);
 }
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 37218e5..ab4e0a4 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -1310,14 +1310,6 @@
 }
 
 
-void Assembler::rdtsc() {
-  ASSERT(IsEnabled(RDTSC));
-  EnsureSpace ensure_space(this);
-  EMIT(0x0F);
-  EMIT(0x31);
-}
-
-
 void Assembler::ret(int imm16) {
   EnsureSpace ensure_space(this);
   ASSERT(is_uint16(imm16));
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index c102937..d6b6dab 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -537,7 +537,6 @@
     if (f == SSE3 && !FLAG_enable_sse3) return false;
     if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
     if (f == CMOV && !FLAG_enable_cmov) return false;
-    if (f == RDTSC && !FLAG_enable_rdtsc) return false;
     return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
   }
 
@@ -870,7 +869,6 @@
   void hlt();
   void int3();
   void nop();
-  void rdtsc();
   void ret(int imm16);
 
   // Label operations & relative jumps (PPUM Appendix D)
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index c43f11c..892b66e 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -862,7 +862,6 @@
   switch (f0byte) {
     case 0x18: return "prefetch";
     case 0xA2: return "cpuid";
-    case 0x31: return "rdtsc";
     case 0xBE: return "movsx_b";
     case 0xBF: return "movsx_w";
     case 0xB6: return "movzx_b";
diff --git a/src/ic.cc b/src/ic.cc
index 7634ce9..cc7fee5 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -379,7 +379,7 @@
   Code* target = GetTargetAtAddress(address);
 
   // Don't clear debug break inline cache as it will remove the break point.
-  if (target->is_debug_break()) return;
+  if (target->is_debug_stub()) return;
 
   switch (target->kind()) {
     case Code::LOAD_IC: return LoadIC::Clear(address, target);
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 406510a..b260c81 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -1691,7 +1691,7 @@
   Code* pre_top_frame_code = pre_top_frame->LookupCode();
   bool frame_has_padding;
   if (pre_top_frame_code->is_inline_cache_stub() &&
-      pre_top_frame_code->is_debug_break()) {
+      pre_top_frame_code->is_debug_stub()) {
     // OK, we can drop inline cache calls.
     *mode = Debug::FRAME_DROPPED_IN_IC_CALL;
     frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 0e84267..f065da1 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -2743,12 +2743,10 @@
                                          int size,
                                          AllocationSpace dest) {
   HEAP_PROFILE(heap(), ObjectMoveEvent(src, dst));
-  // TODO(hpayer): Replace that check with an assert.
+  // TODO(hpayer): Replace these checks with asserts.
+  CHECK(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest));
   CHECK(dest != LO_SPACE && size <= Page::kMaxNonCodeHeapObjectSize);
   if (dest == OLD_POINTER_SPACE) {
-    // TODO(hpayer): Replace this check with an assert.
-    HeapObject* heap_object = HeapObject::FromAddress(src);
-    CHECK(heap_->TargetSpace(heap_object) == heap_->old_pointer_space());
     Address src_slot = src;
     Address dst_slot = dst;
     ASSERT(IsAligned(size, kPointerSize));
@@ -2794,13 +2792,6 @@
     Code::cast(HeapObject::FromAddress(dst))->Relocate(dst - src);
   } else {
     ASSERT(dest == OLD_DATA_SPACE || dest == NEW_SPACE);
-    // Objects in old data space can just be moved by compaction to a different
-    // page in old data space.
-    // TODO(hpayer): Replace the following check with an assert.
-    CHECK(!heap_->old_data_space()->Contains(src) ||
-          (heap_->old_data_space()->Contains(dst) &&
-          heap_->TargetSpace(HeapObject::FromAddress(src)) ==
-          heap_->old_data_space()));
     heap()->MoveBlock(dst, src, size);
   }
   Memory::Address_at(src) = dst;
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 6c1ecbb..4c74b10 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4084,8 +4084,8 @@
 }
 
 
-bool Code::is_debug_break() {
-  return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
+bool Code::is_debug_stub() {
+  return ic_state() == DEBUG_STUB;
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index 96b4011..ffd8584 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4911,7 +4911,7 @@
 
   // Testers for IC stub kinds.
   inline bool is_inline_cache_stub();
-  inline bool is_debug_break();
+  inline bool is_debug_stub();
   inline bool is_load_stub() { return kind() == LOAD_IC; }
   inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
   inline bool is_store_stub() { return kind() == STORE_IC; }
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index 13b819b..f7ab8a1 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -83,7 +83,7 @@
   // Mac OS X requires all these to install so we can assume they are present.
   // These constants are defined by the CPUid instructions.
   const uint64_t one = 1;
-  return (one << SSE2) | (one << CMOV) | (one << RDTSC) | (one << CPUID);
+  return (one << SSE2) | (one << CMOV) | (one << CPUID);
 #else
   return 0;  // Nothing special about the other systems.
 #endif
diff --git a/src/runtime.cc b/src/runtime.cc
index 057e268..6311f4b 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -14153,6 +14153,14 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 0);
+  isolate->heap()->NotifyContextDisposed();
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
diff --git a/src/runtime.h b/src/runtime.h
index 3d2f1c0..a4924ec 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -111,6 +111,7 @@
   F(DebugPrepareStepInIfStepping, 1, 1) \
   F(FlattenString, 1, 1) \
   F(MigrateInstance, 1, 1) \
+  F(NotifyContextDisposed, 0, 1) \
   \
   /* Array join support */ \
   F(PushIfAbsent, 2, 1) \
diff --git a/src/spaces.cc b/src/spaces.cc
index 5935c4a..8a5aa03 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -2852,8 +2852,7 @@
 // the VerifyObject definition behind VERIFY_HEAP.
 
 void MapSpace::VerifyObject(HeapObject* object) {
-  // The object should be a map or a free-list node.
-  CHECK(object->IsMap() || object->IsFreeSpace());
+  CHECK(object->IsMap());
 }
 
 
@@ -2864,16 +2863,12 @@
 // the VerifyObject definition behind VERIFY_HEAP.
 
 void CellSpace::VerifyObject(HeapObject* object) {
-  // The object should be a global object property cell or a free-list node.
-  CHECK(object->IsCell() ||
-         object->map() == heap()->two_pointer_filler_map());
+  CHECK(object->IsCell());
 }
 
 
 void PropertyCellSpace::VerifyObject(HeapObject* object) {
-  // The object should be a global object property cell or a free-list node.
-  CHECK(object->IsPropertyCell() ||
-         object->map() == heap()->two_pointer_filler_map());
+  CHECK(object->IsPropertyCell());
 }
 
 
diff --git a/src/v8globals.h b/src/v8globals.h
index 6ec7547..00693fa 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -438,7 +438,6 @@
                   SSE3 = 32 + 0,     // x86
                   SSE2 = 26,   // x86
                   CMOV = 15,   // x86
-                  RDTSC = 4,   // x86
                   CPUID = 10,  // x86
                   VFP3 = 1,    // ARM
                   ARMv7 = 2,   // ARM
diff --git a/src/version.cc b/src/version.cc
index 5a6a939..0929191 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     21
-#define BUILD_NUMBER      1
+#define BUILD_NUMBER      2
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 8969d89..68d2c05 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -1919,13 +1919,6 @@
 }
 
 
-void Assembler::rdtsc() {
-  EnsureSpace ensure_space(this);
-  emit(0x0F);
-  emit(0x31);
-}
-
-
 void Assembler::ret(int imm16) {
   EnsureSpace ensure_space(this);
   ASSERT(is_uint16(imm16));
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 4e36b6e..d92849a 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -475,7 +475,6 @@
     if (f == SSE3 && !FLAG_enable_sse3) return false;
     if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
     if (f == CMOV && !FLAG_enable_cmov) return false;
-    if (f == RDTSC && !FLAG_enable_rdtsc) return false;
     if (f == SAHF && !FLAG_enable_sahf) return false;
     return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
   }
@@ -1176,7 +1175,6 @@
   void hlt();
   void int3();
   void nop();
-  void rdtsc();
   void ret(int imm16);
   void setcc(Condition cc, Register reg);
 
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index eefa703..e9ace15 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -1229,8 +1229,8 @@
     current += PrintRightXMMOperand(current);
     AppendToBuffer(", %s", NameOfXMMRegister(regop));
 
-  } else if (opcode == 0xA2 || opcode == 0x31) {
-    // RDTSC or CPUID
+  } else if (opcode == 0xA2) {
+    // CPUID
     AppendToBuffer("%s", mnemonic);
 
   } else if ((opcode & 0xF0) == 0x40) {
@@ -1294,8 +1294,6 @@
       return "nop";
     case 0x2A:  // F2/F3 prefix.
       return "cvtsi2s";
-    case 0x31:
-      return "rdtsc";
     case 0x51:  // F2 prefix.
       return "sqrtsd";
     case 0x58:  // F2 prefix.
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index 14447b2..90469e5 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -104,11 +104,6 @@
     CpuFeatureScope fscope(&assm, CPUID);
     __ cpuid();
   }
-  {
-    CHECK(CpuFeatures::IsSupported(RDTSC));
-    CpuFeatureScope fscope(&assm, RDTSC);
-    __ rdtsc();
-  }
   __ movsx_b(edx, ecx);
   __ movsx_w(edx, ecx);
   __ movzx_b(edx, ecx);
diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc
index 1c7f416..1ff9fd3 100644
--- a/test/cctest/test-disasm-x64.cc
+++ b/test/cctest/test-disasm-x64.cc
@@ -95,11 +95,6 @@
     CpuFeatures::Scope fscope(CPUID);
     __ cpuid();
   }
-  {
-    CHECK(CpuFeatures::IsSupported(RDTSC));
-    CpuFeatures::Scope fscope(RDTSC);
-    __ rdtsc();
-  }
   __ movsxbq(rdx, Operand(rcx, 0));
   __ movsxwq(rdx, Operand(rcx, 0));
   __ movzxbl(rdx, Operand(rcx, 0));
diff --git a/test/mjsunit/regress/consolidated-holey-load.js b/test/mjsunit/regress/consolidated-holey-load.js
new file mode 100644
index 0000000..ef8f1ef
--- /dev/null
+++ b/test/mjsunit/regress/consolidated-holey-load.js
@@ -0,0 +1,40 @@
+// Copyright 2013 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: --allow-natives-syntax
+
+function foo(array) {
+  return array[0];
+}
+
+var a = [1, 2, , 4];  // Holey Smi elements.
+var b = ["abcd", 0];  // Fast elements.
+foo(b);  // Observe fast elements first, or the IC will transition without
+foo(a);  // going polymorphic.
+%OptimizeFunctionOnNextCall(foo);
+var c = [, 0];
+assertEquals(undefined, foo(c));  // Elided hole check will leak the hole.
diff --git a/test/mjsunit/regress/debug-prepare-step-in.js b/test/mjsunit/regress/debug-prepare-step-in.js
new file mode 100644
index 0000000..b8c2116
--- /dev/null
+++ b/test/mjsunit/regress/debug-prepare-step-in.js
@@ -0,0 +1,54 @@
+// Copyright 2013 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-debug-as debug --allow-natives-syntax --expose-gc
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+function breakListener(event, exec_state, event_data, data) {
+  exec_state.prepareStep(Debug.StepAction.StepIn, 1);
+}
+
+Debug.setListener(breakListener);
+
+var o = {x:function() { return 10; }};
+
+function f(o) {
+  var m = "x";
+  o[m]();
+}
+
+Debug.setBreakPoint(f, 2, 0);
+
+f(o);
+
+%NotifyContextDisposed();
+function g() {
+  gc();
+}
+
+g();
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index a7e89db..eccd7d2 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -689,10 +689,6 @@
                 }],
               ],
             },
-            'defines': [
-              'V8_OS_LINUX=1',
-              'V8_OS_POSIX=1'
-            ],
             'sources': [  ### gcmole(os:linux) ###
               '../../src/platform-linux.cc',
               '../../src/platform-posix.cc'
@@ -710,29 +706,16 @@
               ['host_os=="mac"', {
                 'target_conditions': [
                   ['_toolset=="host"', {
-                    'defines': [
-                      'V8_OS_BSD=1',
-                      'V8_OS_MACOSX=1',
-                      'V8_OS_POSIX=1'
-                    ],
                     'sources': [
                       '../../src/platform-macos.cc'
                     ]
                   }, {
-                    'defines': [
-                      'V8_OS_LINUX=1',
-                      'V8_OS_POSIX=1'
-                    ],
                     'sources': [
                       '../../src/platform-linux.cc'
                     ]
                   }],
                 ],
               }, {
-                'defines': [
-                  'V8_OS_LINUX=1',
-                  'V8_OS_POSIX=1'
-                ],
                 'sources': [
                   '../../src/platform-linux.cc'
                 ]
@@ -741,11 +724,6 @@
           },
         ],
         ['OS=="freebsd"', {
-            'defines': [
-              'V8_OS_BSD=1',
-              'V8_OS_FREEBSD=1',
-              'V8_OS_POSIX=1'
-            ],
             'link_settings': {
               'libraries': [
                 '-L/usr/local/lib -lexecinfo',
@@ -757,11 +735,6 @@
           }
         ],
         ['OS=="openbsd"', {
-            'defines': [
-              'V8_OS_BSD=1',
-              'V8_OS_OPENBSD=1',
-              'V8_OS_POSIX=1'
-            ],
             'link_settings': {
               'libraries': [
                 '-L/usr/local/lib -lexecinfo',
@@ -773,11 +746,6 @@
           }
         ],
         ['OS=="netbsd"', {
-            'defines': [
-              'V8_OS_BSD=1',
-              'V8_OS_NETBSD=1',
-              'V8_OS_POSIX=1'
-            ],
             'link_settings': {
               'libraries': [
                 '-L/usr/pkg/lib -Wl,-R/usr/pkg/lib -lexecinfo',
@@ -789,10 +757,6 @@
           }
         ],
         ['OS=="solaris"', {
-            'defines': [
-              'V8_OS_POSIX=1',
-              'V8_OS_SOLARIS=1'
-            ],
             'link_settings': {
               'libraries': [
                 '-lsocket -lnsl',
@@ -804,11 +768,6 @@
           }
         ],
         ['OS=="mac"', {
-          'defines': [
-            'V8_OS_BSD=1',
-            'V8_OS_MACOSX=1',
-            'V8_OS_POSIX=1'
-          ],
           'sources': [
             '../../src/platform-macos.cc',
             '../../src/platform-posix.cc'
@@ -825,18 +784,11 @@
               },
               'conditions': [
                 ['build_env=="Cygwin"', {
-                  'defines': [
-                    'V8_OS_CYGWIN=1',
-                    'V8_OS_POSIX=1'
-                  ],
                   'sources': [
                     '../../src/platform-cygwin.cc',
                     '../../src/platform-posix.cc',
                   ],
                 }, {
-                  'defines': [
-                    'V8_OS_WIN=1'
-                  ],
                   'sources': [
                     '../../src/platform-win32.cc',
                     '../../src/win32-math.h',
@@ -848,9 +800,6 @@
                 'libraries': [ '-lwinmm', '-lws2_32' ],
               },
             }, {
-              'defines': [
-                'V8_OS_WIN=1'
-              ],
               'sources': [
                 '../../src/platform-win32.cc',
                 '../../src/win32-math.h',