Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / v8 / src / objects-debug.cc
index 9d54141..4834ef2 100644 (file)
@@ -1,53 +1,26 @@
 // 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.
-
-#include "v8.h"
-
-#include "disassembler.h"
-#include "disasm.h"
-#include "jsregexp.h"
-#include "macro-assembler.h"
-#include "objects-visiting.h"
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/disasm.h"
+#include "src/disassembler.h"
+#include "src/heap/objects-visiting.h"
+#include "src/jsregexp.h"
+#include "src/macro-assembler.h"
+#include "src/ostreams.h"
 
 namespace v8 {
 namespace internal {
 
 #ifdef VERIFY_HEAP
 
-void MaybeObject::Verify() {
-  Object* this_as_object;
-  if (ToObject(&this_as_object)) {
-    if (this_as_object->IsSmi()) {
-      Smi::cast(this_as_object)->SmiVerify();
-    } else {
-      HeapObject::cast(this_as_object)->HeapObjectVerify();
-    }
+void Object::ObjectVerify() {
+  if (IsSmi()) {
+    Smi::cast(this)->SmiVerify();
   } else {
-    Failure::cast(this)->FailureVerify();
+    HeapObject::cast(this)->HeapObjectVerify();
   }
 }
 
@@ -66,11 +39,6 @@ void Smi::SmiVerify() {
 }
 
 
-void Failure::FailureVerify() {
-  CHECK(IsFailure());
-}
-
-
 void HeapObject::HeapObjectVerify() {
   InstanceType instance_type = map()->instance_type();
 
@@ -87,14 +55,9 @@ void HeapObject::HeapObjectVerify() {
       Map::cast(this)->MapVerify();
       break;
     case HEAP_NUMBER_TYPE:
+    case MUTABLE_HEAP_NUMBER_TYPE:
       HeapNumber::cast(this)->HeapNumberVerify();
       break;
-    case FLOAT32x4_TYPE:
-      Float32x4::cast(this)->Float32x4Verify();
-      break;
-    case INT32x4_TYPE:
-      Int32x4::cast(this)->Int32x4Verify();
-      break;
     case FIXED_ARRAY_TYPE:
       FixedArray::cast(this)->FixedArrayVerify();
       break;
@@ -171,6 +134,12 @@ void HeapObject::HeapObjectVerify() {
     case JS_MAP_TYPE:
       JSMap::cast(this)->JSMapVerify();
       break;
+    case JS_SET_ITERATOR_TYPE:
+      JSSetIterator::cast(this)->JSSetIteratorVerify();
+      break;
+    case JS_MAP_ITERATOR_TYPE:
+      JSMapIterator::cast(this)->JSMapIteratorVerify();
+      break;
     case JS_WEAK_MAP_TYPE:
       JSWeakMap::cast(this)->JSWeakMapVerify();
       break;
@@ -238,17 +207,7 @@ void Symbol::SymbolVerify() {
 
 
 void HeapNumber::HeapNumberVerify() {
-  CHECK(IsHeapNumber());
-}
-
-
-void Float32x4::Float32x4Verify() {
-  CHECK(IsFloat32x4());
-}
-
-
-void Int32x4::Int32x4Verify() {
-  CHECK(IsInt32x4());
+  CHECK(IsHeapNumber() || IsMutableHeapNumber());
 }
 
 
@@ -304,12 +263,18 @@ void JSObject::JSObjectVerify() {
     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
       if (descriptors->GetDetails(i).type() == FIELD) {
         Representation r = descriptors->GetDetails(i).representation();
-        int field = descriptors->GetFieldIndex(i);
-        Object* value = RawFastPropertyAt(field);
-        if (r.IsDouble()) ASSERT(value->IsHeapNumber());
+        FieldIndex index = FieldIndex::ForDescriptor(map(), i);
+        Object* value = RawFastPropertyAt(index);
+        if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
         if (value->IsUninitialized()) continue;
-        if (r.IsSmi()) ASSERT(value->IsSmi());
-        if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
+        if (r.IsSmi()) DCHECK(value->IsSmi());
+        if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
+        HeapType* field_type = descriptors->GetFieldType(i);
+        if (r.IsNone()) {
+          CHECK(field_type->Is(HeapType::None()));
+        } else if (!HeapType::Any()->Is(field_type)) {
+          CHECK(!field_type->NowStable() || field_type->NowContains(value));
+        }
       }
     }
   }
@@ -335,17 +300,17 @@ void Map::MapVerify() {
           instance_size() < heap->Capacity()));
   VerifyHeapPointer(prototype());
   VerifyHeapPointer(instance_descriptors());
-  SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates());
+  SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
   if (HasTransitionArray()) {
-    SLOW_ASSERT(transitions()->IsSortedNoDuplicates());
-    SLOW_ASSERT(transitions()->IsConsistentWithBackPointers(this));
+    SLOW_DCHECK(transitions()->IsSortedNoDuplicates());
+    SLOW_DCHECK(transitions()->IsConsistentWithBackPointers(this));
   }
 }
 
 
-void Map::SharedMapVerify() {
+void Map::DictionaryMapVerify() {
   MapVerify();
-  CHECK(is_shared());
+  CHECK(is_dictionary_map());
   CHECK(instance_descriptors()->IsEmpty());
   CHECK_EQ(0, pre_allocated_property_fields());
   CHECK_EQ(0, unused_property_fields());
@@ -384,7 +349,7 @@ void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
   VerifyObjectField(kStorage1Offset);
   VerifyObjectField(kStorage2Offset);
-  VerifyHeapPointer(feedback_vector());
+  VerifyObjectField(kStorage3Offset);
 }
 
 
@@ -396,11 +361,7 @@ void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
 void FixedArray::FixedArrayVerify() {
   for (int i = 0; i < length(); i++) {
     Object* e = get(i);
-    if (e->IsHeapObject()) {
-      VerifyHeapPointer(e);
-    } else {
-      e->Verify();
-    }
+    VerifyPointer(e);
   }
 }
 
@@ -420,12 +381,14 @@ void FixedDoubleArray::FixedDoubleArrayVerify() {
 
 void ConstantPoolArray::ConstantPoolArrayVerify() {
   CHECK(IsConstantPoolArray());
-  for (int i = 0; i < count_of_code_ptr_entries(); i++) {
-    Address code_entry = get_code_ptr_entry(first_code_ptr_index() + i);
+  ConstantPoolArray::Iterator code_iter(this, ConstantPoolArray::CODE_PTR);
+  while (!code_iter.is_finished()) {
+    Address code_entry = get_code_ptr_entry(code_iter.next_index());
     VerifyPointer(Code::GetCodeFromTargetAddress(code_entry));
   }
-  for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
-    VerifyObjectField(OffsetOfElementAt(first_heap_ptr_index() + i));
+  ConstantPoolArray::Iterator heap_iter(this, ConstantPoolArray::HEAP_PTR);
+  while (!heap_iter.is_finished()) {
+    VerifyObjectField(OffsetOfElementAt(heap_iter.next_index()));
   }
 }
 
@@ -537,6 +500,7 @@ void ConsString::ConsStringVerify() {
   CHECK(this->second() == GetHeap()->empty_string() ||
         this->second()->IsString());
   CHECK(this->length() >= ConsString::kMinLength);
+  CHECK(this->length() == this->first()->length() + this->second()->length());
   if (this->IsFlat()) {
     // A flat cons can only be created by String::SlowTryFlatten.
     // Afterwards, the first part may be externalized.
@@ -568,6 +532,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
   VerifyObjectField(kNameOffset);
   VerifyObjectField(kCodeOffset);
   VerifyObjectField(kOptimizedCodeMapOffset);
+  VerifyObjectField(kFeedbackVectorOffset);
   VerifyObjectField(kScopeInfoOffset);
   VerifyObjectField(kInstanceClassNameOffset);
   VerifyObjectField(kFunctionDataOffset);
@@ -582,7 +547,7 @@ void JSGlobalProxy::JSGlobalProxyVerify() {
   VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
   // Make sure that this object has no properties, elements.
   CHECK_EQ(0, properties()->length());
-  CHECK(HasFastObjectElements());
+  CHECK(HasFastSmiElements());
   CHECK_EQ(0, FixedArray::cast(elements())->length());
 }
 
@@ -611,18 +576,41 @@ void JSBuiltinsObject::JSBuiltinsObjectVerify() {
 
 void Oddball::OddballVerify() {
   CHECK(IsOddball());
+  Heap* heap = GetHeap();
   VerifyHeapPointer(to_string());
   Object* number = to_number();
   if (number->IsHeapObject()) {
-    CHECK(number == HeapObject::cast(number)->GetHeap()->nan_value());
+    CHECK(number == heap->nan_value());
   } else {
     CHECK(number->IsSmi());
     int value = Smi::cast(number)->value();
     // Hidden oddballs have negative smis.
-    const int kLeastHiddenOddballNumber = -4;
+    const int kLeastHiddenOddballNumber = -5;
     CHECK_LE(value, 1);
     CHECK(value >= kLeastHiddenOddballNumber);
   }
+  if (map() == heap->undefined_map()) {
+    CHECK(this == heap->undefined_value());
+  } else if (map() == heap->the_hole_map()) {
+    CHECK(this == heap->the_hole_value());
+  } else if (map() == heap->null_map()) {
+    CHECK(this == heap->null_value());
+  } else if (map() == heap->boolean_map()) {
+    CHECK(this == heap->true_value() ||
+          this == heap->false_value());
+  } else if (map() == heap->uninitialized_map()) {
+    CHECK(this == heap->uninitialized_value());
+  } else if (map() == heap->no_interceptor_result_sentinel_map()) {
+    CHECK(this == heap->no_interceptor_result_sentinel());
+  } else if (map() == heap->arguments_marker_map()) {
+    CHECK(this == heap->arguments_marker());
+  } else if (map() == heap->termination_exception_map()) {
+    CHECK(this == heap->termination_exception());
+  } else if (map() == heap->exception_map()) {
+    CHECK(this == heap->exception());
+  } else {
+    UNREACHABLE();
+  }
 }
 
 
@@ -642,33 +630,42 @@ void PropertyCell::PropertyCellVerify() {
 void Code::CodeVerify() {
   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
                   kCodeAlignment));
-  relocation_info()->Verify();
+  relocation_info()->ObjectVerify();
   Address last_gc_pc = NULL;
+  Isolate* isolate = GetIsolate();
   for (RelocIterator it(this); !it.done(); it.next()) {
-    it.rinfo()->Verify();
+    it.rinfo()->Verify(isolate);
     // Ensure that GC will not iterate twice over the same pointer.
     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
       CHECK(it.rinfo()->pc() != last_gc_pc);
       last_gc_pc = it.rinfo()->pc();
     }
   }
+  CHECK(raw_type_feedback_info() == Smi::FromInt(0) ||
+        raw_type_feedback_info()->IsSmi() == IsCodeStubOrIC());
 }
 
 
 void Code::VerifyEmbeddedObjectsDependency() {
+  if (!CanContainWeakObjects()) return;
+  DisallowHeapAllocation no_gc;
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
     Object* obj = it.rinfo()->target_object();
     if (IsWeakObject(obj)) {
       if (obj->IsMap()) {
         Map* map = Map::cast(obj);
-        CHECK(map->dependent_code()->Contains(
-            DependentCode::kWeaklyEmbeddedGroup, this));
+        DependentCode::DependencyGroup group = is_optimized_code() ?
+            DependentCode::kWeakCodeGroup : DependentCode::kWeakICGroup;
+        CHECK(map->dependent_code()->Contains(group, this));
       } else if (obj->IsJSObject()) {
         Object* raw_table = GetIsolate()->heap()->weak_object_to_code_table();
         WeakHashTable* table = WeakHashTable::cast(raw_table);
-        CHECK(DependentCode::cast(table->Lookup(obj))->Contains(
-            DependentCode::kWeaklyEmbeddedGroup, this));
+        Handle<Object> key_obj(obj, isolate);
+        CHECK(DependentCode::cast(table->Lookup(key_obj))->Contains(
+            DependentCode::kWeakCodeGroup, this));
       }
     }
   }
@@ -692,7 +689,8 @@ void JSSet::JSSetVerify() {
   CHECK(IsJSSet());
   JSObjectVerify();
   VerifyHeapPointer(table());
-  CHECK(table()->IsHashTable() || table()->IsUndefined());
+  CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+  // TODO(arv): Verify OrderedHashTable too.
 }
 
 
@@ -700,7 +698,28 @@ void JSMap::JSMapVerify() {
   CHECK(IsJSMap());
   JSObjectVerify();
   VerifyHeapPointer(table());
-  CHECK(table()->IsHashTable() || table()->IsUndefined());
+  CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+  // TODO(arv): Verify OrderedHashTable too.
+}
+
+
+void JSSetIterator::JSSetIteratorVerify() {
+  CHECK(IsJSSetIterator());
+  JSObjectVerify();
+  VerifyHeapPointer(table());
+  CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+  CHECK(index()->IsSmi() || index()->IsUndefined());
+  CHECK(kind()->IsSmi() || kind()->IsUndefined());
+}
+
+
+void JSMapIterator::JSMapIteratorVerify() {
+  CHECK(IsJSMapIterator());
+  JSObjectVerify();
+  VerifyHeapPointer(table());
+  CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+  CHECK(index()->IsSmi() || index()->IsUndefined());
+  CHECK(kind()->IsSmi() || kind()->IsUndefined());
 }
 
 
@@ -827,7 +846,7 @@ void Foreign::ForeignVerify() {
 
 void Box::BoxVerify() {
   CHECK(IsBox());
-  value()->Verify();
+  value()->ObjectVerify();
 }
 
 
@@ -864,7 +883,6 @@ void AccessorPair::AccessorPairVerify() {
   CHECK(IsAccessorPair());
   VerifyPointer(getter());
   VerifyPointer(setter());
-  VerifySmiField(kAccessFlagsOffset);
 }
 
 
@@ -963,7 +981,7 @@ void Script::ScriptVerify() {
 
 
 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
-  JSFunction::cast(get(kFactoryIndex))->Verify();
+  JSFunction::cast(get(kFactoryIndex))->ObjectVerify();
 
   int size = Smi::cast(get(kCacheSizeIndex))->value();
   CHECK(kEntriesIndex <= size);
@@ -978,23 +996,23 @@ void JSFunctionResultCache::JSFunctionResultCacheVerify() {
   if (FLAG_enable_slow_asserts) {
     for (int i = kEntriesIndex; i < size; i++) {
       CHECK(!get(i)->IsTheHole());
-      get(i)->Verify();
+      get(i)->ObjectVerify();
     }
     for (int i = size; i < length(); i++) {
       CHECK(get(i)->IsTheHole());
-      get(i)->Verify();
+      get(i)->ObjectVerify();
     }
   }
 }
 
 
 void NormalizedMapCache::NormalizedMapCacheVerify() {
-  FixedArray::cast(this)->Verify();
+  FixedArray::cast(this)->FixedArrayVerify();
   if (FLAG_enable_slow_asserts) {
     for (int i = 0; i < length(); i++) {
-      Object* e = get(i);
+      Object* e = FixedArray::get(i);
       if (e->IsMap()) {
-        Map::cast(e)->SharedMapVerify();
+        Map::cast(e)->DictionaryMapVerify();
       } else {
         CHECK(e->IsUndefined());
       }
@@ -1003,7 +1021,6 @@ void NormalizedMapCache::NormalizedMapCacheVerify() {
 }
 
 
-#ifdef ENABLE_DEBUGGER_SUPPORT
 void DebugInfo::DebugInfoVerify() {
   CHECK(IsDebugInfo());
   VerifyPointer(shared());
@@ -1020,7 +1037,6 @@ void BreakPointInfo::BreakPointInfoVerify() {
   statement_position()->SmiVerify();
   VerifyPointer(break_point_objects());
 }
-#endif  // ENABLE_DEBUGGER_SUPPORT
 #endif  // VERIFY_HEAP
 
 #ifdef DEBUG
@@ -1128,13 +1144,15 @@ bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
   for (int i = 0; i < number_of_descriptors(); i++) {
     Name* key = GetSortedKey(i);
     if (key == current_key) {
-      PrintDescriptors();
+      OFStream os(stdout);
+      PrintDescriptors(os);
       return false;
     }
     current_key = key;
     uint32_t hash = GetSortedKey(i)->Hash();
     if (hash < current) {
-      PrintDescriptors();
+      OFStream os(stdout);
+      PrintDescriptors(os);
       return false;
     }
     current = hash;
@@ -1144,19 +1162,21 @@ bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
 
 
 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
-  ASSERT(valid_entries == -1);
+  DCHECK(valid_entries == -1);
   Name* current_key = NULL;
   uint32_t current = 0;
   for (int i = 0; i < number_of_transitions(); i++) {
     Name* key = GetSortedKey(i);
     if (key == current_key) {
-      PrintTransitions();
+      OFStream os(stdout);
+      PrintTransitions(os);
       return false;
     }
     current_key = key;
     uint32_t hash = GetSortedKey(i)->Hash();
     if (hash < current) {
-      PrintTransitions();
+      OFStream os(stdout);
+      PrintTransitions(os);
       return false;
     }
     current = hash;