Version 1.3.1.

Speed improvements to accessors and interceptors.

Added support for capturing stack information on custom errors.

Added support for morphing an object into a pixel array where its indexed properties are stored in an external byte array. Values written are always clamped to the 0..255 interval.

Profiler on x64 now handles C/C++ functions from shared libraries.

Changed the debugger to avoid stepping into function.call/apply if the function is a built-in.

Initial implementation of constructor heap profile for JS objects.

More fine grained control of profiling aspects through the API.

Optimized the called as constructor check for API calls.



git-svn-id: http://v8.googlecode.com/svn/trunk@2592 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 7abc7c3..c7f791c 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -321,6 +321,12 @@
 }
 
 
+bool Object::IsPixelArray() {
+  return Object::IsHeapObject() &&
+      HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
+}
+
+
 bool Object::IsFailure() {
   return HAS_FAILURE_TAG(this);
 }
@@ -1043,7 +1049,22 @@
 
 
 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
-ACCESSORS(JSObject, elements, FixedArray, kElementsOffset)
+
+
+Array* JSObject::elements() {
+  Object* array = READ_FIELD(this, kElementsOffset);
+  // In the assert below Dictionary is covered under FixedArray.
+  ASSERT(array->IsFixedArray() || array->IsPixelArray());
+  return reinterpret_cast<Array*>(array);
+}
+
+
+void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
+  // In the assert below Dictionary is covered under FixedArray.
+  ASSERT(value->IsFixedArray() || value->IsPixelArray());
+  WRITE_FIELD(this, kElementsOffset, value);
+  CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
+}
 
 
 void JSObject::initialize_properties() {
@@ -1502,6 +1523,7 @@
 CAST_ACCESSOR(JSRegExp)
 CAST_ACCESSOR(Proxy)
 CAST_ACCESSOR(ByteArray)
+CAST_ACCESSOR(PixelArray)
 CAST_ACCESSOR(Struct)
 
 
@@ -1860,6 +1882,32 @@
 }
 
 
+uint8_t* PixelArray::external_pointer() {
+  intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
+  return reinterpret_cast<uint8_t*>(ptr);
+}
+
+
+void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
+  intptr_t ptr = reinterpret_cast<intptr_t>(value);
+  WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
+}
+
+
+uint8_t PixelArray::get(int index) {
+  ASSERT((index >= 0) && (index < this->length()));
+  uint8_t* ptr = external_pointer();
+  return ptr[index];
+}
+
+
+void PixelArray::set(int index, uint8_t value) {
+  ASSERT((index >= 0) && (index < this->length()));
+  uint8_t* ptr = external_pointer();
+  ptr[index] = value;
+}
+
+
 int Map::instance_size() {
   return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
 }
@@ -2293,6 +2341,11 @@
 }
 
 
+bool JSFunction::IsBuiltin() {
+  return context()->global()->IsJSBuiltinsObject();
+}
+
+
 bool JSObject::IsLoaded() {
   return !map()->needs_loading();
 }
@@ -2523,8 +2576,33 @@
 }
 
 
+JSObject::ElementsKind JSObject::GetElementsKind() {
+  Array* array = elements();
+  if (array->IsFixedArray()) {
+    // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
+    if (array->map() == Heap::fixed_array_map()) {
+      return FAST_ELEMENTS;
+    }
+    ASSERT(array->IsDictionary());
+    return DICTIONARY_ELEMENTS;
+  }
+  ASSERT(array->IsPixelArray());
+  return PIXEL_ELEMENTS;
+}
+
+
 bool JSObject::HasFastElements() {
-  return !elements()->IsDictionary();
+  return GetElementsKind() == FAST_ELEMENTS;
+}
+
+
+bool JSObject::HasDictionaryElements() {
+  return GetElementsKind() == DICTIONARY_ELEMENTS;
+}
+
+
+bool JSObject::HasPixelElements() {
+  return GetElementsKind() == PIXEL_ELEMENTS;
 }
 
 
@@ -2545,7 +2623,7 @@
 
 
 NumberDictionary* JSObject::element_dictionary() {
-  ASSERT(!HasFastElements());
+  ASSERT(HasDictionaryElements());
   return NumberDictionary::cast(elements());
 }
 
@@ -2651,24 +2729,6 @@
 }
 
 
-Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
-  // TODO(antonm): Do we want to do any shortcuts for global object?
-  if (HasFastProperties()) {
-    LookupResult lookup;
-    LocalLookupRealNamedProperty(name, &lookup);
-    if (lookup.IsValid()) {
-      if (lookup.type() == FIELD && lookup.IsCacheable()) {
-        return Smi::FromInt(lookup.GetFieldIndex());
-      }
-    } else {
-      return Smi::FromInt(kLookupInPrototype);
-    }
-  }
-
-  return Smi::FromInt(kLookupInHolder);
-}
-
-
 bool AccessorInfo::all_can_read() {
   return BooleanBit::get(flag(), kAllCanReadBit);
 }