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

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: ready to land 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_smi = false;
435 if (is_cow) { 440 if (is_cow) {
436 #ifdef DEBUG
437 // Copy-on-write arrays must be shallow (and simple). 441 // Copy-on-write arrays must be shallow (and simple).
438 for (int i = 0; i < content->length(); i++) { 442 if (FLAG_smi_only_arrays) {
439 ASSERT(!content->get(i)->IsFixedArray()); 443 for (int i = 0; i < content->length(); i++) {
444 Object* current = content->get(i);
445 ASSERT(!current->IsFixedArray());
446 if (!current->IsSmi()) {
447 has_non_smi = true;
448 }
449 }
450 } else {
451 #if DEBUG
452 for (int i = 0; i < content->length(); i++) {
453 ASSERT(!content->get(i)->IsFixedArray());
454 }
455 #endif
440 } 456 }
441 #endif
442 } else { 457 } else {
443 for (int i = 0; i < content->length(); i++) { 458 for (int i = 0; i < content->length(); i++) {
444 if (content->get(i)->IsFixedArray()) { 459 Object* current = content->get(i);
460 if (current->IsFixedArray()) {
445 // The value contains the constant_properties of a 461 // The value contains the constant_properties of a
446 // simple object or array literal. 462 // simple object or array literal.
447 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); 463 Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
448 Handle<Object> result = 464 Handle<Object> result =
449 CreateLiteralBoilerplate(isolate, literals, fa); 465 CreateLiteralBoilerplate(isolate, literals, fa);
450 if (result.is_null()) return result; 466 if (result.is_null()) return result;
451 content->set(i, *result); 467 content->set(i, *result);
468 has_non_smi = true;
469 } else {
470 if (!current->IsSmi()) {
471 has_non_smi = true;
472 }
452 } 473 }
453 } 474 }
454 } 475 }
455 476
456 // Set the elements. 477 // Set the elements.
457 Handle<JSArray>::cast(object)->SetContent(*content); 478 Handle<JSArray> js_object(Handle<JSArray>::cast(object));
479 isolate->factory()->SetContent(js_object, content);
480
481 if (FLAG_smi_only_arrays) {
482 if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
483 isolate->factory()->EnsureCanContainNonSmiElements(js_object);
484 }
485 }
486
458 return object; 487 return object;
459 } 488 }
460 489
461 490
462 static Handle<Object> CreateLiteralBoilerplate( 491 static Handle<Object> CreateLiteralBoilerplate(
463 Isolate* isolate, 492 Isolate* isolate,
464 Handle<FixedArray> literals, 493 Handle<FixedArray> literals,
465 Handle<FixedArray> array) { 494 Handle<FixedArray> array) {
466 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 495 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
467 const bool kHasNoFunctionLiteral = false; 496 const bool kHasNoFunctionLiteral = false;
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 ASSERT(args.length() == 2); 1653 ASSERT(args.length() == 2);
1625 CONVERT_ARG_CHECKED(JSObject, object, 0); 1654 CONVERT_ARG_CHECKED(JSObject, object, 0);
1626 CONVERT_SMI_ARG_CHECKED(properties, 1); 1655 CONVERT_SMI_ARG_CHECKED(properties, 1);
1627 if (object->HasFastProperties()) { 1656 if (object->HasFastProperties()) {
1628 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); 1657 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1629 } 1658 }
1630 return *object; 1659 return *object;
1631 } 1660 }
1632 1661
1633 1662
1663 RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
1664 ASSERT(args.length() == 1);
1665 CONVERT_ARG_CHECKED(JSObject, object, 0);
1666 if (FLAG_smi_only_arrays && object->HasFastSmiOnlyElements()) {
1667 MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
1668 Map* map;
1669 if (!maybe_map->To<Map>(&map)) return maybe_map;
1670 object->set_map(Map::cast(map));
1671 }
1672 return *object;
1673 }
1674
1675
1634 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { 1676 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1635 HandleScope scope(isolate); 1677 HandleScope scope(isolate);
1636 ASSERT(args.length() == 4); 1678 ASSERT(args.length() == 4);
1637 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 1679 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
1638 CONVERT_ARG_CHECKED(String, subject, 1); 1680 CONVERT_ARG_CHECKED(String, subject, 1);
1639 // Due to the way the JS calls are constructed this must be less than the 1681 // Due to the way the JS calls are constructed this must be less than the
1640 // length of a string, i.e. it is always a Smi. We check anyway for security. 1682 // length of a string, i.e. it is always a Smi. We check anyway for security.
1641 CONVERT_SMI_ARG_CHECKED(index, 2); 1683 CONVERT_SMI_ARG_CHECKED(index, 2);
1642 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); 1684 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1643 RUNTIME_ASSERT(last_match_info->HasFastElements()); 1685 RUNTIME_ASSERT(last_match_info->HasFastElements());
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 NoHandleAllocation ha; 2249 NoHandleAllocation ha;
2208 ASSERT(args.length() == 1); 2250 ASSERT(args.length() == 1);
2209 return CharFromCode(isolate, args[0]); 2251 return CharFromCode(isolate, args[0]);
2210 } 2252 }
2211 2253
2212 2254
2213 class FixedArrayBuilder { 2255 class FixedArrayBuilder {
2214 public: 2256 public:
2215 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) 2257 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
2216 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), 2258 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
2217 length_(0) { 2259 length_(0),
2260 has_non_smi_elements_(false) {
2218 // Require a non-zero initial size. Ensures that doubling the size to 2261 // Require a non-zero initial size. Ensures that doubling the size to
2219 // extend the array will work. 2262 // extend the array will work.
2220 ASSERT(initial_capacity > 0); 2263 ASSERT(initial_capacity > 0);
2221 } 2264 }
2222 2265
2223 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) 2266 explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
2224 : array_(backing_store), 2267 : array_(backing_store),
2225 length_(0) { 2268 length_(0),
2269 has_non_smi_elements_(false) {
2226 // Require a non-zero initial size. Ensures that doubling the size to 2270 // Require a non-zero initial size. Ensures that doubling the size to
2227 // extend the array will work. 2271 // extend the array will work.
2228 ASSERT(backing_store->length() > 0); 2272 ASSERT(backing_store->length() > 0);
2229 } 2273 }
2230 2274
2231 bool HasCapacity(int elements) { 2275 bool HasCapacity(int elements) {
2232 int length = array_->length(); 2276 int length = array_->length();
2233 int required_length = length_ + elements; 2277 int required_length = length_ + elements;
2234 return (length >= required_length); 2278 return (length >= required_length);
2235 } 2279 }
2236 2280
2237 void EnsureCapacity(int elements) { 2281 void EnsureCapacity(int elements) {
2238 int length = array_->length(); 2282 int length = array_->length();
2239 int required_length = length_ + elements; 2283 int required_length = length_ + elements;
2240 if (length < required_length) { 2284 if (length < required_length) {
2241 int new_length = length; 2285 int new_length = length;
2242 do { 2286 do {
2243 new_length *= 2; 2287 new_length *= 2;
2244 } while (new_length < required_length); 2288 } while (new_length < required_length);
2245 Handle<FixedArray> extended_array = 2289 Handle<FixedArray> extended_array =
2246 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); 2290 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
2247 array_->CopyTo(0, *extended_array, 0, length_); 2291 array_->CopyTo(0, *extended_array, 0, length_);
2248 array_ = extended_array; 2292 array_ = extended_array;
2249 } 2293 }
2250 } 2294 }
2251 2295
2252 void Add(Object* value) { 2296 void Add(Object* value) {
2297 ASSERT(!value->IsSmi());
2253 ASSERT(length_ < capacity()); 2298 ASSERT(length_ < capacity());
2254 array_->set(length_, value); 2299 array_->set(length_, value);
2255 length_++; 2300 length_++;
2301 has_non_smi_elements_ = true;
2256 } 2302 }
2257 2303
2258 void Add(Smi* value) { 2304 void Add(Smi* value) {
2305 ASSERT(value->IsSmi());
2259 ASSERT(length_ < capacity()); 2306 ASSERT(length_ < capacity());
2260 array_->set(length_, value); 2307 array_->set(length_, value);
2261 length_++; 2308 length_++;
2262 } 2309 }
2263 2310
2264 Handle<FixedArray> array() { 2311 Handle<FixedArray> array() {
2265 return array_; 2312 return array_;
2266 } 2313 }
2267 2314
2268 int length() { 2315 int length() {
2269 return length_; 2316 return length_;
2270 } 2317 }
2271 2318
2272 int capacity() { 2319 int capacity() {
2273 return array_->length(); 2320 return array_->length();
2274 } 2321 }
2275 2322
2276 Handle<JSArray> ToJSArray() { 2323 Handle<JSArray> ToJSArray() {
2277 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); 2324 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_);
2278 result_array->set_length(Smi::FromInt(length_)); 2325 result_array->set_length(Smi::FromInt(length_));
2279 return result_array; 2326 return result_array;
2280 } 2327 }
2281 2328
2282 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { 2329 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
2283 target_array->set_elements(*array_); 2330 FACTORY->SetContent(target_array, array_);
2284 target_array->set_length(Smi::FromInt(length_)); 2331 target_array->set_length(Smi::FromInt(length_));
2285 return target_array; 2332 return target_array;
2286 } 2333 }
2287 2334
2288 private: 2335 private:
2289 Handle<FixedArray> array_; 2336 Handle<FixedArray> array_;
2290 int length_; 2337 int length_;
2338 bool has_non_smi_elements_;
2291 }; 2339 };
2292 2340
2293 2341
2294 // Forward declarations. 2342 // Forward declarations.
2295 const int kStringBuilderConcatHelperLengthBits = 11; 2343 const int kStringBuilderConcatHelperLengthBits = 11;
2296 const int kStringBuilderConcatHelperPositionBits = 19; 2344 const int kStringBuilderConcatHelperPositionBits = 19;
2297 2345
2298 template <typename schar> 2346 template <typename schar>
2299 static inline void StringBuilderConcatHelper(String*, 2347 static inline void StringBuilderConcatHelper(String*,
2300 schar*, 2348 schar*,
(...skipping 3813 matching lines...) Expand 10 before | Expand all | Expand 10 after
6114 if (static_cast<uint32_t>(indices.length()) < limit) { 6162 if (static_cast<uint32_t>(indices.length()) < limit) {
6115 indices.Add(subject_length); 6163 indices.Add(subject_length);
6116 } 6164 }
6117 6165
6118 // The list indices now contains the end of each part to create. 6166 // The list indices now contains the end of each part to create.
6119 6167
6120 // Create JSArray of substrings separated by separator. 6168 // Create JSArray of substrings separated by separator.
6121 int part_count = indices.length(); 6169 int part_count = indices.length();
6122 6170
6123 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); 6171 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6172 MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements();
6173 if (maybe_result->IsFailure()) return maybe_result;
6124 result->set_length(Smi::FromInt(part_count)); 6174 result->set_length(Smi::FromInt(part_count));
6125 6175
6126 ASSERT(result->HasFastElements()); 6176 ASSERT(result->HasFastElements());
6127 6177
6128 if (part_count == 1 && indices.at(0) == subject_length) { 6178 if (part_count == 1 && indices.at(0) == subject_length) {
6129 FixedArray::cast(result->elements())->set(0, *subject); 6179 FixedArray::cast(result->elements())->set(0, *subject);
6130 return *result; 6180 return *result;
6131 } 6181 }
6132 6182
6133 Handle<FixedArray> elements(FixedArray::cast(result->elements())); 6183 Handle<FixedArray> elements(FixedArray::cast(result->elements()));
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
6488 if (!args[1]->IsSmi()) { 6538 if (!args[1]->IsSmi()) {
6489 isolate->context()->mark_out_of_memory(); 6539 isolate->context()->mark_out_of_memory();
6490 return Failure::OutOfMemoryException(); 6540 return Failure::OutOfMemoryException();
6491 } 6541 }
6492 int array_length = args.smi_at(1); 6542 int array_length = args.smi_at(1);
6493 CONVERT_CHECKED(String, special, args[2]); 6543 CONVERT_CHECKED(String, special, args[2]);
6494 6544
6495 // This assumption is used by the slice encoding in one or two smis. 6545 // This assumption is used by the slice encoding in one or two smis.
6496 ASSERT(Smi::kMaxValue >= String::kMaxLength); 6546 ASSERT(Smi::kMaxValue >= String::kMaxLength);
6497 6547
6548 MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements();
6549 if (maybe_result->IsFailure()) return maybe_result;
6550
6498 int special_length = special->length(); 6551 int special_length = special->length();
6499 if (!array->HasFastElements()) { 6552 if (!array->HasFastElements()) {
6500 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6553 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6501 } 6554 }
6502 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6555 FixedArray* fixed_array = FixedArray::cast(array->elements());
6503 if (fixed_array->length() < array_length) { 6556 if (fixed_array->length() < array_length) {
6504 array_length = fixed_array->length(); 6557 array_length = fixed_array->length();
6505 } 6558 }
6506 6559
6507 if (array_length == 0) { 6560 if (array_length == 0) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
6715 } 6768 }
6716 } 6769 }
6717 ASSERT(cursor <= buffer.length()); 6770 ASSERT(cursor <= buffer.length());
6718 } 6771 }
6719 6772
6720 6773
6721 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { 6774 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
6722 NoHandleAllocation ha; 6775 NoHandleAllocation ha;
6723 ASSERT(args.length() == 3); 6776 ASSERT(args.length() == 3);
6724 CONVERT_CHECKED(JSArray, elements_array, args[0]); 6777 CONVERT_CHECKED(JSArray, elements_array, args[0]);
6725 RUNTIME_ASSERT(elements_array->HasFastElements()); 6778 RUNTIME_ASSERT(elements_array->HasFastElements() ||
6779 elements_array->HasFastSmiOnlyElements());
6726 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); 6780 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
6727 CONVERT_CHECKED(String, separator, args[2]); 6781 CONVERT_CHECKED(String, separator, args[2]);
6728 // elements_array is fast-mode JSarray of alternating positions 6782 // elements_array is fast-mode JSarray of alternating positions
6729 // (increasing order) and strings. 6783 // (increasing order) and strings.
6730 // array_length is length of original array (used to add separators); 6784 // array_length is length of original array (used to add separators);
6731 // separator is string to put between elements. Assumed to be non-empty. 6785 // separator is string to put between elements. Assumed to be non-empty.
6732 6786
6733 // Find total length of join result. 6787 // Find total length of join result.
6734 int string_length = 0; 6788 int string_length = 0;
6735 bool is_ascii = true; 6789 bool is_ascii = true;
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
7882 HandleScope scope(isolate); 7936 HandleScope scope(isolate);
7883 ASSERT(args.length() == 2); 7937 ASSERT(args.length() == 2);
7884 // First argument is a function to use as a constructor. 7938 // First argument is a function to use as a constructor.
7885 CONVERT_ARG_CHECKED(JSFunction, function, 0); 7939 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7886 7940
7887 // Second argument is either null or an array of bound arguments. 7941 // Second argument is either null or an array of bound arguments.
7888 Handle<FixedArray> bound_args; 7942 Handle<FixedArray> bound_args;
7889 int bound_argc = 0; 7943 int bound_argc = 0;
7890 if (!args[1]->IsNull()) { 7944 if (!args[1]->IsNull()) {
7891 CONVERT_ARG_CHECKED(JSArray, params, 1); 7945 CONVERT_ARG_CHECKED(JSArray, params, 1);
7892 RUNTIME_ASSERT(params->HasFastElements()); 7946 RUNTIME_ASSERT(params->HasFastTypeElements());
7893 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements())); 7947 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements()));
7894 bound_argc = Smi::cast(params->length())->value(); 7948 bound_argc = Smi::cast(params->length())->value();
7895 } 7949 }
7896 7950
7897 int total_argc = 0; 7951 int total_argc = 0;
7898 SmartArrayPointer<Object**> param_data = 7952 SmartArrayPointer<Object**> param_data =
7899 GetNonBoundArguments(bound_argc, &total_argc); 7953 GetNonBoundArguments(bound_argc, &total_argc);
7900 for (int i = 0; i < bound_argc; i++) { 7954 for (int i = 0; i < bound_argc; i++) {
7901 Handle<Object> val = Handle<Object>(bound_args->get(i)); 7955 Handle<Object> val = Handle<Object>(bound_args->get(i));
7902 param_data[i] = val.location(); 7956 param_data[i] = val.location();
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
8977 9031
8978 9032
8979 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { 9033 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
8980 HandleScope scope(isolate); 9034 HandleScope scope(isolate);
8981 ASSERT(args.length() == 2); 9035 ASSERT(args.length() == 2);
8982 9036
8983 CONVERT_ARG_CHECKED(String, str, 0); 9037 CONVERT_ARG_CHECKED(String, str, 0);
8984 FlattenString(str); 9038 FlattenString(str);
8985 9039
8986 CONVERT_ARG_CHECKED(JSArray, output, 1); 9040 CONVERT_ARG_CHECKED(JSArray, output, 1);
9041
9042 MaybeObject* maybe_result_array =
9043 output->EnsureCanContainNonSmiElements();
9044 if (maybe_result_array->IsFailure()) return maybe_result_array;
8987 RUNTIME_ASSERT(output->HasFastElements()); 9045 RUNTIME_ASSERT(output->HasFastElements());
8988 9046
8989 AssertNoAllocation no_allocation; 9047 AssertNoAllocation no_allocation;
8990 9048
8991 FixedArray* output_array = FixedArray::cast(output->elements()); 9049 FixedArray* output_array = FixedArray::cast(output->elements());
8992 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); 9050 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
8993 bool result; 9051 bool result;
8994 String::FlatContent str_content = str->GetFlatContent(); 9052 String::FlatContent str_content = str->GetFlatContent();
8995 if (str_content.IsAscii()) { 9053 if (str_content.IsAscii()) {
8996 result = DateParser::Parse(str_content.ToAsciiVector(), 9054 result = DateParser::Parse(str_content.ToAsciiVector(),
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
9280 } 9338 }
9281 9339
9282 9340
9283 // Push an object unto an array of objects if it is not already in the 9341 // Push an object unto an array of objects if it is not already in the
9284 // array. Returns true if the element was pushed on the stack and 9342 // array. Returns true if the element was pushed on the stack and
9285 // false otherwise. 9343 // false otherwise.
9286 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { 9344 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
9287 ASSERT(args.length() == 2); 9345 ASSERT(args.length() == 2);
9288 CONVERT_CHECKED(JSArray, array, args[0]); 9346 CONVERT_CHECKED(JSArray, array, args[0]);
9289 CONVERT_CHECKED(JSObject, element, args[1]); 9347 CONVERT_CHECKED(JSObject, element, args[1]);
9290 RUNTIME_ASSERT(array->HasFastElements()); 9348 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
9291 int length = Smi::cast(array->length())->value(); 9349 int length = Smi::cast(array->length())->value();
9292 FixedArray* elements = FixedArray::cast(array->elements()); 9350 FixedArray* elements = FixedArray::cast(array->elements());
9293 for (int i = 0; i < length; i++) { 9351 for (int i = 0; i < length; i++) {
9294 if (elements->get(i) == element) return isolate->heap()->false_value(); 9352 if (elements->get(i) == element) return isolate->heap()->false_value();
9295 } 9353 }
9296 Object* obj; 9354 Object* obj;
9297 // Strict not needed. Used for cycle detection in Array join implementation. 9355 // Strict not needed. Used for cycle detection in Array join implementation.
9298 { MaybeObject* maybe_obj = 9356 { MaybeObject* maybe_obj =
9299 array->SetFastElement(length, element, kNonStrictMode, true); 9357 array->SetFastElement(length, element, kNonStrictMode, true);
9300 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9358 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
9511 uint32_t b = *bp; 9569 uint32_t b = *bp;
9512 return (a == b) ? 0 : (a < b) ? -1 : 1; 9570 return (a == b) ? 0 : (a < b) ? -1 : 1;
9513 } 9571 }
9514 9572
9515 9573
9516 static void CollectElementIndices(Handle<JSObject> object, 9574 static void CollectElementIndices(Handle<JSObject> object,
9517 uint32_t range, 9575 uint32_t range,
9518 List<uint32_t>* indices) { 9576 List<uint32_t>* indices) {
9519 ElementsKind kind = object->GetElementsKind(); 9577 ElementsKind kind = object->GetElementsKind();
9520 switch (kind) { 9578 switch (kind) {
9579 case FAST_SMI_ONLY_ELEMENTS:
9521 case FAST_ELEMENTS: { 9580 case FAST_ELEMENTS: {
9522 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 9581 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
9523 uint32_t length = static_cast<uint32_t>(elements->length()); 9582 uint32_t length = static_cast<uint32_t>(elements->length());
9524 if (range < length) length = range; 9583 if (range < length) length = range;
9525 for (uint32_t i = 0; i < length; i++) { 9584 for (uint32_t i = 0; i < length; i++) {
9526 if (!elements->get(i)->IsTheHole()) { 9585 if (!elements->get(i)->IsTheHole()) {
9527 indices->Add(i); 9586 indices->Add(i);
9528 } 9587 }
9529 } 9588 }
9530 break; 9589 break;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
9630 * with the element index and the element's value. 9689 * with the element index and the element's value.
9631 * Afterwards it increments the base-index of the visitor by the array 9690 * Afterwards it increments the base-index of the visitor by the array
9632 * length. 9691 * length.
9633 * Returns false if any access threw an exception, otherwise true. 9692 * Returns false if any access threw an exception, otherwise true.
9634 */ 9693 */
9635 static bool IterateElements(Isolate* isolate, 9694 static bool IterateElements(Isolate* isolate,
9636 Handle<JSArray> receiver, 9695 Handle<JSArray> receiver,
9637 ArrayConcatVisitor* visitor) { 9696 ArrayConcatVisitor* visitor) {
9638 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); 9697 uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
9639 switch (receiver->GetElementsKind()) { 9698 switch (receiver->GetElementsKind()) {
9699 case FAST_SMI_ONLY_ELEMENTS:
9640 case FAST_ELEMENTS: { 9700 case FAST_ELEMENTS: {
9641 // Run through the elements FixedArray and use HasElement and GetElement 9701 // Run through the elements FixedArray and use HasElement and GetElement
9642 // to check the prototype for missing elements. 9702 // to check the prototype for missing elements.
9643 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 9703 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
9644 int fast_length = static_cast<int>(length); 9704 int fast_length = static_cast<int>(length);
9645 ASSERT(fast_length <= elements->length()); 9705 ASSERT(fast_length <= elements->length());
9646 for (int j = 0; j < fast_length; j++) { 9706 for (int j = 0; j < fast_length; j++) {
9647 HandleScope loop_scope(isolate); 9707 HandleScope loop_scope(isolate);
9648 Handle<Object> element_value(elements->get(j), isolate); 9708 Handle<Object> element_value(elements->get(j), isolate);
9649 if (!element_value->IsTheHole()) { 9709 if (!element_value->IsTheHole()) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
9953 for (int i = 0; i < keys_length; i++) { 10013 for (int i = 0; i < keys_length; i++) {
9954 Object* key = keys->get(i); 10014 Object* key = keys->get(i);
9955 uint32_t index = 0; 10015 uint32_t index = 0;
9956 if (!key->ToArrayIndex(&index) || index >= length) { 10016 if (!key->ToArrayIndex(&index) || index >= length) {
9957 // Zap invalid keys. 10017 // Zap invalid keys.
9958 keys->set_undefined(i); 10018 keys->set_undefined(i);
9959 } 10019 }
9960 } 10020 }
9961 return *isolate->factory()->NewJSArrayWithElements(keys); 10021 return *isolate->factory()->NewJSArrayWithElements(keys);
9962 } else { 10022 } else {
9963 ASSERT(array->HasFastElements() || array->HasFastDoubleElements()); 10023 ASSERT(array->HasFastElements() ||
10024 array->HasFastSmiOnlyElements() ||
10025 array->HasFastDoubleElements());
9964 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); 10026 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
9965 // -1 means start of array. 10027 // -1 means start of array.
9966 single_interval->set(0, Smi::FromInt(-1)); 10028 single_interval->set(0, Smi::FromInt(-1));
9967 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); 10029 FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
9968 uint32_t actual_length = 10030 uint32_t actual_length =
9969 static_cast<uint32_t>(elements->length()); 10031 static_cast<uint32_t>(elements->length());
9970 uint32_t min_length = actual_length < length ? actual_length : length; 10032 uint32_t min_length = actual_length < length ? actual_length : length;
9971 Handle<Object> length_object = 10033 Handle<Object> length_object =
9972 isolate->factory()->NewNumber(static_cast<double>(min_length)); 10034 isolate->factory()->NewNumber(static_cast<double>(min_length));
9973 single_interval->set(1, *length_object); 10035 single_interval->set(1, *length_object);
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after
11863 // instances->set(i, *GetScriptWrapper(script)) 11925 // instances->set(i, *GetScriptWrapper(script))
11864 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might 11926 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
11865 // already have deferenced the instances handle. 11927 // already have deferenced the instances handle.
11866 Handle<JSValue> wrapper = GetScriptWrapper(script); 11928 Handle<JSValue> wrapper = GetScriptWrapper(script);
11867 instances->set(i, *wrapper); 11929 instances->set(i, *wrapper);
11868 } 11930 }
11869 11931
11870 // Return result as a JS array. 11932 // Return result as a JS array.
11871 Handle<JSObject> result = 11933 Handle<JSObject> result =
11872 isolate->factory()->NewJSObject(isolate->array_function()); 11934 isolate->factory()->NewJSObject(isolate->array_function());
11873 Handle<JSArray>::cast(result)->SetContent(*instances); 11935 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
11874 return *result; 11936 return *result;
11875 } 11937 }
11876 11938
11877 11939
11878 // Helper function used by Runtime_DebugReferencedBy below. 11940 // Helper function used by Runtime_DebugReferencedBy below.
11879 static int DebugReferencedBy(HeapIterator* iterator, 11941 static int DebugReferencedBy(HeapIterator* iterator,
11880 JSObject* target, 11942 JSObject* target,
11881 Object* instance_filter, int max_references, 11943 Object* instance_filter, int max_references,
11882 FixedArray* instances, int instances_size, 11944 FixedArray* instances, int instances_size,
11883 JSFunction* arguments_function) { 11945 JSFunction* arguments_function) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
11991 // Fill the referencing objects. 12053 // Fill the referencing objects.
11992 // AllocateFixedArray above does not make the heap non-iterable. 12054 // AllocateFixedArray above does not make the heap non-iterable.
11993 ASSERT(HEAP->IsHeapIterable()); 12055 ASSERT(HEAP->IsHeapIterable());
11994 HeapIterator heap_iterator2; 12056 HeapIterator heap_iterator2;
11995 count = DebugReferencedBy(&heap_iterator2, 12057 count = DebugReferencedBy(&heap_iterator2,
11996 target, instance_filter, max_references, 12058 target, instance_filter, max_references,
11997 instances, count, arguments_function); 12059 instances, count, arguments_function);
11998 12060
11999 // Return result as JS array. 12061 // Return result as JS array.
12000 Object* result; 12062 Object* result;
12001 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( 12063 MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
12002 isolate->context()->global_context()->array_function()); 12064 isolate->context()->global_context()->array_function());
12003 if (!maybe_result->ToObject(&result)) return maybe_result; 12065 if (!maybe_result->ToObject(&result)) return maybe_result;
12004 } 12066 return JSArray::cast(result)->SetContent(instances);
12005 JSArray::cast(result)->SetContent(instances);
12006 return result;
12007 } 12067 }
12008 12068
12009 12069
12010 // Helper function used by Runtime_DebugConstructedBy below. 12070 // Helper function used by Runtime_DebugConstructedBy below.
12011 static int DebugConstructedBy(HeapIterator* iterator, 12071 static int DebugConstructedBy(HeapIterator* iterator,
12012 JSFunction* constructor, 12072 JSFunction* constructor,
12013 int max_references, 12073 int max_references,
12014 FixedArray* instances, 12074 FixedArray* instances,
12015 int instances_size) { 12075 int instances_size) {
12016 AssertNoAllocation no_alloc; 12076 AssertNoAllocation no_alloc;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
12077 max_references, 12137 max_references,
12078 instances, 12138 instances,
12079 count); 12139 count);
12080 12140
12081 // Return result as JS array. 12141 // Return result as JS array.
12082 Object* result; 12142 Object* result;
12083 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( 12143 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
12084 isolate->context()->global_context()->array_function()); 12144 isolate->context()->global_context()->array_function());
12085 if (!maybe_result->ToObject(&result)) return maybe_result; 12145 if (!maybe_result->ToObject(&result)) return maybe_result;
12086 } 12146 }
12087 JSArray::cast(result)->SetContent(instances); 12147 return JSArray::cast(result)->SetContent(instances);
12088 return result;
12089 } 12148 }
12090 12149
12091 12150
12092 // Find the effective prototype object as returned by __proto__. 12151 // Find the effective prototype object as returned by __proto__.
12093 // args[0]: the object to find the prototype for. 12152 // args[0]: the object to find the prototype for.
12094 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { 12153 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
12095 ASSERT(args.length() == 1); 12154 ASSERT(args.length() == 1);
12096 12155
12097 CONVERT_CHECKED(JSObject, obj, args[0]); 12156 CONVERT_CHECKED(JSObject, obj, args[0]);
12098 12157
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
13050 return NULL; 13109 return NULL;
13051 } 13110 }
13052 13111
13053 13112
13054 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ 13113 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
13055 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ 13114 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
13056 CONVERT_CHECKED(JSObject, obj, args[0]); \ 13115 CONVERT_CHECKED(JSObject, obj, args[0]); \
13057 return isolate->heap()->ToBoolean(obj->Has##Name()); \ 13116 return isolate->heap()->ToBoolean(obj->Has##Name()); \
13058 } 13117 }
13059 13118
13119 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements)
13060 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) 13120 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
13061 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) 13121 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
13062 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) 13122 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
13063 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) 13123 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
13064 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) 13124 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
13065 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) 13125 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
13066 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) 13126 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
13067 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) 13127 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
13068 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) 13128 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
13069 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) 13129 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
13149 } else { 13209 } else {
13150 // Handle last resort GC and make sure to allow future allocations 13210 // Handle last resort GC and make sure to allow future allocations
13151 // to grow the heap without causing GCs (if possible). 13211 // to grow the heap without causing GCs (if possible).
13152 isolate->counters()->gc_last_resort_from_js()->Increment(); 13212 isolate->counters()->gc_last_resort_from_js()->Increment();
13153 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 13213 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13154 } 13214 }
13155 } 13215 }
13156 13216
13157 13217
13158 } } // namespace v8::internal 13218 } } // namespace v8::internal
OLDNEW
« src/bootstrapper.cc ('K') | « src/runtime.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698