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

Side by Side Diff: src/builtins.cc

Issue 11818021: Allocation Info Tracking, continued. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 UNREACHABLE(); 179 UNREACHABLE();
180 return isolate->heap()->undefined_value(); // Make compiler happy. 180 return isolate->heap()->undefined_value(); // Make compiler happy.
181 } 181 }
182 182
183 183
184 BUILTIN(EmptyFunction) { 184 BUILTIN(EmptyFunction) {
185 return isolate->heap()->undefined_value(); 185 return isolate->heap()->undefined_value();
186 } 186 }
187 187
188 188
189 #define CONVERT_ARG_STUB_CALLER_ARGS(name) \
190 Arguments* name = reinterpret_cast<Arguments*>(args[0]);
191
192
193 RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure) {
194 CONVERT_ARG_STUB_CALLER_ARGS(caller_args);
195 // ASSERT(args.length() == 3);
196 Handle<JSFunction> function = args.at<JSFunction>(1);
197 Handle<Object> type_info = args.at<Object>(2);
198
199 JSArray* array = NULL;
200 bool holey = false;
201 if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) {
202 int value = Smi::cast((*caller_args)[0])->value();
203 holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray);
204 }
205
206 // Allocate the initial map if absent.
207 if (!function->has_initial_map()) {
208 Object* initial_map;
209 { MaybeObject* maybe_initial_map =
210 isolate->heap()->AllocateInitialMap(*function);
211 if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map;
212 }
Toon Verwaest 2013/02/13 15:14:51 Remove { ... }; replace ToObject(& by To(&; set th
mvstanton 2013/02/19 11:04:08 Indeed, it won't be called until after the initial
213 function->set_initial_map(Map::cast(initial_map));
214 Map::cast(initial_map)->set_constructor(*function);
215 }
216
217 ElementsKind kind = function->initial_map()->elements_kind();
218 if (holey) {
219 kind = GetHoleyElementsKind(kind);
220 }
221
222 MaybeObject* maybe_array;
223 if (*type_info != isolate->heap()->undefined_value()) {
224 ASSERT(type_info->IsJSGlobalPropertyCell());
225 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
226 if (cell->value()->IsSmi()) {
227 Smi* smi = Smi::cast(cell->value());
228 ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
229 if (holey) {
Toon Verwaest 2013/02/13 15:14:51 If this is holey, you'll probably want to update t
mvstanton 2013/02/19 11:04:08 Done.
230 to_kind = GetHoleyElementsKind(to_kind);
231 }
232
233 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
Toon Verwaest 2013/02/13 15:14:51 Shouldn't happen I guess. Otherwise we are doing a
mvstanton 2013/02/19 11:04:08 good point, I'll let the ::GetMode(kind) call belo
234 maybe_array = isolate->heap()->AllocateEmptyJSArray(to_kind);
Toon Verwaest 2013/02/13 15:14:51 Again; update type feedback in the cell.
mvstanton 2013/02/19 11:04:08 Done.
235 } else {
236 AllocationSiteMode mode = AllocationSiteInfo::GetMode(kind);
237 maybe_array = isolate->heap()->AllocateEmptyJSArray(kind,
238 mode,
239 &type_info);
240 }
241 if (!maybe_array->To(&array)) return maybe_array;
242 }
243 }
244
245 if (array == NULL) {
246 maybe_array = isolate->heap()->AllocateEmptyJSArray(kind);
247 if (!maybe_array->To(&array)) return maybe_array;
248 }
249
250 maybe_array = ArrayConstructInitializeElements(array, caller_args);
251 if (maybe_array->IsFailure()) return maybe_array;
252 return array;
253 }
254
255
189 static MaybeObject* ArrayCodeGenericCommon(Arguments* args, 256 static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
190 Isolate* isolate, 257 Isolate* isolate,
191 JSFunction* constructor) { 258 JSFunction* constructor) {
259 ASSERT(args->length() >= 1);
192 Heap* heap = isolate->heap(); 260 Heap* heap = isolate->heap();
193 isolate->counters()->array_function_runtime()->Increment(); 261 isolate->counters()->array_function_runtime()->Increment();
194 262
195 JSArray* array; 263 JSArray* array;
196 if (CalledAsConstructor(isolate)) { 264 if (CalledAsConstructor(isolate)) {
197 array = JSArray::cast((*args)[0]); 265 array = JSArray::cast((*args)[0]);
198 // Initialize elements and length in case later allocations fail so that the 266 // Initialize elements and length in case later allocations fail so that the
199 // array object is initialized in a valid state. 267 // array object is initialized in a valid state.
200 array->set_length(Smi::FromInt(0)); 268 array->set_length(Smi::FromInt(0));
201 array->set_elements(heap->empty_fixed_array()); 269 array->set_elements(heap->empty_fixed_array());
270 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(array);
271 ElementsKind to_kind = array->GetElementsKind();
272 if (info != NULL && info->GetElementsKindPayload(&to_kind)) {
273 if (IsMoreGeneralElementsKindTransition(array->GetElementsKind(),
274 to_kind)) {
275 // We have advice that we should change the elements kind
276 if (FLAG_trace_track_allocation_sites) {
277 PrintF("AllocationSiteInfo: pre-transitioning array %p(%s->%s)\n",
278 reinterpret_cast<void*>(array),
279 ElementsKindToString(array->GetElementsKind()),
280 ElementsKindToString(to_kind));
281 }
282
283 MaybeObject* maybe_array =
284 array->TransitionElementsKind(to_kind);
285 if (maybe_array->IsFailure()) return maybe_array;
286 }
287 }
288
202 if (!FLAG_smi_only_arrays) { 289 if (!FLAG_smi_only_arrays) {
203 Context* native_context = isolate->context()->native_context(); 290 Context* native_context = isolate->context()->native_context();
204 if (array->GetElementsKind() == GetInitialFastElementsKind() && 291 if (array->GetElementsKind() == GetInitialFastElementsKind() &&
205 !native_context->js_array_maps()->IsUndefined()) { 292 !native_context->js_array_maps()->IsUndefined()) {
206 FixedArray* map_array = 293 FixedArray* map_array =
207 FixedArray::cast(native_context->js_array_maps()); 294 FixedArray::cast(native_context->js_array_maps());
208 array->set_map(Map::cast(map_array-> 295 array->set_map(Map::cast(map_array->
209 get(TERMINAL_FAST_ELEMENTS_KIND))); 296 get(TERMINAL_FAST_ELEMENTS_KIND)));
210 } 297 }
211 } 298 }
212 } else { 299 } else {
213 // Allocate the JS Array 300 // Allocate the JS Array
301 // TODO(mvstanton): There is no allocation info advice for this case.
302 // How to address?
214 MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); 303 MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
215 if (!maybe_obj->To(&array)) return maybe_obj; 304 if (!maybe_obj->To(&array)) return maybe_obj;
216 } 305 }
217 306
218 // Optimize the case where there is one argument and the argument is a 307 Arguments adjusted_arguments(args->length() - 1, args->arguments() - 1);
219 // small smi. 308 ASSERT(adjusted_arguments.length() < 1 ||
220 if (args->length() == 2) { 309 adjusted_arguments[0] == (*args)[1]);
221 Object* obj = (*args)[1]; 310 { MaybeObject* maybe_obj = ArrayConstructInitializeElements(array,
222 if (obj->IsSmi()) { 311 &adjusted_arguments);
223 int len = Smi::cast(obj)->value(); 312 if (!maybe_obj->To(&array)) return maybe_obj;
224 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
225 Object* fixed_array;
226 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len);
227 if (!maybe_obj->ToObject(&fixed_array)) return maybe_obj;
228 }
229 ElementsKind elements_kind = array->GetElementsKind();
230 if (!IsFastHoleyElementsKind(elements_kind)) {
231 elements_kind = GetHoleyElementsKind(elements_kind);
232 MaybeObject* maybe_array =
233 array->TransitionElementsKind(elements_kind);
234 if (maybe_array->IsFailure()) return maybe_array;
235 }
236 // We do not use SetContent to skip the unnecessary elements type check.
237 array->set_elements(FixedArray::cast(fixed_array));
238 array->set_length(Smi::cast(obj));
239 return array;
240 }
241 }
242 // Take the argument as the length.
243 { MaybeObject* maybe_obj = array->Initialize(0);
244 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
245 }
246 return array->SetElementsLength((*args)[1]);
247 } 313 }
248 314
249 // Optimize the case where there are no parameters passed.
250 if (args->length() == 1) {
251 return array->Initialize(JSArray::kPreallocatedArrayElements);
252 }
253
254 // Set length and elements on the array.
255 int number_of_elements = args->length() - 1;
256 MaybeObject* maybe_object =
257 array->EnsureCanContainElements(args, 1, number_of_elements,
258 ALLOW_CONVERTED_DOUBLE_ELEMENTS);
259 if (maybe_object->IsFailure()) return maybe_object;
260
261 // Allocate an appropriately typed elements array.
262 MaybeObject* maybe_elms;
263 ElementsKind elements_kind = array->GetElementsKind();
264 if (IsFastDoubleElementsKind(elements_kind)) {
265 maybe_elms = heap->AllocateUninitializedFixedDoubleArray(
266 number_of_elements);
267 } else {
268 maybe_elms = heap->AllocateFixedArrayWithHoles(number_of_elements);
269 }
270 FixedArrayBase* elms;
271 if (!maybe_elms->To(&elms)) return maybe_elms;
272
273 // Fill in the content
274 switch (array->GetElementsKind()) {
275 case FAST_HOLEY_SMI_ELEMENTS:
276 case FAST_SMI_ELEMENTS: {
277 FixedArray* smi_elms = FixedArray::cast(elms);
278 for (int index = 0; index < number_of_elements; index++) {
279 smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER);
280 }
281 break;
282 }
283 case FAST_HOLEY_ELEMENTS:
284 case FAST_ELEMENTS: {
285 AssertNoAllocation no_gc;
286 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
287 FixedArray* object_elms = FixedArray::cast(elms);
288 for (int index = 0; index < number_of_elements; index++) {
289 object_elms->set(index, (*args)[index+1], mode);
290 }
291 break;
292 }
293 case FAST_HOLEY_DOUBLE_ELEMENTS:
294 case FAST_DOUBLE_ELEMENTS: {
295 FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms);
296 for (int index = 0; index < number_of_elements; index++) {
297 double_elms->set(index, (*args)[index+1]->Number());
298 }
299 break;
300 }
301 default:
302 UNREACHABLE();
303 break;
304 }
305
306 array->set_elements(elms);
307 array->set_length(Smi::FromInt(number_of_elements));
308 return array; 315 return array;
309 } 316 }
310 317
311 318
312 BUILTIN(InternalArrayCodeGeneric) { 319 BUILTIN(InternalArrayCodeGeneric) {
313 return ArrayCodeGenericCommon( 320 return ArrayCodeGenericCommon(
314 &args, 321 &args,
315 isolate, 322 isolate,
316 isolate->context()->native_context()->internal_array_function()); 323 isolate->context()->native_context()->internal_array_function());
317 } 324 }
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 // boxing doubles may cause incremental marking. 1176 // boxing doubles may cause incremental marking.
1170 ArrayStorageAllocationMode mode = 1177 ArrayStorageAllocationMode mode =
1171 has_double && IsFastObjectElementsKind(elements_kind) 1178 has_double && IsFastObjectElementsKind(elements_kind)
1172 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS; 1179 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
1173 JSArray* result_array; 1180 JSArray* result_array;
1174 // Allocate result. 1181 // Allocate result.
1175 MaybeObject* maybe_array = 1182 MaybeObject* maybe_array =
1176 heap->AllocateJSArrayAndStorage(elements_kind, 1183 heap->AllocateJSArrayAndStorage(elements_kind,
1177 result_len, 1184 result_len,
1178 result_len, 1185 result_len,
1186 DONT_TRACK_ALLOCATION_SITE,
1187 NULL,
1179 mode); 1188 mode);
1180 if (!maybe_array->To(&result_array)) return maybe_array; 1189 if (!maybe_array->To(&result_array)) return maybe_array;
1181 if (result_len == 0) return result_array; 1190 if (result_len == 0) return result_array;
1182 1191
1183 int j = 0; 1192 int j = 0;
1184 FixedArrayBase* storage = result_array->elements(); 1193 FixedArrayBase* storage = result_array->elements();
1185 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); 1194 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
1186 for (int i = 0; i < n_arguments; i++) { 1195 for (int i = 0; i < n_arguments; i++) {
1187 JSArray* array = JSArray::cast(args[i]); 1196 JSArray* array = JSArray::cast(args[i]);
1188 int len = Smi::cast(array->length())->value(); 1197 int len = Smi::cast(array->length())->value();
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 return Handle<Code>(code_address); \ 1884 return Handle<Code>(code_address); \
1876 } 1885 }
1877 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1886 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1878 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1887 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1879 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1888 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1880 #undef DEFINE_BUILTIN_ACCESSOR_C 1889 #undef DEFINE_BUILTIN_ACCESSOR_C
1881 #undef DEFINE_BUILTIN_ACCESSOR_A 1890 #undef DEFINE_BUILTIN_ACCESSOR_A
1882 1891
1883 1892
1884 } } // namespace v8::internal 1893 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/code-stubs.h » ('j') | src/code-stubs.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698