OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 JSObject* jsObject = JSObject::cast(value); | 148 JSObject* jsObject = JSObject::cast(value); |
149 result = DeepCopyBoilerplate(jsObject); | 149 result = DeepCopyBoilerplate(jsObject); |
150 if (result->IsFailure()) return result; | 150 if (result->IsFailure()) return result; |
151 result = copy->SetProperty(keyString, result, NONE); | 151 result = copy->SetProperty(keyString, result, NONE); |
152 if (result->IsFailure()) return result; | 152 if (result->IsFailure()) return result; |
153 } | 153 } |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 // Deep copy local elements. | 157 // Deep copy local elements. |
158 if (copy->HasFastElements()) { | 158 // Pixel elements cannot be created using an object literal. |
159 FixedArray* elements = copy->elements(); | 159 ASSERT(!copy->HasPixelElements()); |
160 WriteBarrierMode mode = elements->GetWriteBarrierMode(); | 160 switch (copy->GetElementsKind()) { |
161 for (int i = 0; i < elements->length(); i++) { | 161 case JSObject::FAST_ELEMENTS: { |
162 Object* value = elements->get(i); | 162 FixedArray* elements = FixedArray::cast(copy->elements()); |
163 if (value->IsJSObject()) { | 163 WriteBarrierMode mode = elements->GetWriteBarrierMode(); |
164 JSObject* jsObject = JSObject::cast(value); | 164 for (int i = 0; i < elements->length(); i++) { |
165 result = DeepCopyBoilerplate(jsObject); | 165 Object* value = elements->get(i); |
166 if (result->IsFailure()) return result; | |
167 elements->set(i, result, mode); | |
168 } | |
169 } | |
170 } else { | |
171 NumberDictionary* element_dictionary = copy->element_dictionary(); | |
172 int capacity = element_dictionary->Capacity(); | |
173 for (int i = 0; i < capacity; i++) { | |
174 Object* k = element_dictionary->KeyAt(i); | |
175 if (element_dictionary->IsKey(k)) { | |
176 Object* value = element_dictionary->ValueAt(i); | |
177 if (value->IsJSObject()) { | 166 if (value->IsJSObject()) { |
178 JSObject* jsObject = JSObject::cast(value); | 167 JSObject* jsObject = JSObject::cast(value); |
179 result = DeepCopyBoilerplate(jsObject); | 168 result = DeepCopyBoilerplate(jsObject); |
180 if (result->IsFailure()) return result; | 169 if (result->IsFailure()) return result; |
181 element_dictionary->ValueAtPut(i, result); | 170 elements->set(i, result, mode); |
182 } | 171 } |
183 } | 172 } |
| 173 break; |
184 } | 174 } |
| 175 case JSObject::DICTIONARY_ELEMENTS: { |
| 176 NumberDictionary* element_dictionary = copy->element_dictionary(); |
| 177 int capacity = element_dictionary->Capacity(); |
| 178 for (int i = 0; i < capacity; i++) { |
| 179 Object* k = element_dictionary->KeyAt(i); |
| 180 if (element_dictionary->IsKey(k)) { |
| 181 Object* value = element_dictionary->ValueAt(i); |
| 182 if (value->IsJSObject()) { |
| 183 JSObject* jsObject = JSObject::cast(value); |
| 184 result = DeepCopyBoilerplate(jsObject); |
| 185 if (result->IsFailure()) return result; |
| 186 element_dictionary->ValueAtPut(i, result); |
| 187 } |
| 188 } |
| 189 } |
| 190 break; |
| 191 } |
| 192 default: |
| 193 UNREACHABLE(); |
| 194 break; |
185 } | 195 } |
186 return copy; | 196 return copy; |
187 } | 197 } |
188 | 198 |
189 | 199 |
190 static Object* Runtime_CloneLiteralBoilerplate(Arguments args) { | 200 static Object* Runtime_CloneLiteralBoilerplate(Arguments args) { |
191 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 201 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
192 return DeepCopyBoilerplate(boilerplate); | 202 return DeepCopyBoilerplate(boilerplate); |
193 } | 203 } |
194 | 204 |
(...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 break; | 1640 break; |
1631 case SUBJECT_SUFFIX: { | 1641 case SUBJECT_SUFFIX: { |
1632 int subject_length = part.data; | 1642 int subject_length = part.data; |
1633 if (match_to < subject_length) { | 1643 if (match_to < subject_length) { |
1634 builder->AddSubjectSlice(match_to, subject_length); | 1644 builder->AddSubjectSlice(match_to, subject_length); |
1635 } | 1645 } |
1636 break; | 1646 break; |
1637 } | 1647 } |
1638 case SUBJECT_CAPTURE: { | 1648 case SUBJECT_CAPTURE: { |
1639 int capture = part.data; | 1649 int capture = part.data; |
1640 FixedArray* match_info = last_match_info->elements(); | 1650 FixedArray* match_info = FixedArray::cast(last_match_info->elements()); |
1641 int from = RegExpImpl::GetCapture(match_info, capture * 2); | 1651 int from = RegExpImpl::GetCapture(match_info, capture * 2); |
1642 int to = RegExpImpl::GetCapture(match_info, capture * 2 + 1); | 1652 int to = RegExpImpl::GetCapture(match_info, capture * 2 + 1); |
1643 if (from >= 0 && to > from) { | 1653 if (from >= 0 && to > from) { |
1644 builder->AddSubjectSlice(from, to); | 1654 builder->AddSubjectSlice(from, to); |
1645 } | 1655 } |
1646 break; | 1656 break; |
1647 } | 1657 } |
1648 case REPLACEMENT_SUBSTRING: | 1658 case REPLACEMENT_SUBSTRING: |
1649 case REPLACEMENT_STRING: | 1659 case REPLACEMENT_STRING: |
1650 builder->AddString(replacement_substrings_[part.data]); | 1660 builder->AddString(replacement_substrings_[part.data]); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 do { | 1720 do { |
1711 ASSERT(last_match_info_handle->HasFastElements()); | 1721 ASSERT(last_match_info_handle->HasFastElements()); |
1712 // Increase the capacity of the builder before entering local handle-scope, | 1722 // Increase the capacity of the builder before entering local handle-scope, |
1713 // so its internal buffer can safely allocate a new handle if it grows. | 1723 // so its internal buffer can safely allocate a new handle if it grows. |
1714 builder.EnsureCapacity(parts_added_per_loop); | 1724 builder.EnsureCapacity(parts_added_per_loop); |
1715 | 1725 |
1716 HandleScope loop_scope; | 1726 HandleScope loop_scope; |
1717 int start, end; | 1727 int start, end; |
1718 { | 1728 { |
1719 AssertNoAllocation match_info_array_is_not_in_a_handle; | 1729 AssertNoAllocation match_info_array_is_not_in_a_handle; |
1720 FixedArray* match_info_array = last_match_info_handle->elements(); | 1730 FixedArray* match_info_array = |
| 1731 FixedArray::cast(last_match_info_handle->elements()); |
1721 | 1732 |
1722 ASSERT_EQ(capture_count * 2 + 2, | 1733 ASSERT_EQ(capture_count * 2 + 2, |
1723 RegExpImpl::GetLastCaptureCount(match_info_array)); | 1734 RegExpImpl::GetLastCaptureCount(match_info_array)); |
1724 start = RegExpImpl::GetCapture(match_info_array, 0); | 1735 start = RegExpImpl::GetCapture(match_info_array, 0); |
1725 end = RegExpImpl::GetCapture(match_info_array, 1); | 1736 end = RegExpImpl::GetCapture(match_info_array, 1); |
1726 } | 1737 } |
1727 | 1738 |
1728 if (prev < start) { | 1739 if (prev < start) { |
1729 builder.AddSubjectSlice(prev, start); | 1740 builder.AddSubjectSlice(prev, start); |
1730 } | 1741 } |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 } | 2349 } |
2339 int length = subject->length(); | 2350 int length = subject->length(); |
2340 | 2351 |
2341 CompilationZoneScope zone_space(DELETE_ON_EXIT); | 2352 CompilationZoneScope zone_space(DELETE_ON_EXIT); |
2342 ZoneList<int> offsets(8); | 2353 ZoneList<int> offsets(8); |
2343 do { | 2354 do { |
2344 int start; | 2355 int start; |
2345 int end; | 2356 int end; |
2346 { | 2357 { |
2347 AssertNoAllocation no_alloc; | 2358 AssertNoAllocation no_alloc; |
2348 FixedArray* elements = regexp_info->elements(); | 2359 FixedArray* elements = FixedArray::cast(regexp_info->elements()); |
2349 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); | 2360 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); |
2350 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); | 2361 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); |
2351 } | 2362 } |
2352 offsets.Add(start); | 2363 offsets.Add(start); |
2353 offsets.Add(end); | 2364 offsets.Add(end); |
2354 int index = start < end ? end : end + 1; | 2365 int index = start < end ? end : end + 1; |
2355 if (index > length) break; | 2366 if (index > length) break; |
2356 match = RegExpImpl::Exec(regexp, subject, index, regexp_info); | 2367 match = RegExpImpl::Exec(regexp, subject, index, regexp_info); |
2357 if (match.is_null()) { | 2368 if (match.is_null()) { |
2358 return Failure::Exception(); | 2369 return Failure::Exception(); |
(...skipping 2519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4878 ASSERT(args.length() == 2); | 4889 ASSERT(args.length() == 2); |
4879 | 4890 |
4880 CONVERT_ARG_CHECKED(String, str, 0); | 4891 CONVERT_ARG_CHECKED(String, str, 0); |
4881 FlattenString(str); | 4892 FlattenString(str); |
4882 | 4893 |
4883 CONVERT_ARG_CHECKED(JSArray, output, 1); | 4894 CONVERT_ARG_CHECKED(JSArray, output, 1); |
4884 RUNTIME_ASSERT(output->HasFastElements()); | 4895 RUNTIME_ASSERT(output->HasFastElements()); |
4885 | 4896 |
4886 AssertNoAllocation no_allocation; | 4897 AssertNoAllocation no_allocation; |
4887 | 4898 |
4888 FixedArray* output_array = output->elements(); | 4899 FixedArray* output_array = FixedArray::cast(output->elements()); |
4889 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 4900 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
4890 bool result; | 4901 bool result; |
4891 if (str->IsAsciiRepresentation()) { | 4902 if (str->IsAsciiRepresentation()) { |
4892 result = DateParser::Parse(str->ToAsciiVector(), output_array); | 4903 result = DateParser::Parse(str->ToAsciiVector(), output_array); |
4893 } else { | 4904 } else { |
4894 ASSERT(str->IsTwoByteRepresentation()); | 4905 ASSERT(str->IsTwoByteRepresentation()); |
4895 result = DateParser::Parse(str->ToUC16Vector(), output_array); | 4906 result = DateParser::Parse(str->ToUC16Vector(), output_array); |
4896 } | 4907 } |
4897 | 4908 |
4898 if (result) { | 4909 if (result) { |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5166 * If the third parameter, visitor, is not NULL, the visitor is called | 5177 * If the third parameter, visitor, is not NULL, the visitor is called |
5167 * with parameters, 'visitor_index_offset + element index' and the element. | 5178 * with parameters, 'visitor_index_offset + element index' and the element. |
5168 * | 5179 * |
5169 * It returns the number of visisted elements. | 5180 * It returns the number of visisted elements. |
5170 */ | 5181 */ |
5171 static uint32_t IterateElements(Handle<JSObject> receiver, | 5182 static uint32_t IterateElements(Handle<JSObject> receiver, |
5172 uint32_t range, | 5183 uint32_t range, |
5173 ArrayConcatVisitor* visitor) { | 5184 ArrayConcatVisitor* visitor) { |
5174 uint32_t num_of_elements = 0; | 5185 uint32_t num_of_elements = 0; |
5175 | 5186 |
5176 if (receiver->HasFastElements()) { | 5187 switch (receiver->GetElementsKind()) { |
5177 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 5188 case JSObject::FAST_ELEMENTS: { |
5178 uint32_t len = elements->length(); | 5189 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
5179 if (range < len) len = range; | 5190 uint32_t len = elements->length(); |
| 5191 if (range < len) { |
| 5192 len = range; |
| 5193 } |
5180 | 5194 |
5181 for (uint32_t j = 0; j < len; j++) { | 5195 for (uint32_t j = 0; j < len; j++) { |
5182 Handle<Object> e(elements->get(j)); | 5196 Handle<Object> e(elements->get(j)); |
5183 if (!e->IsTheHole()) { | 5197 if (!e->IsTheHole()) { |
5184 num_of_elements++; | |
5185 if (visitor) | |
5186 visitor->visit(j, e); | |
5187 } | |
5188 } | |
5189 | |
5190 } else { | |
5191 Handle<NumberDictionary> dict(receiver->element_dictionary()); | |
5192 uint32_t capacity = dict->Capacity(); | |
5193 for (uint32_t j = 0; j < capacity; j++) { | |
5194 Handle<Object> k(dict->KeyAt(j)); | |
5195 if (dict->IsKey(*k)) { | |
5196 ASSERT(k->IsNumber()); | |
5197 uint32_t index = static_cast<uint32_t>(k->Number()); | |
5198 if (index < range) { | |
5199 num_of_elements++; | 5198 num_of_elements++; |
5200 if (visitor) { | 5199 if (visitor) { |
5201 visitor->visit(index, | 5200 visitor->visit(j, e); |
5202 Handle<Object>(dict->ValueAt(j))); | |
5203 } | 5201 } |
5204 } | 5202 } |
5205 } | 5203 } |
| 5204 break; |
5206 } | 5205 } |
| 5206 case JSObject::PIXEL_ELEMENTS: { |
| 5207 Handle<PixelArray> pixels(PixelArray::cast(receiver->elements())); |
| 5208 uint32_t len = pixels->length(); |
| 5209 if (range < len) { |
| 5210 len = range; |
| 5211 } |
| 5212 |
| 5213 for (uint32_t j = 0; j < len; j++) { |
| 5214 num_of_elements++; |
| 5215 if (visitor != NULL) { |
| 5216 Handle<Smi> e(Smi::FromInt(pixels->get(j))); |
| 5217 visitor->visit(j, e); |
| 5218 } |
| 5219 } |
| 5220 break; |
| 5221 } |
| 5222 case JSObject::DICTIONARY_ELEMENTS: { |
| 5223 Handle<NumberDictionary> dict(receiver->element_dictionary()); |
| 5224 uint32_t capacity = dict->Capacity(); |
| 5225 for (uint32_t j = 0; j < capacity; j++) { |
| 5226 Handle<Object> k(dict->KeyAt(j)); |
| 5227 if (dict->IsKey(*k)) { |
| 5228 ASSERT(k->IsNumber()); |
| 5229 uint32_t index = static_cast<uint32_t>(k->Number()); |
| 5230 if (index < range) { |
| 5231 num_of_elements++; |
| 5232 if (visitor) { |
| 5233 visitor->visit(index, Handle<Object>(dict->ValueAt(j))); |
| 5234 } |
| 5235 } |
| 5236 } |
| 5237 } |
| 5238 break; |
| 5239 } |
| 5240 default: |
| 5241 UNREACHABLE(); |
| 5242 break; |
5207 } | 5243 } |
5208 | 5244 |
5209 return num_of_elements; | 5245 return num_of_elements; |
5210 } | 5246 } |
5211 | 5247 |
5212 | 5248 |
5213 /** | 5249 /** |
5214 * A helper function that visits elements of an Array object, and elements | 5250 * A helper function that visits elements of an Array object, and elements |
5215 * on its prototypes. | 5251 * on its prototypes. |
5216 * | 5252 * |
(...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7442 while (!iter.done() && frames_seen < limit) { | 7478 while (!iter.done() && frames_seen < limit) { |
7443 StackFrame* raw_frame = iter.frame(); | 7479 StackFrame* raw_frame = iter.frame(); |
7444 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { | 7480 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { |
7445 frames_seen++; | 7481 frames_seen++; |
7446 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 7482 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
7447 Object* recv = frame->receiver(); | 7483 Object* recv = frame->receiver(); |
7448 Object* fun = frame->function(); | 7484 Object* fun = frame->function(); |
7449 Address pc = frame->pc(); | 7485 Address pc = frame->pc(); |
7450 Address start = frame->code()->address(); | 7486 Address start = frame->code()->address(); |
7451 Smi* offset = Smi::FromInt(pc - start); | 7487 Smi* offset = Smi::FromInt(pc - start); |
7452 FixedArray* elements = result->elements(); | 7488 FixedArray* elements = FixedArray::cast(result->elements()); |
7453 if (cursor + 2 < elements->length()) { | 7489 if (cursor + 2 < elements->length()) { |
7454 elements->set(cursor++, recv); | 7490 elements->set(cursor++, recv); |
7455 elements->set(cursor++, fun); | 7491 elements->set(cursor++, fun); |
7456 elements->set(cursor++, offset, SKIP_WRITE_BARRIER); | 7492 elements->set(cursor++, offset, SKIP_WRITE_BARRIER); |
7457 } else { | 7493 } else { |
7458 HandleScope scope; | 7494 HandleScope scope; |
7459 Handle<Object> recv_handle(recv); | 7495 Handle<Object> recv_handle(recv); |
7460 Handle<Object> fun_handle(fun); | 7496 Handle<Object> fun_handle(fun); |
7461 SetElement(result, cursor++, recv_handle); | 7497 SetElement(result, cursor++, recv_handle); |
7462 SetElement(result, cursor++, fun_handle); | 7498 SetElement(result, cursor++, fun_handle); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7564 } else { | 7600 } else { |
7565 // Handle last resort GC and make sure to allow future allocations | 7601 // Handle last resort GC and make sure to allow future allocations |
7566 // to grow the heap without causing GCs (if possible). | 7602 // to grow the heap without causing GCs (if possible). |
7567 Counters::gc_last_resort_from_js.Increment(); | 7603 Counters::gc_last_resort_from_js.Increment(); |
7568 Heap::CollectAllGarbage(); | 7604 Heap::CollectAllGarbage(); |
7569 } | 7605 } |
7570 } | 7606 } |
7571 | 7607 |
7572 | 7608 |
7573 } } // namespace v8::internal | 7609 } } // namespace v8::internal |
OLD | NEW |