Version 3.9.0
Reduce memory use immediately after starting V8.
Stability fixes and performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@10576 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index f95ecdf..7f3d318 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -428,6 +428,23 @@
}
+MaybeObject* TransitionElements(Handle<Object> object,
+ ElementsKind to_kind,
+ Isolate* isolate) {
+ HandleScope scope(isolate);
+ if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
+ ElementsKind from_kind =
+ Handle<JSObject>::cast(object)->map()->elements_kind();
+ if (Map::IsValidElementsTransition(from_kind, to_kind)) {
+ Handle<Object> result = JSObject::TransitionElementsKind(
+ Handle<JSObject>::cast(object), to_kind);
+ if (result.is_null()) return isolate->ThrowIllegalOperation();
+ return *result;
+ }
+ return isolate->ThrowIllegalOperation();
+}
+
+
static const int kSmiOnlyLiteralMinimumLength = 1024;
@@ -446,25 +463,13 @@
Handle<FixedArrayBase> constant_elements_values(
FixedArrayBase::cast(elements->get(1)));
- ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS ||
- constant_elements_kind == FAST_SMI_ONLY_ELEMENTS);
- bool allow_literal_kind_transition = FLAG_smi_only_arrays &&
- constant_elements_kind > object->GetElementsKind();
-
- if (!FLAG_smi_only_arrays &&
- constant_elements_values->length() > kSmiOnlyLiteralMinimumLength &&
- constant_elements_kind != object->GetElementsKind()) {
- allow_literal_kind_transition = true;
- }
-
- // If the ElementsKind of the constant values of the array literal are less
- // specific than the ElementsKind of the boilerplate array object, change the
- // boilerplate array object's map to reflect that kind.
- if (allow_literal_kind_transition) {
- Handle<Map> transitioned_array_map =
- isolate->factory()->GetElementsTransitionMap(object,
- constant_elements_kind);
- object->set_map(*transitioned_array_map);
+ Context* global_context = isolate->context()->global_context();
+ if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) {
+ object->set_map(Map::cast(global_context->smi_js_array_map()));
+ } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
+ object->set_map(Map::cast(global_context->double_js_array_map()));
+ } else {
+ object->set_map(Map::cast(global_context->object_js_array_map()));
}
Handle<FixedArrayBase> copied_elements_values;
@@ -509,6 +514,16 @@
}
object->set_elements(*copied_elements_values);
object->set_length(Smi::FromInt(copied_elements_values->length()));
+
+ // Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is
+ // on or the object is larger than the threshold.
+ if (!FLAG_smi_only_arrays &&
+ constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) {
+ if (object->GetElementsKind() != FAST_ELEMENTS) {
+ CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
+ }
+ }
+
return object;
}
@@ -4202,23 +4217,6 @@
}
-MaybeObject* TransitionElements(Handle<Object> object,
- ElementsKind to_kind,
- Isolate* isolate) {
- HandleScope scope(isolate);
- if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
- ElementsKind from_kind =
- Handle<JSObject>::cast(object)->map()->elements_kind();
- if (Map::IsValidElementsTransition(from_kind, to_kind)) {
- Handle<Object> result = JSObject::TransitionElementsKind(
- Handle<JSObject>::cast(object), to_kind);
- if (result.is_null()) return isolate->ThrowIllegalOperation();
- return *result;
- }
- return isolate->ThrowIllegalOperation();
-}
-
-
// KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric.
RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
NoHandleAllocation ha;
@@ -10236,7 +10234,7 @@
} else {
elements_kind = DICTIONARY_ELEMENTS;
}
- maybe_new_map = to->GetElementsTransitionMap(elements_kind);
+ maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind);
Object* new_map;
if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
to->set_map(Map::cast(new_map));
@@ -10749,6 +10747,11 @@
? deoptimized_frame_->GetExpression(index)
: frame_->GetExpression(index);
}
+ int GetSourcePosition() {
+ return is_optimized_
+ ? deoptimized_frame_->GetSourcePosition()
+ : frame_->LookupCode()->SourcePosition(frame_->pc());
+ }
// To inspect all the provided arguments the frame might need to be
// replaced with the arguments frame.
@@ -10854,9 +10857,8 @@
// Get the frame id.
Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
- // Find source position.
- int position =
- it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
+ // Find source position in unoptimized code.
+ int position = frame_inspector.GetSourcePosition();
// Check for constructor frame. Inlined frames cannot be construct calls.
bool inlined_frame = is_optimized && inlined_jsframe_index != 0;