Revision: 10314
Author: [email protected]
Date: Mon Jan 2 01:26:59 2012
Log: Version 3.8.4
Performance improvements for large Smi-only arrays.
Fixed InternalArrays construction. (issue 1878)
http://code.google.com/p/v8/source/detail?r=10314
Added:
/trunk/test/mjsunit/regress/regress-1849.js
/trunk/test/mjsunit/regress/regress-1878.js
Modified:
/trunk/ChangeLog
/trunk/src/arm/builtins-arm.cc
/trunk/src/ast.cc
/trunk/src/bootstrapper.cc
/trunk/src/builtins.cc
/trunk/src/builtins.h
/trunk/src/contexts.h
/trunk/src/ia32/builtins-ia32.cc
/trunk/src/objects-inl.h
/trunk/src/objects.cc
/trunk/src/objects.h
/trunk/src/runtime.cc
/trunk/src/runtime.h
/trunk/src/version.cc
/trunk/src/x64/builtins-x64.cc
/trunk/test/mjsunit/regress/regress-95113.js
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-1849.js Mon Jan 2 01:26:59 2012
@@ -0,0 +1,39 @@
+// Copyright 2011 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.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1878
+
+// Flags: --allow-natives-syntax
+
+var count = 1e5;
+var arr = new Array(count);
+assertFalse(%HasFastDoubleElements(arr));
+for (var i = 0; i < count; i++) {
+ arr[i] = 0;
+}
+assertFalse(%HasFastDoubleElements(arr));
+assertTrue(%HasFastSmiOnlyElements(arr));
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-1878.js Mon Jan 2 01:26:59 2012
@@ -0,0 +1,34 @@
+// Copyright 2009 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.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1878
+
+// Flags: --allow-natives-syntax --expose_natives_as=natives
+
+var a = Array();
+var ai = natives.InternalArray();
+assertFalse(%HaveSameMap(ai, a));
=======================================
--- /trunk/ChangeLog Tue Dec 27 02:09:42 2011
+++ /trunk/ChangeLog Mon Jan 2 01:26:59 2012
@@ -1,3 +1,10 @@
+2012-01-02: Version 3.8.4
+
+ Performance improvements for large Smi-only arrays.
+
+ Fixed InternalArrays construction. (issue 1878)
+
+
2011-12-27: Version 3.8.3
Avoid embedding new space objects into code objects in the lithium
gap
=======================================
--- /trunk/src/arm/builtins-arm.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/arm/builtins-arm.cc Mon Jan 2 01:26:59 2012
@@ -70,6 +70,22 @@
__ add(r0, r0, Operand(num_extra_args + 1));
__ JumpToExternalReference(ExternalReference(id, masm->isolate()));
}
+
+
+// Load the built-in InternalArray function from the current context.
+static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
+ Register result) {
+ // Load the global context.
+
+ __ ldr(result, MemOperand(cp,
Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ ldr(result,
+ FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
+ // Load the InternalArray function from the global context.
+ __ ldr(result,
+ MemOperand(result,
+ Context::SlotOffset(
+ Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
+}
// Load the built-in Array function from the current context.
@@ -416,6 +432,40 @@
__ mov(r0, r3);
__ Jump(lr);
}
+
+
+void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- r0 : number of arguments
+ // -- lr : return address
+ // -- sp[...]: constructor arguments
+ // -----------------------------------
+ Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
+
+ // Get the InternalArray function.
+ GenerateLoadInternalArrayFunction(masm, r1);
+
+ if (FLAG_debug_code) {
+ // Initial map for the builtin InternalArray functions should be maps.
+ __ ldr(r2, FieldMemOperand(r1,
JSFunction::kPrototypeOrInitialMapOffset));
+ __ tst(r2, Operand(kSmiTagMask));
+ __ Assert(ne, "Unexpected initial map for InternalArray function");
+ __ CompareObjectType(r2, r3, r4, MAP_TYPE);
+ __ Assert(eq, "Unexpected initial map for InternalArray function");
+ }
+
+ // Run the native code for the InternalArray function called as a normal
+ // function.
+ ArrayNativeCode(masm, &generic_array_code);
+
+ // Jump to the generic array code if the specialized code cannot handle
the
+ // construction.
+ __ bind(&generic_array_code);
+
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->InternalArrayCodeGeneric();
+ __ Jump(array_code, RelocInfo::CODE_TARGET);
+}
void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
=======================================
--- /trunk/src/ast.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/ast.cc Mon Jan 2 01:26:59 2012
@@ -748,7 +748,8 @@
type->LookupInDescriptors(NULL, *name, &lookup);
// If the function wasn't found directly in the map, we start
// looking upwards through the prototype chain.
- if (!lookup.IsFound() && type->prototype()->IsJSObject()) {
+ if ((!lookup.IsFound() || IsTransitionType(lookup.type()))
+ && type->prototype()->IsJSObject()) {
holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
type = Handle<Map>(holder()->map());
} else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
=======================================
--- /trunk/src/bootstrapper.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/bootstrapper.cc Mon Jan 2 01:26:59 2012
@@ -1613,16 +1613,13 @@
// doesn't inherit from Object.prototype.
// To be used only for internal work by builtins. Instances
// must not be leaked to user code.
- // Only works correctly when called as a constructor. The normal
- // Array code uses Array.prototype as prototype when called as
- // a function.
Handle<JSFunction> array_function =
InstallFunction(builtins,
"InternalArray",
JS_ARRAY_TYPE,
JSArray::kSize,
isolate()->initial_object_prototype(),
- Builtins::kArrayCode,
+ Builtins::kInternalArrayCode,
true);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
@@ -1654,6 +1651,8 @@
array_function->initial_map()->set_instance_descriptors(
*array_descriptors);
+
+ global_context()->set_internal_array_function(*array_function);
}
if (FLAG_disable_native_files) {
=======================================
--- /trunk/src/builtins.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/builtins.cc Mon Jan 2 01:26:59 2012
@@ -184,31 +184,28 @@
}
-BUILTIN(ArrayCodeGeneric) {
+static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
+ Isolate* isolate,
+ JSFunction* constructor) {
Heap* heap = isolate->heap();
isolate->counters()->array_function_runtime()->Increment();
JSArray* array;
if (CalledAsConstructor(isolate)) {
- array = JSArray::cast(*args.receiver());
+ array = JSArray::cast((*args)[0]);
} else {
// Allocate the JS Array
- JSFunction* constructor =
- isolate->context()->global_context()->array_function();
Object* obj;
{ MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
array = JSArray::cast(obj);
}
-
- // 'array' now contains the JSArray we should initialize.
- ASSERT(array->HasFastTypeElements());
// Optimize the case where there is one argument and the argument is a
// small smi.
- if (args.length() == 2) {
- Object* obj = args[1];
+ if (args->length() == 2) {
+ Object* obj = (*args)[1];
if (obj->IsSmi()) {
int len = Smi::cast(obj)->value();
if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
@@ -225,18 +222,18 @@
{ MaybeObject* maybe_obj = array->Initialize(0);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- return array->SetElementsLength(args[1]);
+ return array->SetElementsLength((*args)[1]);
}
// Optimize the case where there are no parameters passed.
- if (args.length() == 1) {
+ if (args->length() == 1) {
return array->Initialize(JSArray::kPreallocatedArrayElements);
}
// Set length and elements on the array.
- int number_of_elements = args.length() - 1;
+ int number_of_elements = args->length() - 1;
MaybeObject* maybe_object =
- array->EnsureCanContainElements(&args, 1, number_of_elements,
+ array->EnsureCanContainElements(args, 1, number_of_elements,
ALLOW_CONVERTED_DOUBLE_ELEMENTS);
if (maybe_object->IsFailure()) return maybe_object;
@@ -257,7 +254,7 @@
case FAST_SMI_ONLY_ELEMENTS: {
FixedArray* smi_elms = FixedArray::cast(elms);
for (int index = 0; index < number_of_elements; index++) {
- smi_elms->set(index, args[index+1], SKIP_WRITE_BARRIER);
+ smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER);
}
break;
}
@@ -266,14 +263,14 @@
WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
FixedArray* object_elms = FixedArray::cast(elms);
for (int index = 0; index < number_of_elements; index++) {
- object_elms->set(index, args[index+1], mode);
+ object_elms->set(index, (*args)[index+1], mode);
}
break;
}
case FAST_DOUBLE_ELEMENTS: {
FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms);
for (int index = 0; index < number_of_elements; index++) {
- double_elms->set(index, args[index+1]->Number());
+ double_elms->set(index, (*args)[index+1]->Number());
}
break;
}
@@ -286,6 +283,22 @@
array->set_length(Smi::FromInt(number_of_elements));
return array;
}
+
+
+BUILTIN(InternalArrayCodeGeneric) {
+ return ArrayCodeGenericCommon(
+ &args,
+ isolate,
+ isolate->context()->global_context()->internal_array_function());
+}
+
+
+BUILTIN(ArrayCodeGeneric) {
+ return ArrayCodeGenericCommon(
+ &args,
+ isolate,
+ isolate->context()->global_context()->array_function());
+}
MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) {
=======================================
--- /trunk/src/builtins.h Thu Nov 10 03:38:15 2011
+++ /trunk/src/builtins.h Mon Jan 2 01:26:59 2012
@@ -44,6 +44,7 @@
\
V(EmptyFunction, NO_EXTRA_ARGUMENTS) \
\
+ V(InternalArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \
V(ArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \
\
V(ArrayPush, NO_EXTRA_ARGUMENTS) \
@@ -178,6 +179,8 @@
V(FunctionApply, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
\
+ V(InternalArrayCode, BUILTIN, UNINITIALIZED, \
+ Code::kNoExtraICState) \
V(ArrayCode, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
V(ArrayConstructCode, BUILTIN, UNINITIALIZED, \
@@ -359,6 +362,7 @@
static void Generate_FunctionCall(MacroAssembler* masm);
static void Generate_FunctionApply(MacroAssembler* masm);
+ static void Generate_InternalArrayCode(MacroAssembler* masm);
static void Generate_ArrayCode(MacroAssembler* masm);
static void Generate_ArrayConstructCode(MacroAssembler* masm);
=======================================
--- /trunk/src/contexts.h Thu Nov 17 00:34:43 2011
+++ /trunk/src/contexts.h Mon Jan 2 01:26:59 2012
@@ -104,6 +104,7 @@
V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map,
string_function_prototype_map) \
V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
+ V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
V(JSON_OBJECT_INDEX, JSObject, json_object) \
@@ -244,6 +245,7 @@
STRING_FUNCTION_INDEX,
STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
OBJECT_FUNCTION_INDEX,
+ INTERNAL_ARRAY_FUNCTION_INDEX,
ARRAY_FUNCTION_INDEX,
DATE_FUNCTION_INDEX,
JSON_OBJECT_INDEX,
=======================================
--- /trunk/src/ia32/builtins-ia32.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/ia32/builtins-ia32.cc Mon Jan 2 01:26:59 2012
@@ -1306,6 +1306,40 @@
}
__ jmp(call_generic_code);
}
+
+
+void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- eax : argc
+ // -- esp[0] : return address
+ // -- esp[4] : last argument
+ // -----------------------------------
+ Label generic_array_code;
+
+ // Get the InternalArray function.
+ __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi);
+
+ if (FLAG_debug_code) {
+ // Initial map for the builtin InternalArray function shoud be a map.
+ __ mov(ebx, FieldOperand(edi,
JSFunction::kPrototypeOrInitialMapOffset));
+ // Will both indicate a NULL and a Smi.
+ __ test(ebx, Immediate(kSmiTagMask));
+ __ Assert(not_zero, "Unexpected initial map for InternalArray
function");
+ __ CmpObjectType(ebx, MAP_TYPE, ecx);
+ __ Assert(equal, "Unexpected initial map for InternalArray function");
+ }
+
+ // Run the native code for the InternalArray function called as a normal
+ // function.
+ ArrayNativeCode(masm, false, &generic_array_code);
+
+ // Jump to the generic array code in case the specialized code cannot
handle
+ // the construction.
+ __ bind(&generic_array_code);
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->InternalArrayCodeGeneric();
+ __ jmp(array_code, RelocInfo::CODE_TARGET);
+}
void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
=======================================
--- /trunk/src/objects-inl.h Mon Dec 19 04:13:11 2011
+++ /trunk/src/objects-inl.h Mon Jan 2 01:26:59 2012
@@ -1219,7 +1219,7 @@
map != heap->free_space_map()) {
for (int i = 0; i < fixed_array->length(); i++) {
Object* current = fixed_array->get(i);
- ASSERT(current->IsSmi() || current == heap->the_hole_value());
+ ASSERT(current->IsSmi() || current->IsTheHole());
}
}
}
@@ -1290,20 +1290,35 @@
}
-void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
+void JSObject::set_map_and_elements(Map* new_map,
+ FixedArrayBase* value,
+ WriteBarrierMode mode) {
+ ASSERT(value->HasValidElements());
+#ifdef DEBUG
+ ValidateSmiOnlyElements();
+#endif
+ if (new_map != NULL) {
+ if (mode == UPDATE_WRITE_BARRIER) {
+ set_map(new_map);
+ } else {
+ ASSERT(mode == SKIP_WRITE_BARRIER);
+ set_map_no_write_barrier(new_map);
+ }
+ }
ASSERT((map()->has_fast_elements() ||
map()->has_fast_smi_only_elements()) ==
(value->map() == GetHeap()->fixed_array_map() ||
value->map() == GetHeap()->fixed_cow_array_map()));
ASSERT(map()->has_fast_double_elements() ==
value->IsFixedDoubleArray());
- ASSERT(value->HasValidElements());
-#ifdef DEBUG
- ValidateSmiOnlyElements();
-#endif
WRITE_FIELD(this, kElementsOffset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
}
+
+
+void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
+ set_map_and_elements(NULL, value, mode);
+}
void JSObject::initialize_properties() {
=======================================
--- /trunk/src/objects.cc Tue Dec 27 02:09:42 2011
+++ /trunk/src/objects.cc Mon Jan 2 01:26:59 2012
@@ -8188,10 +8188,13 @@
Map* new_map = NULL;
if (elements()->map() != heap->non_strict_arguments_elements_map()) {
Object* object;
+ // The resized array has FAST_SMI_ONLY_ELEMENTS if the capacity mode
forces
+ // it, or if it's allowed and the old elements array contained only
SMIs.
bool has_fast_smi_only_elements =
- (set_capacity_mode == kAllowSmiOnlyElements) &&
- (elements()->map()->has_fast_smi_only_elements() ||
- elements() == heap->empty_fixed_array());
+ (set_capacity_mode == kForceSmiOnlyElements) ||
+ ((set_capacity_mode == kAllowSmiOnlyElements) &&
+ (elements()->map()->has_fast_smi_only_elements() ||
+ elements() == heap->empty_fixed_array()));
ElementsKind elements_kind = has_fast_smi_only_elements
? FAST_SMI_ONLY_ELEMENTS
: FAST_ELEMENTS;
@@ -8209,8 +8212,7 @@
WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc));
CopyFastElementsToFast(FixedArray::cast(old_elements_raw),
new_elements, mode);
- set_map(new_map);
- set_elements(new_elements);
+ set_map_and_elements(new_map, new_elements);
break;
}
case DICTIONARY_ELEMENTS: {
@@ -8219,8 +8221,7 @@
CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw),
new_elements,
mode);
- set_map(new_map);
- set_elements(new_elements);
+ set_map_and_elements(new_map, new_elements);
break;
}
case NON_STRICT_ARGUMENTS_ELEMENTS: {
@@ -9241,11 +9242,20 @@
} else {
new_length = dictionary->max_number_key() + 1;
}
- MaybeObject* result = CanConvertToFastDoubleElements()
+ SetFastElementsCapacityMode set_capacity_mode = FLAG_smi_only_arrays
+ ? kAllowSmiOnlyElements
+ : kDontAllowSmiOnlyElements;
+ bool has_smi_only_elements = false;
+ bool should_convert_to_fast_double_elements =
+ ShouldConvertToFastDoubleElements(&has_smi_only_elements);
+ if (has_smi_only_elements) {
+ set_capacity_mode = kForceSmiOnlyElements;
+ }
+ MaybeObject* result = should_convert_to_fast_double_elements
? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
: SetFastElementsCapacityAndLength(new_length,
new_length,
- kDontAllowSmiOnlyElements);
+ set_capacity_mode);
if (result->IsFailure()) return result;
#ifdef DEBUG
if (FLAG_trace_normalization) {
@@ -9724,17 +9734,25 @@
}
-bool JSObject::CanConvertToFastDoubleElements() {
+bool JSObject::ShouldConvertToFastDoubleElements(
+ bool* has_smi_only_elements) {
+ *has_smi_only_elements = false;
if (FLAG_unbox_double_arrays) {
ASSERT(HasDictionaryElements());
NumberDictionary* dictionary = NumberDictionary::cast(elements());
+ bool found_double = false;
for (int i = 0; i < dictionary->Capacity(); i++) {
Object* key = dictionary->KeyAt(i);
if (key->IsNumber()) {
- if (!dictionary->ValueAt(i)->IsNumber()) return false;
+ Object* value = dictionary->ValueAt(i);
+ if (!value->IsNumber()) return false;
+ if (!value->IsSmi()) {
+ found_double = true;
+ }
}
}
- return true;
+ *has_smi_only_elements = !found_double;
+ return found_double;
} else {
return false;
}
=======================================
--- /trunk/src/objects.h Mon Dec 19 04:13:11 2011
+++ /trunk/src/objects.h Mon Jan 2 01:26:59 2012
@@ -1473,6 +1473,11 @@
bool HasDictionaryArgumentsElements();
inline NumberDictionary* element_dictionary(); // Gets slow elements.
+ inline void set_map_and_elements(
+ Map* map,
+ FixedArrayBase* value,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
// Requires: HasFastElements().
MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
@@ -1644,8 +1649,9 @@
// elements.
bool ShouldConvertToFastElements();
// Returns true if the elements of JSObject contains only values that
can be
- // represented in a FixedDoubleArray.
- bool CanConvertToFastDoubleElements();
+ // represented in a FixedDoubleArray and has at least one value that can
only
+ // be represented as a double and not a Smi.
+ bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
// Tells whether the index'th element is present.
bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index);
@@ -1708,6 +1714,7 @@
enum SetFastElementsCapacityMode {
kAllowSmiOnlyElements,
+ kForceSmiOnlyElements,
kDontAllowSmiOnlyElements
};
=======================================
--- /trunk/src/runtime.cc Wed Dec 21 00:29:34 2011
+++ /trunk/src/runtime.cc Mon Jan 2 01:26:59 2012
@@ -9227,22 +9227,6 @@
PrintF("\n");
}
}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceElementsKindTransition) {
- ASSERT(args.length() == 5);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- CONVERT_SMI_ARG_CHECKED(from_kind, 1);
- CONVERT_ARG_CHECKED(FixedArrayBase, from_elements, 2);
- CONVERT_SMI_ARG_CHECKED(to_kind, 3);
- CONVERT_ARG_CHECKED(FixedArrayBase, to_elements, 4);
- NoHandleAllocation ha;
- PrintF("*");
- obj->PrintElementsTransition(stdout,
- static_cast<ElementsKind>(from_kind), *from_elements,
- static_cast<ElementsKind>(to_kind), *to_elements);
- return isolate->heap()->undefined_value();
-}
RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
=======================================
--- /trunk/src/runtime.h Mon Dec 19 04:13:11 2011
+++ /trunk/src/runtime.h Mon Jan 2 01:26:59 2012
@@ -341,7 +341,6 @@
/* Debugging */ \
F(DebugPrint, 1, 1) \
F(DebugTrace, 0, 1) \
- F(TraceElementsKindTransition, 5, 1) \
F(TraceEnter, 0, 1) \
F(TraceExit, 1, 1) \
F(Abort, 2, 1) \
=======================================
--- /trunk/src/version.cc Tue Dec 27 02:09:42 2011
+++ /trunk/src/version.cc Mon Jan 2 01:26:59 2012
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 8
-#define BUILD_NUMBER 3
+#define BUILD_NUMBER 4
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x64/builtins-x64.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/x64/builtins-x64.cc Mon Jan 2 01:26:59 2012
@@ -1325,6 +1325,41 @@
__ movq(rax, rbx);
__ ret(0);
}
+
+
+void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- rax : argc
+ // -- rsp[0] : return address
+ // -- rsp[8] : last argument
+ // -----------------------------------
+ Label generic_array_code;
+
+ // Get the InternalArray function.
+ __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, rdi);
+
+ if (FLAG_debug_code) {
+ // Initial map for the builtin InternalArray functions should be maps.
+ __ movq(rbx, FieldOperand(rdi,
JSFunction::kPrototypeOrInitialMapOffset));
+ // Will both indicate a NULL and a Smi.
+ STATIC_ASSERT(kSmiTag == 0);
+ Condition not_smi = NegateCondition(masm->CheckSmi(rbx));
+ __ Check(not_smi, "Unexpected initial map for InternalArray function");
+ __ CmpObjectType(rbx, MAP_TYPE, rcx);
+ __ Check(equal, "Unexpected initial map for InternalArray function");
+ }
+
+ // Run the native code for the InternalArray function called as a normal
+ // function.
+ ArrayNativeCode(masm, &generic_array_code);
+
+ // Jump to the generic array code in case the specialized code cannot
handle
+ // the construction.
+ __ bind(&generic_array_code);
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->InternalArrayCodeGeneric();
+ __ Jump(array_code, RelocInfo::CODE_TARGET);
+}
void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
=======================================
--- /trunk/test/mjsunit/regress/regress-95113.js Wed Sep 7 05:44:28 2011
+++ /trunk/test/mjsunit/regress/regress-95113.js Mon Jan 2 01:26:59 2012
@@ -32,7 +32,7 @@
var i = 0;
while (!%HasFastDoubleElements(a)) {
a[i] = i;
- i++;
+ i += 0.5;
}
assertTrue(%HasFastDoubleElements(a));
a.length = 1;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev