Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Unified Diff: src/ia32/builtins-ia32.cc

Issue 10615002: Track allocation info (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Diff with b_e Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/builtins-ia32.cc
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 9bc15e90986c54048aa950b7bac9b3391ba0c0be..81824397121e3db005656830b836a035989aece4 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -930,91 +930,137 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
static void AllocateEmptyJSArray(MacroAssembler* masm,
Register array_function,
Register result,
- Register scratch1,
+ Register type_info_cell,
Register scratch2,
Register scratch3,
Label* gc_required) {
- const int initial_capacity = JSArray::kPreallocatedArrayElements;
- STATIC_ASSERT(initial_capacity >= 0);
-
- __ LoadInitialArrayMap(array_function, scratch2, scratch1, false);
-
+ Label with_alloc_info, no_alloc_info, common_init, empty_double;
+ Label no_known_elements_kind, init_js_array;
+ Register scratch1 = type_info_cell;
+
+ // If no type info cell is provided, then there's no point in tracking
+ // site allocation info.
+ Handle<Object> undefined_value(masm->isolate()->heap()->undefined_value());
+ __ cmp(type_info_cell, Immediate(undefined_value));
+ __ j(equal, &no_known_elements_kind);
+
+ // If there is a type info cell provided, only track information about the
+ // allocation site if the no ElementsKind transition has been detected.
+ __ mov(scratch3, FieldOperand(type_info_cell,
+ JSGlobalPropertyCell::kValueOffset));
+ __ JumpIfNotSmi(scratch3, &no_known_elements_kind);
+ __ cmp(scratch3, Immediate(Smi::FromInt(GetInitialFastElementsKind())));
+ __ j(equal, &with_alloc_info);
+
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
+ __ cmp(scratch3, Immediate(Smi::FromInt(FAST_HOLEY_ELEMENTS)));
+ __ j(above, gc_required);
+
+ __ LoadInitialArrayMap(array_function, scratch3, scratch2);
+ __ jmp(&no_alloc_info);
+
// Allocate the JSArray object together with space for a fixed array with the
- // requested elements.
+ // requested elements and an AllocationSiteInfo object to later be able to
+ // feed back array transition information to the allocation site.
+ __ bind(&with_alloc_info);
int size = JSArray::kSize;
- if (initial_capacity > 0) {
- size += FixedArray::SizeFor(initial_capacity);
- }
+ int allocation_info_start = size;
+ int elements_offset = size;
+ size += AllocationSiteInfo::kSize;
+ elements_offset = size;
+ size += FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
__ AllocateInNewSpace(size,
result,
scratch2,
scratch3,
gc_required,
- TAG_OBJECT);
-
- // Allocated the JSArray. Now initialize the fields except for the elements
- // array.
- // result: JSObject
- // scratch1: initial map
- // scratch2: start of next object
- __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1);
- Factory* factory = masm->isolate()->factory();
- __ mov(FieldOperand(result, JSArray::kPropertiesOffset),
- factory->empty_fixed_array());
- // Field JSArray::kElementsOffset is initialized later.
- __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
-
- // If no storage is requested for the elements array just set the empty
- // fixed array.
- if (initial_capacity == 0) {
- __ mov(FieldOperand(result, JSArray::kElementsOffset),
- factory->empty_fixed_array());
- return;
- }
+ TAG_OBJECT);
+
+ // Track information about the allocation site
+ __ mov(FieldOperand(result, allocation_info_start),
+ Immediate(Handle<Map>(masm->isolate()->heap()->
+ allocation_site_info_map())));
+ __ mov(FieldOperand(result, allocation_info_start + kPointerSize),
+ type_info_cell); // No write barrier because it's a cell.
// Calculate the location of the elements array and set elements array member
// of the JSArray.
- // result: JSObject
- // scratch2: start of next object
- __ lea(scratch1, Operand(result, JSArray::kSize));
- __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1);
-
+ // result: JSArray
+ __ LoadInitialArrayMap(array_function, GetInitialFastElementsKind(), scratch2);
+ __ lea(scratch1, Operand(result, elements_offset));
+ __ jmp(&common_init);
+
+ __ bind(&no_known_elements_kind);
+ __ LoadInitialArrayMap(array_function, GetInitialFastElementsKind(), scratch2);
+
+ // Allocate the JSArray object together with space for a fixed array with the
+ // requested elements.
+ __ bind(&no_alloc_info);
+ size = JSArray::kSize;
+ elements_offset = size;
+ size += FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
+ __ AllocateInNewSpace(size,
+ result,
+ scratch1,
+ scratch3,
+ gc_required,
+ TAG_OBJECT);
+ // Calculate the location of the elements array and set elements array member
+ // of the JSArray.
+ // result: JSArray
+ __ lea(scratch1, Operand(result, elements_offset));
+
+ __ bind(&common_init);
// Initialize the FixedArray and fill it with holes. FixedArray length is
// stored as a smi.
// result: JSObject
// scratch1: elements array
- // scratch2: start of next object
+ Factory* factory = masm->isolate()->factory();
__ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
factory->fixed_array_map());
__ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
- Immediate(Smi::FromInt(initial_capacity)));
+ Immediate(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
// Fill the FixedArray with the hole value. Inline the code if short.
// Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
static const int kLoopUnfoldLimit = 4;
- if (initial_capacity <= kLoopUnfoldLimit) {
+ if (JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit) {
// Use a scratch register here to have only one reloc info when unfolding
// the loop.
__ mov(scratch3, factory->the_hole_value());
- for (int i = 0; i < initial_capacity; i++) {
+ for (int i = 0; i < JSArray::kPreallocatedArrayElements; i++) {
__ mov(FieldOperand(scratch1,
FixedArray::kHeaderSize + i * kPointerSize),
scratch3);
}
} else {
Label loop, entry;
- __ mov(scratch2, Immediate(initial_capacity));
+ __ mov(scratch3, Immediate(JSArray::kPreallocatedArrayElements));
__ jmp(&entry);
__ bind(&loop);
__ mov(FieldOperand(scratch1,
- scratch2,
+ scratch3,
times_pointer_size,
FixedArray::kHeaderSize),
factory->the_hole_value());
__ bind(&entry);
- __ dec(scratch2);
+ __ dec(scratch3);
__ j(not_sign, &loop);
}
+
+ __ bind(&init_js_array);
+ // Initialize the fields of the JSArray
+ // result: JSArray
+ // scratch1: elements array
+ // scratch2: map for Array
+ __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1);
+ __ mov(FieldOperand(result, JSObject::kMapOffset), scratch2);
+ __ mov(FieldOperand(result, JSArray::kPropertiesOffset),
+ factory->empty_fixed_array());
+ __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
}
@@ -1046,7 +1092,10 @@ static void AllocateJSArray(MacroAssembler* masm,
// Allocate the JSArray object together with space for a FixedArray with the
// requested elements.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
- __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
+
+ int fixed_size = JSArray::kSize + FixedArray::kHeaderSize +
+ AllocationSiteInfo::kSize;
+ __ AllocateInNewSpace(fixed_size,
times_half_pointer_size, // array_size is a smi.
array_size,
result,
@@ -1054,6 +1103,7 @@ static void AllocateJSArray(MacroAssembler* masm,
scratch,
gc_required,
TAG_OBJECT);
+ __ sub(elements_array_end, Immediate(AllocationSiteInfo::kSize));
// Allocated the JSArray. Now initialize the fields except for the elements
// array.
@@ -1111,6 +1161,13 @@ static void AllocateJSArray(MacroAssembler* masm,
__ j(below, &loop);
__ bind(&done);
}
+
+ // Track information about the allocation site
+ __ mov(Operand(elements_array_end, 0),
+ Immediate(Handle<Map>(masm->isolate()->heap()->
+ allocation_site_info_map())));
+ __ mov(Operand(elements_array_end, kPointerSize),
+ Immediate(Handle<HeapObject>(masm->isolate()->heap()->null_value())));
}
@@ -1120,6 +1177,7 @@ static void AllocateJSArray(MacroAssembler* masm,
// function assumes the following state:
// edi: constructor (built-in Array function)
// eax: argc
+// ebx: cell containing type feedback cell for Array's ElementsKind
// esp[0]: return address
// esp[4]: last argument
// This function is used for both construct and normal calls of Array. Whether
@@ -1155,7 +1213,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
eax,
ebx,
ecx,
- edi,
+ edx,
&prepare_generic_code_call);
__ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1);
__ pop(ebx);
@@ -1361,14 +1419,18 @@ void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Initial map for the builtin InternalArray function should be a map.
- __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
+ __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a NULL and a Smi.
- __ test(ebx, Immediate(kSmiTagMask));
+ __ test(ecx, Immediate(kSmiTagMask));
__ Assert(not_zero, "Unexpected initial map for InternalArray function");
- __ CmpObjectType(ebx, MAP_TYPE, ecx);
+ __ CmpObjectType(ecx, MAP_TYPE, ecx);
__ Assert(equal, "Unexpected initial map for InternalArray function");
}
+ // No type feedback cell is available
+ Handle<Object> undefined_sentinel(masm->isolate()->heap()->undefined_value());
+ __ mov(ebx, Immediate(undefined_sentinel));
+
// Run the native code for the InternalArray function called as a normal
// function.
ArrayNativeCode(masm, false, &generic_array_code);
@@ -1395,14 +1457,18 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Initial map for the builtin Array function should be a map.
- __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
+ __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a NULL and a Smi.
- __ test(ebx, Immediate(kSmiTagMask));
+ __ test(ecx, Immediate(kSmiTagMask));
__ Assert(not_zero, "Unexpected initial map for Array function");
- __ CmpObjectType(ebx, MAP_TYPE, ecx);
+ __ CmpObjectType(ecx, MAP_TYPE, ecx);
__ Assert(equal, "Unexpected initial map for Array function");
}
+ // No type feedback cell is available
+ Handle<Object> undefined_sentinel(masm->isolate()->heap()->undefined_value());
+ __ mov(ebx, Immediate(undefined_sentinel));
+
// Run the native code for the Array function called as a normal function.
ArrayNativeCode(masm, false, &generic_array_code);
@@ -1429,11 +1495,11 @@ void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) {
// builtin Array functions which always have maps.
// Initial map for the builtin Array function should be a map.
- __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
+ __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a NULL and a Smi.
- __ test(ebx, Immediate(kSmiTagMask));
+ __ test(ecx, Immediate(kSmiTagMask));
__ Assert(not_zero, "Unexpected initial map for Array function");
- __ CmpObjectType(ebx, MAP_TYPE, ecx);
+ __ CmpObjectType(ecx, MAP_TYPE, ecx);
__ Assert(equal, "Unexpected initial map for Array function");
}
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698