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

Side by Side Diff: src/runtime.cc

Issue 7901016: Basic support for tracking smi-only arrays on ia32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: deactivate by default Created 9 years, 3 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 if (!maybe_result->ToObject(&result)) return maybe_result; 170 if (!maybe_result->ToObject(&result)) return maybe_result;
171 } 171 }
172 } 172 }
173 } 173 }
174 } 174 }
175 175
176 // Deep copy local elements. 176 // Deep copy local elements.
177 // Pixel elements cannot be created using an object literal. 177 // Pixel elements cannot be created using an object literal.
178 ASSERT(!copy->HasExternalArrayElements()); 178 ASSERT(!copy->HasExternalArrayElements());
179 switch (copy->GetElementsKind()) { 179 switch (copy->GetElementsKind()) {
180 case FAST_SMI_ONLY_ELEMENTS:
180 case FAST_ELEMENTS: { 181 case FAST_ELEMENTS: {
181 FixedArray* elements = FixedArray::cast(copy->elements()); 182 FixedArray* elements = FixedArray::cast(copy->elements());
182 if (elements->map() == heap->fixed_cow_array_map()) { 183 if (elements->map() == heap->fixed_cow_array_map()) {
183 isolate->counters()->cow_arrays_created_runtime()->Increment(); 184 isolate->counters()->cow_arrays_created_runtime()->Increment();
184 #ifdef DEBUG 185 #ifdef DEBUG
185 for (int i = 0; i < elements->length(); i++) { 186 for (int i = 0; i < elements->length(); i++) {
186 ASSERT(!elements->get(i)->IsJSObject()); 187 ASSERT(!elements->get(i)->IsJSObject());
187 } 188 }
188 #endif 189 #endif
189 } else { 190 } else {
190 for (int i = 0; i < elements->length(); i++) { 191 for (int i = 0; i < elements->length(); i++) {
191 Object* value = elements->get(i); 192 Object* value = elements->get(i);
193 ASSERT(value->IsSmi() ||
194 value->IsTheHole() ||
195 (copy->GetElementsKind() == FAST_ELEMENTS));
192 if (value->IsJSObject()) { 196 if (value->IsJSObject()) {
193 JSObject* js_object = JSObject::cast(value); 197 JSObject* js_object = JSObject::cast(value);
194 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, 198 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
195 js_object); 199 js_object);
196 if (!maybe_result->ToObject(&result)) return maybe_result; 200 if (!maybe_result->ToObject(&result)) return maybe_result;
197 } 201 }
198 elements->set(i, result); 202 elements->set(i, result);
199 } 203 }
200 } 204 }
201 } 205 }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 Handle<JSFunction> constructor( 429 Handle<JSFunction> constructor(
426 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); 430 JSFunction::GlobalContextFromLiterals(*literals)->array_function());
427 Handle<Object> object = isolate->factory()->NewJSObject(constructor); 431 Handle<Object> object = isolate->factory()->NewJSObject(constructor);
428 432
429 const bool is_cow = 433 const bool is_cow =
430 (elements->map() == isolate->heap()->fixed_cow_array_map()); 434 (elements->map() == isolate->heap()->fixed_cow_array_map());
431 Handle<FixedArray> copied_elements = 435 Handle<FixedArray> copied_elements =
432 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); 436 is_cow ? elements : isolate->factory()->CopyFixedArray(elements);
433 437
434 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); 438 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
439 bool has_non_constant_subexpression = true;
435 if (is_cow) { 440 if (is_cow) {
436 #ifdef DEBUG 441 #ifdef DEBUG
437 // Copy-on-write arrays must be shallow (and simple). 442 // Copy-on-write arrays must be shallow (and simple).
438 for (int i = 0; i < content->length(); i++) { 443 for (int i = 0; i < content->length(); i++) {
439 ASSERT(!content->get(i)->IsFixedArray()); 444 ASSERT(!content->get(i)->IsFixedArray());
440 } 445 }
441 #endif 446 #endif
442 } else { 447 } else {
443 for (int i = 0; i < content->length(); i++) { 448 for (int i = 0; i < content->length(); i++) {
444 if (content->get(i)->IsFixedArray()) { 449 if (content->get(i)->IsFixedArray()) {
445 // The value contains the constant_properties of a 450 // The value contains the constant_properties of a
446 // simple object or array literal. 451 // simple object or array literal.
447 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); 452 Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
448 Handle<Object> result = 453 Handle<Object> result =
449 CreateLiteralBoilerplate(isolate, literals, fa); 454 CreateLiteralBoilerplate(isolate, literals, fa);
450 if (result.is_null()) return result; 455 if (result.is_null()) return result;
451 content->set(i, *result); 456 content->set(i, *result);
457 } else {
458 has_non_constant_subexpression = true;
452 } 459 }
453 } 460 }
454 } 461 }
455 462
456 // Set the elements. 463 // Set the elements.
457 Handle<JSArray>::cast(object)->SetContent(*content); 464 Handle<JSArray> js_object(Handle<JSArray>::cast(object));
465 isolate->factory()->SetContent(js_object, content);
466
467 // To simplify the code that fills in non-constant expressions, assume that
468 // any array literal that has non-constant expressions has non smi elements.
469 if (has_non_constant_subexpression && js_object->HasFastSmiOnlyElements()) {
470 isolate->factory()->EnsureCanContainNonSmiElements(js_object);
471 }
458 return object; 472 return object;
459 } 473 }
460 474
461 475
462 static Handle<Object> CreateLiteralBoilerplate( 476 static Handle<Object> CreateLiteralBoilerplate(
463 Isolate* isolate, 477 Isolate* isolate,
464 Handle<FixedArray> literals, 478 Handle<FixedArray> literals,
465 Handle<FixedArray> array) { 479 Handle<FixedArray> array) {
466 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 480 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
467 const bool kHasNoFunctionLiteral = false; 481 const bool kHasNoFunctionLiteral = false;
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after
2280 NoHandleAllocation ha; 2294 NoHandleAllocation ha;
2281 ASSERT(args.length() == 1); 2295 ASSERT(args.length() == 1);
2282 return CharFromCode(isolate, args[0]); 2296 return CharFromCode(isolate, args[0]);
2283 } 2297 }
2284 2298
2285 2299
2286 class FixedArrayBuilder { 2300 class FixedArrayBuilder {
2287 public: 2301 public:
2288 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) 2302 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
2289 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), 2303 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
2290 length_(0) { 2304 length_(0),
2305 has_non_smi_elements_(false) {
2291 // Require a non-zero initial size. Ensures that doubling the size to 2306 // Require a non-zero initial size. Ensures that doubling the size to
2292 // extend the array will work. 2307 // extend the array will work.
2293 ASSERT(initial_capacity > 0); 2308 ASSERT(initial_capacity > 0);
2294 } 2309 }
2295 2310
2296 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) 2311 explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
2297 : array_(backing_store), 2312 : array_(backing_store),
2298 length_(0) { 2313 length_(0),
2314 has_non_smi_elements_(false) {
2299 // Require a non-zero initial size. Ensures that doubling the size to 2315 // Require a non-zero initial size. Ensures that doubling the size to
2300 // extend the array will work. 2316 // extend the array will work.
2301 ASSERT(backing_store->length() > 0); 2317 ASSERT(backing_store->length() > 0);
2302 } 2318 }
2303 2319
2304 bool HasCapacity(int elements) { 2320 bool HasCapacity(int elements) {
2305 int length = array_->length(); 2321 int length = array_->length();
2306 int required_length = length_ + elements; 2322 int required_length = length_ + elements;
2307 return (length >= required_length); 2323 return (length >= required_length);
2308 } 2324 }
2309 2325
2310 void EnsureCapacity(int elements) { 2326 void EnsureCapacity(int elements) {
2311 int length = array_->length(); 2327 int length = array_->length();
2312 int required_length = length_ + elements; 2328 int required_length = length_ + elements;
2313 if (length < required_length) { 2329 if (length < required_length) {
2314 int new_length = length; 2330 int new_length = length;
2315 do { 2331 do {
2316 new_length *= 2; 2332 new_length *= 2;
2317 } while (new_length < required_length); 2333 } while (new_length < required_length);
2318 Handle<FixedArray> extended_array = 2334 Handle<FixedArray> extended_array =
2319 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); 2335 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
2320 array_->CopyTo(0, *extended_array, 0, length_); 2336 array_->CopyTo(0, *extended_array, 0, length_);
2321 array_ = extended_array; 2337 array_ = extended_array;
2322 } 2338 }
2323 } 2339 }
2324 2340
2325 void Add(Object* value) { 2341 void Add(Object* value) {
2342 ASSERT(!value->IsSmi());
2326 ASSERT(length_ < capacity()); 2343 ASSERT(length_ < capacity());
2327 array_->set(length_, value); 2344 array_->set(length_, value);
2328 length_++; 2345 length_++;
2346 has_non_smi_elements_ = true;
2329 } 2347 }
2330 2348
2331 void Add(Smi* value) { 2349 void Add(Smi* value) {
2350 ASSERT(value->IsSmi());
2332 ASSERT(length_ < capacity()); 2351 ASSERT(length_ < capacity());
2333 array_->set(length_, value); 2352 array_->set(length_, value);
2334 length_++; 2353 length_++;
2335 } 2354 }
2336 2355
2337 Handle<FixedArray> array() { 2356 Handle<FixedArray> array() {
2338 return array_; 2357 return array_;
2339 } 2358 }
2340 2359
2341 int length() { 2360 int length() {
2342 return length_; 2361 return length_;
2343 } 2362 }
2344 2363
2345 int capacity() { 2364 int capacity() {
2346 return array_->length(); 2365 return array_->length();
2347 } 2366 }
2348 2367
2349 Handle<JSArray> ToJSArray() { 2368 Handle<JSArray> ToJSArray() {
2350 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); 2369 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_);
2351 result_array->set_length(Smi::FromInt(length_)); 2370 result_array->set_length(Smi::FromInt(length_));
2352 return result_array; 2371 return result_array;
2353 } 2372 }
2354 2373
2355 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { 2374 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
2356 target_array->set_elements(*array_); 2375 FACTORY->SetContent(target_array, array_);
2357 target_array->set_length(Smi::FromInt(length_)); 2376 target_array->set_length(Smi::FromInt(length_));
2358 return target_array; 2377 return target_array;
2359 } 2378 }
2360 2379
2361 private: 2380 private:
2362 Handle<FixedArray> array_; 2381 Handle<FixedArray> array_;
2363 int length_; 2382 int length_;
2383 bool has_non_smi_elements_;
2364 }; 2384 };
2365 2385
2366 2386
2367 // Forward declarations. 2387 // Forward declarations.
2368 const int kStringBuilderConcatHelperLengthBits = 11; 2388 const int kStringBuilderConcatHelperLengthBits = 11;
2369 const int kStringBuilderConcatHelperPositionBits = 19; 2389 const int kStringBuilderConcatHelperPositionBits = 19;
2370 2390
2371 template <typename schar> 2391 template <typename schar>
2372 static inline void StringBuilderConcatHelper(String*, 2392 static inline void StringBuilderConcatHelper(String*,
2373 schar*, 2393 schar*,
(...skipping 3809 matching lines...) Expand 10 before | Expand all | Expand 10 after
6183 if (static_cast<uint32_t>(indices.length()) < limit) { 6203 if (static_cast<uint32_t>(indices.length()) < limit) {
6184 indices.Add(subject_length); 6204 indices.Add(subject_length);
6185 } 6205 }
6186 6206
6187 // The list indices now contains the end of each part to create. 6207 // The list indices now contains the end of each part to create.
6188 6208
6189 // Create JSArray of substrings separated by separator. 6209 // Create JSArray of substrings separated by separator.
6190 int part_count = indices.length(); 6210 int part_count = indices.length();
6191 6211
6192 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); 6212 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6213 MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements();
6214 if (maybe_result->IsFailure()) return maybe_result;
6193 result->set_length(Smi::FromInt(part_count)); 6215 result->set_length(Smi::FromInt(part_count));
6194 6216
6195 ASSERT(result->HasFastElements()); 6217 ASSERT(result->HasFastElements());
6196 6218
6197 if (part_count == 1 && indices.at(0) == subject_length) { 6219 if (part_count == 1 && indices.at(0) == subject_length) {
6198 FixedArray::cast(result->elements())->set(0, *subject); 6220 FixedArray::cast(result->elements())->set(0, *subject);
6199 return *result; 6221 return *result;
6200 } 6222 }
6201 6223
6202 Handle<FixedArray> elements(FixedArray::cast(result->elements())); 6224 Handle<FixedArray> elements(FixedArray::cast(result->elements()));
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
6557 if (!args[1]->IsSmi()) { 6579 if (!args[1]->IsSmi()) {
6558 isolate->context()->mark_out_of_memory(); 6580 isolate->context()->mark_out_of_memory();
6559 return Failure::OutOfMemoryException(); 6581 return Failure::OutOfMemoryException();
6560 } 6582 }
6561 int array_length = args.smi_at(1); 6583 int array_length = args.smi_at(1);
6562 CONVERT_CHECKED(String, special, args[2]); 6584 CONVERT_CHECKED(String, special, args[2]);
6563 6585
6564 // This assumption is used by the slice encoding in one or two smis. 6586 // This assumption is used by the slice encoding in one or two smis.
6565 ASSERT(Smi::kMaxValue >= String::kMaxLength); 6587 ASSERT(Smi::kMaxValue >= String::kMaxLength);
6566 6588
6589 MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements();
6590 if (maybe_result->IsFailure()) return maybe_result;
6591
6567 int special_length = special->length(); 6592 int special_length = special->length();
6568 if (!array->HasFastElements()) { 6593 if (!array->HasFastElements()) {
6569 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6594 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6570 } 6595 }
6571 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6596 FixedArray* fixed_array = FixedArray::cast(array->elements());
6572 if (fixed_array->length() < array_length) { 6597 if (fixed_array->length() < array_length) {
6573 array_length = fixed_array->length(); 6598 array_length = fixed_array->length();
6574 } 6599 }
6575 6600
6576 if (array_length == 0) { 6601 if (array_length == 0) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
6784 } 6809 }
6785 } 6810 }
6786 ASSERT(cursor <= buffer.length()); 6811 ASSERT(cursor <= buffer.length());
6787 } 6812 }
6788 6813
6789 6814
6790 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { 6815 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
6791 NoHandleAllocation ha; 6816 NoHandleAllocation ha;
6792 ASSERT(args.length() == 3); 6817 ASSERT(args.length() == 3);
6793 CONVERT_CHECKED(JSArray, elements_array, args[0]); 6818 CONVERT_CHECKED(JSArray, elements_array, args[0]);
6794 RUNTIME_ASSERT(elements_array->HasFastElements()); 6819 RUNTIME_ASSERT(elements_array->HasFastElements() ||
6820 elements_array->HasFastSmiOnlyElements());
6795 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); 6821 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
6796 CONVERT_CHECKED(String, separator, args[2]); 6822 CONVERT_CHECKED(String, separator, args[2]);
6797 // elements_array is fast-mode JSarray of alternating positions 6823 // elements_array is fast-mode JSarray of alternating positions
6798 // (increasing order) and strings. 6824 // (increasing order) and strings.
6799 // array_length is length of original array (used to add separators); 6825 // array_length is length of original array (used to add separators);
6800 // separator is string to put between elements. Assumed to be non-empty. 6826 // separator is string to put between elements. Assumed to be non-empty.
6801 6827
6802 // Find total length of join result. 6828 // Find total length of join result.
6803 int string_length = 0; 6829 int string_length = 0;
6804 bool is_ascii = true; 6830 bool is_ascii = true;
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after
9040 9066
9041 9067
9042 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { 9068 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
9043 HandleScope scope(isolate); 9069 HandleScope scope(isolate);
9044 ASSERT(args.length() == 2); 9070 ASSERT(args.length() == 2);
9045 9071
9046 CONVERT_ARG_CHECKED(String, str, 0); 9072 CONVERT_ARG_CHECKED(String, str, 0);
9047 FlattenString(str); 9073 FlattenString(str);
9048 9074
9049 CONVERT_ARG_CHECKED(JSArray, output, 1); 9075 CONVERT_ARG_CHECKED(JSArray, output, 1);
9076
9077 MaybeObject* maybe_result_array =
9078 output->EnsureCanContainNonSmiElements();
9079 if (maybe_result_array->IsFailure()) return maybe_result_array;
9050 RUNTIME_ASSERT(output->HasFastElements()); 9080 RUNTIME_ASSERT(output->HasFastElements());
9051 9081
9052 AssertNoAllocation no_allocation; 9082 AssertNoAllocation no_allocation;
9053 9083
9054 FixedArray* output_array = FixedArray::cast(output->elements()); 9084 FixedArray* output_array = FixedArray::cast(output->elements());
9055 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); 9085 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9056 bool result; 9086 bool result;
9057 String::FlatContent str_content = str->GetFlatContent(); 9087 String::FlatContent str_content = str->GetFlatContent();
9058 if (str_content.IsAscii()) { 9088 if (str_content.IsAscii()) {
9059 result = DateParser::Parse(str_content.ToAsciiVector(), 9089 result = DateParser::Parse(str_content.ToAsciiVector(),
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
9340 } 9370 }
9341 9371
9342 9372
9343 // Push an object unto an array of objects if it is not already in the 9373 // Push an object unto an array of objects if it is not already in the
9344 // array. Returns true if the element was pushed on the stack and 9374 // array. Returns true if the element was pushed on the stack and
9345 // false otherwise. 9375 // false otherwise.
9346 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { 9376 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
9347 ASSERT(args.length() == 2); 9377 ASSERT(args.length() == 2);
9348 CONVERT_CHECKED(JSArray, array, args[0]); 9378 CONVERT_CHECKED(JSArray, array, args[0]);
9349 CONVERT_CHECKED(JSObject, element, args[1]); 9379 CONVERT_CHECKED(JSObject, element, args[1]);
9350 RUNTIME_ASSERT(array->HasFastElements()); 9380 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
9351 int length = Smi::cast(array->length())->value(); 9381 int length = Smi::cast(array->length())->value();
9352 FixedArray* elements = FixedArray::cast(array->elements()); 9382 FixedArray* elements = FixedArray::cast(array->elements());
9353 for (int i = 0; i < length; i++) { 9383 for (int i = 0; i < length; i++) {
9354 if (elements->get(i) == element) return isolate->heap()->false_value(); 9384 if (elements->get(i) == element) return isolate->heap()->false_value();
9355 } 9385 }
9356 Object* obj; 9386 Object* obj;
9357 // Strict not needed. Used for cycle detection in Array join implementation. 9387 // Strict not needed. Used for cycle detection in Array join implementation.
9358 { MaybeObject* maybe_obj = 9388 { MaybeObject* maybe_obj =
9359 array->SetFastElement(length, element, kNonStrictMode, true); 9389 array->SetFastElement(length, element, kNonStrictMode, true);
9360 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9390 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
9571 uint32_t b = *bp; 9601 uint32_t b = *bp;
9572 return (a == b) ? 0 : (a < b) ? -1 : 1; 9602 return (a == b) ? 0 : (a < b) ? -1 : 1;
9573 } 9603 }
9574 9604
9575 9605
9576 static void CollectElementIndices(Handle<JSObject> object, 9606 static void CollectElementIndices(Handle<JSObject> object,
9577 uint32_t range, 9607 uint32_t range,
9578 List<uint32_t>* indices) { 9608 List<uint32_t>* indices) {
9579 ElementsKind kind = object->GetElementsKind(); 9609 ElementsKind kind = object->GetElementsKind();
9580 switch (kind) { 9610 switch (kind) {
9611 case FAST_SMI_ONLY_ELEMENTS:
9581 case FAST_ELEMENTS: { 9612 case FAST_ELEMENTS: {
9582 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 9613 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
9583 uint32_t length = static_cast<uint32_t>(elements->length()); 9614 uint32_t length = static_cast<uint32_t>(elements->length());
9584 if (range < length) length = range; 9615 if (range < length) length = range;
9585 for (uint32_t i = 0; i < length; i++) { 9616 for (uint32_t i = 0; i < length; i++) {
9586 if (!elements->get(i)->IsTheHole()) { 9617 if (!elements->get(i)->IsTheHole()) {
9587 indices->Add(i); 9618 indices->Add(i);
9588 } 9619 }
9589 } 9620 }
9590 break; 9621 break;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
9690 * with the element index and the element's value. 9721 * with the element index and the element's value.
9691 * Afterwards it increments the base-index of the visitor by the array 9722 * Afterwards it increments the base-index of the visitor by the array
9692 * length. 9723 * length.
9693 * Returns false if any access threw an exception, otherwise true. 9724 * Returns false if any access threw an exception, otherwise true.
9694 */ 9725 */
9695 static bool IterateElements(Isolate* isolate, 9726 static bool IterateElements(Isolate* isolate,
9696 Handle<JSArray> receiver, 9727 Handle<JSArray> receiver,
9697 ArrayConcatVisitor* visitor) { 9728 ArrayConcatVisitor* visitor) {
9698 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); 9729 uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
9699 switch (receiver->GetElementsKind()) { 9730 switch (receiver->GetElementsKind()) {
9731 case FAST_SMI_ONLY_ELEMENTS:
9700 case FAST_ELEMENTS: { 9732 case FAST_ELEMENTS: {
9701 // Run through the elements FixedArray and use HasElement and GetElement 9733 // Run through the elements FixedArray and use HasElement and GetElement
9702 // to check the prototype for missing elements. 9734 // to check the prototype for missing elements.
9703 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 9735 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
9704 int fast_length = static_cast<int>(length); 9736 int fast_length = static_cast<int>(length);
9705 ASSERT(fast_length <= elements->length()); 9737 ASSERT(fast_length <= elements->length());
9706 for (int j = 0; j < fast_length; j++) { 9738 for (int j = 0; j < fast_length; j++) {
9707 HandleScope loop_scope(isolate); 9739 HandleScope loop_scope(isolate);
9708 Handle<Object> element_value(elements->get(j), isolate); 9740 Handle<Object> element_value(elements->get(j), isolate);
9709 if (!element_value->IsTheHole()) { 9741 if (!element_value->IsTheHole()) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
10013 for (int i = 0; i < keys_length; i++) { 10045 for (int i = 0; i < keys_length; i++) {
10014 Object* key = keys->get(i); 10046 Object* key = keys->get(i);
10015 uint32_t index = 0; 10047 uint32_t index = 0;
10016 if (!key->ToArrayIndex(&index) || index >= length) { 10048 if (!key->ToArrayIndex(&index) || index >= length) {
10017 // Zap invalid keys. 10049 // Zap invalid keys.
10018 keys->set_undefined(i); 10050 keys->set_undefined(i);
10019 } 10051 }
10020 } 10052 }
10021 return *isolate->factory()->NewJSArrayWithElements(keys); 10053 return *isolate->factory()->NewJSArrayWithElements(keys);
10022 } else { 10054 } else {
10023 ASSERT(array->HasFastElements() || array->HasFastDoubleElements()); 10055 ASSERT(array->HasFastElements() ||
10056 array->HasFastSmiOnlyElements() ||
10057 array->HasFastDoubleElements());
10024 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); 10058 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
10025 // -1 means start of array. 10059 // -1 means start of array.
10026 single_interval->set(0, Smi::FromInt(-1)); 10060 single_interval->set(0, Smi::FromInt(-1));
10027 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); 10061 FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
10028 uint32_t actual_length = 10062 uint32_t actual_length =
10029 static_cast<uint32_t>(elements->length()); 10063 static_cast<uint32_t>(elements->length());
10030 uint32_t min_length = actual_length < length ? actual_length : length; 10064 uint32_t min_length = actual_length < length ? actual_length : length;
10031 Handle<Object> length_object = 10065 Handle<Object> length_object =
10032 isolate->factory()->NewNumber(static_cast<double>(min_length)); 10066 isolate->factory()->NewNumber(static_cast<double>(min_length));
10033 single_interval->set(1, *length_object); 10067 single_interval->set(1, *length_object);
(...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after
11915 // instances->set(i, *GetScriptWrapper(script)) 11949 // instances->set(i, *GetScriptWrapper(script))
11916 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might 11950 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
11917 // already have deferenced the instances handle. 11951 // already have deferenced the instances handle.
11918 Handle<JSValue> wrapper = GetScriptWrapper(script); 11952 Handle<JSValue> wrapper = GetScriptWrapper(script);
11919 instances->set(i, *wrapper); 11953 instances->set(i, *wrapper);
11920 } 11954 }
11921 11955
11922 // Return result as a JS array. 11956 // Return result as a JS array.
11923 Handle<JSObject> result = 11957 Handle<JSObject> result =
11924 isolate->factory()->NewJSObject(isolate->array_function()); 11958 isolate->factory()->NewJSObject(isolate->array_function());
11925 Handle<JSArray>::cast(result)->SetContent(*instances); 11959 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
11926 return *result; 11960 return *result;
11927 } 11961 }
11928 11962
11929 11963
11930 // Helper function used by Runtime_DebugReferencedBy below. 11964 // Helper function used by Runtime_DebugReferencedBy below.
11931 static int DebugReferencedBy(JSObject* target, 11965 static int DebugReferencedBy(JSObject* target,
11932 Object* instance_filter, int max_references, 11966 Object* instance_filter, int max_references,
11933 FixedArray* instances, int instances_size, 11967 FixedArray* instances, int instances_size,
11934 JSFunction* arguments_function) { 11968 JSFunction* arguments_function) {
11935 NoHandleAllocation ha; 11969 NoHandleAllocation ha;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
12032 if (!maybe_object->ToObject(&object)) return maybe_object; 12066 if (!maybe_object->ToObject(&object)) return maybe_object;
12033 } 12067 }
12034 FixedArray* instances = FixedArray::cast(object); 12068 FixedArray* instances = FixedArray::cast(object);
12035 12069
12036 // Fill the referencing objects. 12070 // Fill the referencing objects.
12037 count = DebugReferencedBy(target, instance_filter, max_references, 12071 count = DebugReferencedBy(target, instance_filter, max_references,
12038 instances, count, arguments_function); 12072 instances, count, arguments_function);
12039 12073
12040 // Return result as JS array. 12074 // Return result as JS array.
12041 Object* result; 12075 Object* result;
12042 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( 12076 MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
12043 isolate->context()->global_context()->array_function()); 12077 isolate->context()->global_context()->array_function());
12044 if (!maybe_result->ToObject(&result)) return maybe_result; 12078 if (!maybe_result->ToObject(&result)) return maybe_result;
12045 } 12079 return JSArray::cast(result)->SetContent(instances);
12046 JSArray::cast(result)->SetContent(instances);
12047 return result;
12048 } 12080 }
12049 12081
12050 12082
12051 // Helper function used by Runtime_DebugConstructedBy below. 12083 // Helper function used by Runtime_DebugConstructedBy below.
12052 static int DebugConstructedBy(JSFunction* constructor, int max_references, 12084 static int DebugConstructedBy(JSFunction* constructor, int max_references,
12053 FixedArray* instances, int instances_size) { 12085 FixedArray* instances, int instances_size) {
12054 AssertNoAllocation no_alloc; 12086 AssertNoAllocation no_alloc;
12055 12087
12056 // Iterate the heap. 12088 // Iterate the heap.
12057 int count = 0; 12089 int count = 0;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
12105 12137
12106 // Fill the referencing objects. 12138 // Fill the referencing objects.
12107 count = DebugConstructedBy(constructor, max_references, instances, count); 12139 count = DebugConstructedBy(constructor, max_references, instances, count);
12108 12140
12109 // Return result as JS array. 12141 // Return result as JS array.
12110 Object* result; 12142 Object* result;
12111 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( 12143 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
12112 isolate->context()->global_context()->array_function()); 12144 isolate->context()->global_context()->array_function());
12113 if (!maybe_result->ToObject(&result)) return maybe_result; 12145 if (!maybe_result->ToObject(&result)) return maybe_result;
12114 } 12146 }
12115 JSArray::cast(result)->SetContent(instances); 12147 return JSArray::cast(result)->SetContent(instances);
12116 return result;
12117 } 12148 }
12118 12149
12119 12150
12120 // Find the effective prototype object as returned by __proto__. 12151 // Find the effective prototype object as returned by __proto__.
12121 // args[0]: the object to find the prototype for. 12152 // args[0]: the object to find the prototype for.
12122 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { 12153 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
12123 ASSERT(args.length() == 1); 12154 ASSERT(args.length() == 1);
12124 12155
12125 CONVERT_CHECKED(JSObject, obj, args[0]); 12156 CONVERT_CHECKED(JSObject, obj, args[0]);
12126 12157
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after
13061 return NULL; 13092 return NULL;
13062 } 13093 }
13063 13094
13064 13095
13065 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ 13096 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
13066 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ 13097 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
13067 CONVERT_CHECKED(JSObject, obj, args[0]); \ 13098 CONVERT_CHECKED(JSObject, obj, args[0]); \
13068 return isolate->heap()->ToBoolean(obj->Has##Name()); \ 13099 return isolate->heap()->ToBoolean(obj->Has##Name()); \
13069 } 13100 }
13070 13101
13102 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements)
13071 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) 13103 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
13072 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) 13104 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
13073 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) 13105 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
13074 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) 13106 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
13075 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) 13107 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
13076 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) 13108 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
13077 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) 13109 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
13078 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) 13110 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
13079 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) 13111 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
13080 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) 13112 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
13157 } else { 13189 } else {
13158 // Handle last resort GC and make sure to allow future allocations 13190 // Handle last resort GC and make sure to allow future allocations
13159 // to grow the heap without causing GCs (if possible). 13191 // to grow the heap without causing GCs (if possible).
13160 isolate->counters()->gc_last_resort_from_js()->Increment(); 13192 isolate->counters()->gc_last_resort_from_js()->Increment();
13161 isolate->heap()->CollectAllGarbage(false); 13193 isolate->heap()->CollectAllGarbage(false);
13162 } 13194 }
13163 } 13195 }
13164 13196
13165 13197
13166 } } // namespace v8::internal 13198 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698