| OLD | NEW |
| 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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 Handle<JSFunction> function = args.at<JSFunction>(1); | 196 Handle<JSFunction> function = args.at<JSFunction>(1); |
| 197 Handle<Object> type_info = args.at<Object>(2); | 197 Handle<Object> type_info = args.at<Object>(2); |
| 198 | 198 |
| 199 JSArray* array = NULL; | 199 JSArray* array = NULL; |
| 200 bool holey = false; | 200 bool holey = false; |
| 201 if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) { | 201 if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) { |
| 202 int value = Smi::cast((*caller_args)[0])->value(); | 202 int value = Smi::cast((*caller_args)[0])->value(); |
| 203 holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray); | 203 holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray); |
| 204 } | 204 } |
| 205 | 205 |
| 206 // Allocate the initial map if absent. | 206 ASSERT(function->has_initial_map()); |
| 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 } | |
| 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(); | 207 ElementsKind kind = function->initial_map()->elements_kind(); |
| 218 if (holey) { | 208 if (holey) { |
| 219 kind = GetHoleyElementsKind(kind); | 209 kind = GetHoleyElementsKind(kind); |
| 220 } | 210 } |
| 221 | 211 |
| 222 MaybeObject* maybe_array; | 212 MaybeObject* maybe_array; |
| 223 if (*type_info != isolate->heap()->undefined_value()) { | 213 if (*type_info != isolate->heap()->undefined_value()) { |
| 224 ASSERT(type_info->IsJSGlobalPropertyCell()); | |
| 225 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info); | 214 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info); |
| 226 if (cell->value()->IsSmi()) { | 215 if (cell->value()->IsSmi()) { |
| 227 Smi* smi = Smi::cast(cell->value()); | 216 Smi* smi = Smi::cast(cell->value()); |
| 228 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); | 217 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); |
| 229 if (holey) { | 218 if (holey && !IsFastHoleyElementsKind(to_kind)) { |
| 230 to_kind = GetHoleyElementsKind(to_kind); | 219 to_kind = GetHoleyElementsKind(to_kind); |
| 220 // Update the allocation site info to reflect the advice alteration. |
| 221 cell->set_value(Smi::FromInt(to_kind)); |
| 231 } | 222 } |
| 232 | 223 |
| 233 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 224 AllocationSiteMode mode = AllocationSiteInfo::GetMode(to_kind); |
| 234 maybe_array = isolate->heap()->AllocateEmptyJSArray(to_kind); | 225 maybe_array = isolate->heap()->AllocateEmptyJSArray(kind, |
| 235 } else { | 226 mode, |
| 236 AllocationSiteMode mode = AllocationSiteInfo::GetMode(kind); | 227 &type_info); |
| 237 maybe_array = isolate->heap()->AllocateEmptyJSArray(kind, | |
| 238 mode, | |
| 239 &type_info); | |
| 240 } | |
| 241 if (!maybe_array->To(&array)) return maybe_array; | 228 if (!maybe_array->To(&array)) return maybe_array; |
| 242 } | 229 } |
| 243 } | 230 } |
| 244 | 231 |
| 245 if (array == NULL) { | 232 if (array == NULL) { |
| 246 maybe_array = isolate->heap()->AllocateEmptyJSArray(kind); | 233 maybe_array = isolate->heap()->AllocateEmptyJSArray(kind); |
| 247 if (!maybe_array->To(&array)) return maybe_array; | 234 if (!maybe_array->To(&array)) return maybe_array; |
| 248 } | 235 } |
| 249 | 236 |
| 250 maybe_array = ArrayConstructInitializeElements(array, caller_args); | 237 maybe_array = ArrayConstructInitializeElements(array, caller_args); |
| 251 if (maybe_array->IsFailure()) return maybe_array; | 238 if (maybe_array->IsFailure()) return maybe_array; |
| 252 return array; | 239 return array; |
| 253 } | 240 } |
| 254 | 241 |
| 255 | 242 |
| 256 static MaybeObject* ArrayCodeGenericCommon(Arguments* args, | 243 static MaybeObject* ArrayCodeGenericCommon(Arguments* args, |
| 257 Isolate* isolate, | 244 Isolate* isolate, |
| 258 JSFunction* constructor) { | 245 JSFunction* constructor) { |
| 259 ASSERT(args->length() >= 1); | 246 ASSERT(args->length() >= 1); |
| 260 Heap* heap = isolate->heap(); | 247 Heap* heap = isolate->heap(); |
| 261 isolate->counters()->array_function_runtime()->Increment(); | 248 isolate->counters()->array_function_runtime()->Increment(); |
| 262 | 249 |
| 263 JSArray* array; | 250 JSArray* array; |
| 264 if (CalledAsConstructor(isolate)) { | 251 if (CalledAsConstructor(isolate)) { |
| 265 array = JSArray::cast((*args)[0]); | 252 array = JSArray::cast((*args)[0]); |
| 266 // Initialize elements and length in case later allocations fail so that the | 253 // Initialize elements and length in case later allocations fail so that the |
| 267 // array object is initialized in a valid state. | 254 // array object is initialized in a valid state. |
| 268 array->set_length(Smi::FromInt(0)); | 255 MaybeObject* maybe_array = array->Initialize(0); |
| 269 array->set_elements(heap->empty_fixed_array()); | 256 if (maybe_array->IsFailure()) return maybe_array; |
| 257 |
| 270 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(array); | 258 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(array); |
| 271 ElementsKind to_kind = array->GetElementsKind(); | 259 ElementsKind to_kind = array->GetElementsKind(); |
| 272 if (info != NULL && info->GetElementsKindPayload(&to_kind)) { | 260 if (info != NULL && info->GetElementsKindPayload(&to_kind)) { |
| 273 if (IsMoreGeneralElementsKindTransition(array->GetElementsKind(), | 261 if (IsMoreGeneralElementsKindTransition(array->GetElementsKind(), |
| 274 to_kind)) { | 262 to_kind)) { |
| 275 // We have advice that we should change the elements kind | 263 // We have advice that we should change the elements kind |
| 276 if (FLAG_trace_track_allocation_sites) { | 264 if (FLAG_trace_track_allocation_sites) { |
| 277 PrintF("AllocationSiteInfo: pre-transitioning array %p(%s->%s)\n", | 265 PrintF("AllocationSiteInfo: pre-transitioning array %p(%s->%s)\n", |
| 278 reinterpret_cast<void*>(array), | 266 reinterpret_cast<void*>(array), |
| 279 ElementsKindToString(array->GetElementsKind()), | 267 ElementsKindToString(array->GetElementsKind()), |
| 280 ElementsKindToString(to_kind)); | 268 ElementsKindToString(to_kind)); |
| 281 } | 269 } |
| 282 | 270 |
| 283 MaybeObject* maybe_array = | 271 maybe_array = array->TransitionElementsKind(to_kind); |
| 284 array->TransitionElementsKind(to_kind); | |
| 285 if (maybe_array->IsFailure()) return maybe_array; | 272 if (maybe_array->IsFailure()) return maybe_array; |
| 286 } | 273 } |
| 287 } | 274 } |
| 288 | 275 |
| 289 if (!FLAG_smi_only_arrays) { | 276 if (!FLAG_smi_only_arrays) { |
| 290 Context* native_context = isolate->context()->native_context(); | 277 Context* native_context = isolate->context()->native_context(); |
| 291 if (array->GetElementsKind() == GetInitialFastElementsKind() && | 278 if (array->GetElementsKind() == GetInitialFastElementsKind() && |
| 292 !native_context->js_array_maps()->IsUndefined()) { | 279 !native_context->js_array_maps()->IsUndefined()) { |
| 293 FixedArray* map_array = | 280 FixedArray* map_array = |
| 294 FixedArray::cast(native_context->js_array_maps()); | 281 FixedArray::cast(native_context->js_array_maps()); |
| 295 array->set_map(Map::cast(map_array-> | 282 array->set_map(Map::cast(map_array-> |
| 296 get(TERMINAL_FAST_ELEMENTS_KIND))); | 283 get(TERMINAL_FAST_ELEMENTS_KIND))); |
| 297 } | 284 } |
| 298 } | 285 } |
| 299 } else { | 286 } else { |
| 300 // Allocate the JS Array | 287 // Allocate the JS Array |
| 301 // TODO(mvstanton): There is no allocation info advice for this case. | |
| 302 // How to address? | |
| 303 MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); | 288 MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); |
| 304 if (!maybe_obj->To(&array)) return maybe_obj; | 289 if (!maybe_obj->To(&array)) return maybe_obj; |
| 305 } | 290 } |
| 306 | 291 |
| 307 Arguments adjusted_arguments(args->length() - 1, args->arguments() - 1); | 292 Arguments adjusted_arguments(args->length() - 1, args->arguments() - 1); |
| 308 ASSERT(adjusted_arguments.length() < 1 || | 293 ASSERT(adjusted_arguments.length() < 1 || |
| 309 adjusted_arguments[0] == (*args)[1]); | 294 adjusted_arguments[0] == (*args)[1]); |
| 310 { MaybeObject* maybe_obj = ArrayConstructInitializeElements(array, | 295 MaybeObject* maybe_obj = ArrayConstructInitializeElements(array, |
| 311 &adjusted_arguments); | 296 &adjusted_arguments); |
| 312 if (!maybe_obj->To(&array)) return maybe_obj; | 297 if (!maybe_obj->To(&array)) return maybe_obj; |
| 313 } | |
| 314 | 298 |
| 315 return array; | 299 return array; |
| 316 } | 300 } |
| 317 | 301 |
| 318 | 302 |
| 319 BUILTIN(InternalArrayCodeGeneric) { | 303 BUILTIN(InternalArrayCodeGeneric) { |
| 320 return ArrayCodeGenericCommon( | 304 return ArrayCodeGenericCommon( |
| 321 &args, | 305 &args, |
| 322 isolate, | 306 isolate, |
| 323 isolate->context()->native_context()->internal_array_function()); | 307 isolate->context()->native_context()->internal_array_function()); |
| (...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 return Handle<Code>(code_address); \ | 1868 return Handle<Code>(code_address); \ |
| 1885 } | 1869 } |
| 1886 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1870 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
| 1887 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1871 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1888 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1872 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1889 #undef DEFINE_BUILTIN_ACCESSOR_C | 1873 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 1890 #undef DEFINE_BUILTIN_ACCESSOR_A | 1874 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 1891 | 1875 |
| 1892 | 1876 |
| 1893 } } // namespace v8::internal | 1877 } } // namespace v8::internal |
| OLD | NEW |