OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 namespace v8 { | 48 namespace v8 { |
49 namespace internal { | 49 namespace internal { |
50 | 50 |
51 // Getters and setters are stored in a fixed array property. These are | 51 // Getters and setters are stored in a fixed array property. These are |
52 // constants for their indices. | 52 // constants for their indices. |
53 const int kGetterIndex = 0; | 53 const int kGetterIndex = 0; |
54 const int kSetterIndex = 1; | 54 const int kSetterIndex = 1; |
55 | 55 |
56 | 56 |
57 MUST_USE_RESULT static Object* CreateJSValue(JSFunction* constructor, | 57 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, |
58 Object* value) { | 58 Object* value) { |
59 Object* result = Heap::AllocateJSObject(constructor); | 59 Object* result; |
60 if (result->IsFailure()) return result; | 60 { MaybeObject* maybe_result = Heap::AllocateJSObject(constructor); |
| 61 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 62 } |
61 JSValue::cast(result)->set_value(value); | 63 JSValue::cast(result)->set_value(value); |
62 return result; | 64 return result; |
63 } | 65 } |
64 | 66 |
65 | 67 |
66 Object* Object::ToObject(Context* global_context) { | 68 MaybeObject* Object::ToObject(Context* global_context) { |
67 if (IsNumber()) { | 69 if (IsNumber()) { |
68 return CreateJSValue(global_context->number_function(), this); | 70 return CreateJSValue(global_context->number_function(), this); |
69 } else if (IsBoolean()) { | 71 } else if (IsBoolean()) { |
70 return CreateJSValue(global_context->boolean_function(), this); | 72 return CreateJSValue(global_context->boolean_function(), this); |
71 } else if (IsString()) { | 73 } else if (IsString()) { |
72 return CreateJSValue(global_context->string_function(), this); | 74 return CreateJSValue(global_context->string_function(), this); |
73 } | 75 } |
74 ASSERT(IsJSObject()); | 76 ASSERT(IsJSObject()); |
75 return this; | 77 return this; |
76 } | 78 } |
77 | 79 |
78 | 80 |
79 Object* Object::ToObject() { | 81 MaybeObject* Object::ToObject() { |
80 Context* global_context = Top::context()->global_context(); | 82 Context* global_context = Top::context()->global_context(); |
81 if (IsJSObject()) { | 83 if (IsJSObject()) { |
82 return this; | 84 return this; |
83 } else if (IsNumber()) { | 85 } else if (IsNumber()) { |
84 return CreateJSValue(global_context->number_function(), this); | 86 return CreateJSValue(global_context->number_function(), this); |
85 } else if (IsBoolean()) { | 87 } else if (IsBoolean()) { |
86 return CreateJSValue(global_context->boolean_function(), this); | 88 return CreateJSValue(global_context->boolean_function(), this); |
87 } else if (IsString()) { | 89 } else if (IsString()) { |
88 return CreateJSValue(global_context->string_function(), this); | 90 return CreateJSValue(global_context->string_function(), this); |
89 } | 91 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 } else if (IsNumber()) { | 125 } else if (IsNumber()) { |
124 holder = global_context->number_function()->instance_prototype(); | 126 holder = global_context->number_function()->instance_prototype(); |
125 } else if (IsBoolean()) { | 127 } else if (IsBoolean()) { |
126 holder = global_context->boolean_function()->instance_prototype(); | 128 holder = global_context->boolean_function()->instance_prototype(); |
127 } | 129 } |
128 ASSERT(holder != NULL); // Cannot handle null or undefined. | 130 ASSERT(holder != NULL); // Cannot handle null or undefined. |
129 JSObject::cast(holder)->Lookup(name, result); | 131 JSObject::cast(holder)->Lookup(name, result); |
130 } | 132 } |
131 | 133 |
132 | 134 |
133 Object* Object::GetPropertyWithReceiver(Object* receiver, | 135 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
134 String* name, | 136 String* name, |
135 PropertyAttributes* attributes) { | 137 PropertyAttributes* attributes) { |
136 LookupResult result; | 138 LookupResult result; |
137 Lookup(name, &result); | 139 Lookup(name, &result); |
138 Object* value = GetProperty(receiver, &result, name, attributes); | 140 MaybeObject* value = GetProperty(receiver, &result, name, attributes); |
139 ASSERT(*attributes <= ABSENT); | 141 ASSERT(*attributes <= ABSENT); |
140 return value; | 142 return value; |
141 } | 143 } |
142 | 144 |
143 | 145 |
144 Object* Object::GetPropertyWithCallback(Object* receiver, | 146 MaybeObject* Object::GetPropertyWithCallback(Object* receiver, |
145 Object* structure, | 147 Object* structure, |
146 String* name, | 148 String* name, |
147 Object* holder) { | 149 Object* holder) { |
148 // To accommodate both the old and the new api we switch on the | 150 // To accommodate both the old and the new api we switch on the |
149 // data structure used to store the callbacks. Eventually proxy | 151 // data structure used to store the callbacks. Eventually proxy |
150 // callbacks should be phased out. | 152 // callbacks should be phased out. |
151 if (structure->IsProxy()) { | 153 if (structure->IsProxy()) { |
152 AccessorDescriptor* callback = | 154 AccessorDescriptor* callback = |
153 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); | 155 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); |
154 Object* value = (callback->getter)(receiver, callback->data); | 156 MaybeObject* value = (callback->getter)(receiver, callback->data); |
155 RETURN_IF_SCHEDULED_EXCEPTION(); | 157 RETURN_IF_SCHEDULED_EXCEPTION(); |
156 return value; | 158 return value; |
157 } | 159 } |
158 | 160 |
159 // api style callbacks. | 161 // api style callbacks. |
160 if (structure->IsAccessorInfo()) { | 162 if (structure->IsAccessorInfo()) { |
161 AccessorInfo* data = AccessorInfo::cast(structure); | 163 AccessorInfo* data = AccessorInfo::cast(structure); |
162 Object* fun_obj = data->getter(); | 164 Object* fun_obj = data->getter(); |
163 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 165 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
164 HandleScope scope; | 166 HandleScope scope; |
(...skipping 23 matching lines...) Expand all Loading... |
188 } | 190 } |
189 // Getter is not a function. | 191 // Getter is not a function. |
190 return Heap::undefined_value(); | 192 return Heap::undefined_value(); |
191 } | 193 } |
192 | 194 |
193 UNREACHABLE(); | 195 UNREACHABLE(); |
194 return NULL; | 196 return NULL; |
195 } | 197 } |
196 | 198 |
197 | 199 |
198 Object* Object::GetPropertyWithDefinedGetter(Object* receiver, | 200 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, |
199 JSFunction* getter) { | 201 JSFunction* getter) { |
200 HandleScope scope; | 202 HandleScope scope; |
201 Handle<JSFunction> fun(JSFunction::cast(getter)); | 203 Handle<JSFunction> fun(JSFunction::cast(getter)); |
202 Handle<Object> self(receiver); | 204 Handle<Object> self(receiver); |
203 #ifdef ENABLE_DEBUGGER_SUPPORT | 205 #ifdef ENABLE_DEBUGGER_SUPPORT |
204 // Handle stepping into a getter if step into is active. | 206 // Handle stepping into a getter if step into is active. |
205 if (Debug::StepInActive()) { | 207 if (Debug::StepInActive()) { |
206 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); | 208 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); |
207 } | 209 } |
208 #endif | 210 #endif |
209 bool has_pending_exception; | 211 bool has_pending_exception; |
210 Handle<Object> result = | 212 Handle<Object> result = |
211 Execution::Call(fun, self, 0, NULL, &has_pending_exception); | 213 Execution::Call(fun, self, 0, NULL, &has_pending_exception); |
212 // Check for pending exception and return the result. | 214 // Check for pending exception and return the result. |
213 if (has_pending_exception) return Failure::Exception(); | 215 if (has_pending_exception) return Failure::Exception(); |
214 return *result; | 216 return *result; |
215 } | 217 } |
216 | 218 |
217 | 219 |
218 // Only deal with CALLBACKS and INTERCEPTOR | 220 // Only deal with CALLBACKS and INTERCEPTOR |
219 Object* JSObject::GetPropertyWithFailedAccessCheck( | 221 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( |
220 Object* receiver, | 222 Object* receiver, |
221 LookupResult* result, | 223 LookupResult* result, |
222 String* name, | 224 String* name, |
223 PropertyAttributes* attributes) { | 225 PropertyAttributes* attributes) { |
224 if (result->IsProperty()) { | 226 if (result->IsProperty()) { |
225 switch (result->type()) { | 227 switch (result->type()) { |
226 case CALLBACKS: { | 228 case CALLBACKS: { |
227 // Only allow API accessors. | 229 // Only allow API accessors. |
228 Object* obj = result->GetCallbackObject(); | 230 Object* obj = result->GetCallbackObject(); |
229 if (obj->IsAccessorInfo()) { | 231 if (obj->IsAccessorInfo()) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 JSGlobalPropertyCell::cast( | 360 JSGlobalPropertyCell::cast( |
359 property_dictionary()->ValueAt(result->GetDictionaryEntry())); | 361 property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
360 cell->set_value(value); | 362 cell->set_value(value); |
361 } else { | 363 } else { |
362 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 364 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
363 } | 365 } |
364 return value; | 366 return value; |
365 } | 367 } |
366 | 368 |
367 | 369 |
368 Object* JSObject::SetNormalizedProperty(String* name, | 370 MaybeObject* JSObject::SetNormalizedProperty(String* name, |
369 Object* value, | 371 Object* value, |
370 PropertyDetails details) { | 372 PropertyDetails details) { |
371 ASSERT(!HasFastProperties()); | 373 ASSERT(!HasFastProperties()); |
372 int entry = property_dictionary()->FindEntry(name); | 374 int entry = property_dictionary()->FindEntry(name); |
373 if (entry == StringDictionary::kNotFound) { | 375 if (entry == StringDictionary::kNotFound) { |
374 Object* store_value = value; | 376 Object* store_value = value; |
375 if (IsGlobalObject()) { | 377 if (IsGlobalObject()) { |
376 store_value = Heap::AllocateJSGlobalPropertyCell(value); | 378 { MaybeObject* maybe_store_value = |
377 if (store_value->IsFailure()) return store_value; | 379 Heap::AllocateJSGlobalPropertyCell(value); |
| 380 if (!maybe_store_value->ToObject(&store_value)) { |
| 381 return maybe_store_value; |
| 382 } |
| 383 } |
378 } | 384 } |
379 Object* dict = property_dictionary()->Add(name, store_value, details); | 385 Object* dict; |
380 if (dict->IsFailure()) return dict; | 386 { MaybeObject* maybe_dict = |
| 387 property_dictionary()->Add(name, store_value, details); |
| 388 if (!maybe_dict->ToObject(&dict)) return maybe_dict; |
| 389 } |
381 set_properties(StringDictionary::cast(dict)); | 390 set_properties(StringDictionary::cast(dict)); |
382 return value; | 391 return value; |
383 } | 392 } |
384 // Preserve enumeration index. | 393 // Preserve enumeration index. |
385 details = PropertyDetails(details.attributes(), | 394 details = PropertyDetails(details.attributes(), |
386 details.type(), | 395 details.type(), |
387 property_dictionary()->DetailsAt(entry).index()); | 396 property_dictionary()->DetailsAt(entry).index()); |
388 if (IsGlobalObject()) { | 397 if (IsGlobalObject()) { |
389 JSGlobalPropertyCell* cell = | 398 JSGlobalPropertyCell* cell = |
390 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); | 399 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); |
391 cell->set_value(value); | 400 cell->set_value(value); |
392 // Please note we have to update the property details. | 401 // Please note we have to update the property details. |
393 property_dictionary()->DetailsAtPut(entry, details); | 402 property_dictionary()->DetailsAtPut(entry, details); |
394 } else { | 403 } else { |
395 property_dictionary()->SetEntry(entry, name, value, details); | 404 property_dictionary()->SetEntry(entry, name, value, details); |
396 } | 405 } |
397 return value; | 406 return value; |
398 } | 407 } |
399 | 408 |
400 | 409 |
401 Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 410 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
402 ASSERT(!HasFastProperties()); | 411 ASSERT(!HasFastProperties()); |
403 StringDictionary* dictionary = property_dictionary(); | 412 StringDictionary* dictionary = property_dictionary(); |
404 int entry = dictionary->FindEntry(name); | 413 int entry = dictionary->FindEntry(name); |
405 if (entry != StringDictionary::kNotFound) { | 414 if (entry != StringDictionary::kNotFound) { |
406 // If we have a global object set the cell to the hole. | 415 // If we have a global object set the cell to the hole. |
407 if (IsGlobalObject()) { | 416 if (IsGlobalObject()) { |
408 PropertyDetails details = dictionary->DetailsAt(entry); | 417 PropertyDetails details = dictionary->DetailsAt(entry); |
409 if (details.IsDontDelete()) { | 418 if (details.IsDontDelete()) { |
410 if (mode != FORCE_DELETION) return Heap::false_value(); | 419 if (mode != FORCE_DELETION) return Heap::false_value(); |
411 // When forced to delete global properties, we have to make a | 420 // When forced to delete global properties, we have to make a |
412 // map change to invalidate any ICs that think they can load | 421 // map change to invalidate any ICs that think they can load |
413 // from the DontDelete cell without checking if it contains | 422 // from the DontDelete cell without checking if it contains |
414 // the hole value. | 423 // the hole value. |
415 Object* new_map = map()->CopyDropDescriptors(); | 424 Object* new_map; |
416 if (new_map->IsFailure()) return new_map; | 425 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 426 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 427 } |
417 set_map(Map::cast(new_map)); | 428 set_map(Map::cast(new_map)); |
418 } | 429 } |
419 JSGlobalPropertyCell* cell = | 430 JSGlobalPropertyCell* cell = |
420 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 431 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
421 cell->set_value(Heap::the_hole_value()); | 432 cell->set_value(Heap::the_hole_value()); |
422 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 433 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
423 } else { | 434 } else { |
424 return dictionary->DeleteProperty(entry, mode); | 435 return dictionary->DeleteProperty(entry, mode); |
425 } | 436 } |
426 } | 437 } |
427 return Heap::true_value(); | 438 return Heap::true_value(); |
428 } | 439 } |
429 | 440 |
430 | 441 |
431 bool JSObject::IsDirty() { | 442 bool JSObject::IsDirty() { |
432 Object* cons_obj = map()->constructor(); | 443 Object* cons_obj = map()->constructor(); |
433 if (!cons_obj->IsJSFunction()) | 444 if (!cons_obj->IsJSFunction()) |
434 return true; | 445 return true; |
435 JSFunction* fun = JSFunction::cast(cons_obj); | 446 JSFunction* fun = JSFunction::cast(cons_obj); |
436 if (!fun->shared()->IsApiFunction()) | 447 if (!fun->shared()->IsApiFunction()) |
437 return true; | 448 return true; |
438 // If the object is fully fast case and has the same map it was | 449 // If the object is fully fast case and has the same map it was |
439 // created with then no changes can have been made to it. | 450 // created with then no changes can have been made to it. |
440 return map() != fun->initial_map() | 451 return map() != fun->initial_map() |
441 || !HasFastElements() | 452 || !HasFastElements() |
442 || !HasFastProperties(); | 453 || !HasFastProperties(); |
443 } | 454 } |
444 | 455 |
445 | 456 |
446 Object* Object::GetProperty(Object* receiver, | 457 MaybeObject* Object::GetProperty(Object* receiver, |
447 LookupResult* result, | 458 LookupResult* result, |
448 String* name, | 459 String* name, |
449 PropertyAttributes* attributes) { | 460 PropertyAttributes* attributes) { |
450 // Make sure that the top context does not change when doing | 461 // Make sure that the top context does not change when doing |
451 // callbacks or interceptor calls. | 462 // callbacks or interceptor calls. |
452 AssertNoContextChange ncc; | 463 AssertNoContextChange ncc; |
453 | 464 |
454 // Traverse the prototype chain from the current object (this) to | 465 // Traverse the prototype chain from the current object (this) to |
455 // the holder and check for access rights. This avoid traversing the | 466 // the holder and check for access rights. This avoid traversing the |
456 // objects more than once in case of interceptors, because the | 467 // objects more than once in case of interceptors, because the |
457 // holder will always be the interceptor holder and the search may | 468 // holder will always be the interceptor holder and the search may |
458 // only continue with a current object just after the interceptor | 469 // only continue with a current object just after the interceptor |
459 // holder in the prototype chain. | 470 // holder in the prototype chain. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 JSObject* recvr = JSObject::cast(receiver); | 516 JSObject* recvr = JSObject::cast(receiver); |
506 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 517 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
507 } | 518 } |
508 default: | 519 default: |
509 UNREACHABLE(); | 520 UNREACHABLE(); |
510 return NULL; | 521 return NULL; |
511 } | 522 } |
512 } | 523 } |
513 | 524 |
514 | 525 |
515 Object* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 526 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
516 // Non-JS objects do not have integer indexed properties. | 527 // Non-JS objects do not have integer indexed properties. |
517 if (!IsJSObject()) return Heap::undefined_value(); | 528 if (!IsJSObject()) return Heap::undefined_value(); |
518 return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver), | 529 return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver), |
519 index); | 530 index); |
520 } | 531 } |
521 | 532 |
522 | 533 |
523 Object* Object::GetPrototype() { | 534 Object* Object::GetPrototype() { |
524 // The object is either a number, a string, a boolean, or a real JS object. | 535 // The object is either a number, a string, a boolean, or a real JS object. |
525 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); | 536 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 return true; // An Ape, an ABCBook. | 602 return true; // An Ape, an ABCBook. |
592 } else if ((c1 == 0 || (c1 >= 'A' && c1 <= 'Z')) && | 603 } else if ((c1 == 0 || (c1 >= 'A' && c1 <= 'Z')) && |
593 (c0 == 'F' || c0 == 'H' || c0 == 'M' || c0 == 'N' || c0 == 'R' || | 604 (c0 == 'F' || c0 == 'H' || c0 == 'M' || c0 == 'N' || c0 == 'R' || |
594 c0 == 'S' || c0 == 'X')) { | 605 c0 == 'S' || c0 == 'X')) { |
595 return true; // An MP3File, an M. | 606 return true; // An MP3File, an M. |
596 } | 607 } |
597 return false; | 608 return false; |
598 } | 609 } |
599 | 610 |
600 | 611 |
601 Object* String::SlowTryFlatten(PretenureFlag pretenure) { | 612 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) { |
602 #ifdef DEBUG | 613 #ifdef DEBUG |
603 // Do not attempt to flatten in debug mode when allocation is not | 614 // Do not attempt to flatten in debug mode when allocation is not |
604 // allowed. This is to avoid an assertion failure when allocating. | 615 // allowed. This is to avoid an assertion failure when allocating. |
605 // Flattening strings is the only case where we always allow | 616 // Flattening strings is the only case where we always allow |
606 // allocation because no GC is performed if the allocation fails. | 617 // allocation because no GC is performed if the allocation fails. |
607 if (!Heap::IsAllocationAllowed()) return this; | 618 if (!Heap::IsAllocationAllowed()) return this; |
608 #endif | 619 #endif |
609 | 620 |
610 switch (StringShape(this).representation_tag()) { | 621 switch (StringShape(this).representation_tag()) { |
611 case kConsStringTag: { | 622 case kConsStringTag: { |
612 ConsString* cs = ConsString::cast(this); | 623 ConsString* cs = ConsString::cast(this); |
613 if (cs->second()->length() == 0) { | 624 if (cs->second()->length() == 0) { |
614 return cs->first(); | 625 return cs->first(); |
615 } | 626 } |
616 // There's little point in putting the flat string in new space if the | 627 // There's little point in putting the flat string in new space if the |
617 // cons string is in old space. It can never get GCed until there is | 628 // cons string is in old space. It can never get GCed until there is |
618 // an old space GC. | 629 // an old space GC. |
619 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; | 630 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; |
620 int len = length(); | 631 int len = length(); |
621 Object* object; | 632 Object* object; |
622 String* result; | 633 String* result; |
623 if (IsAsciiRepresentation()) { | 634 if (IsAsciiRepresentation()) { |
624 object = Heap::AllocateRawAsciiString(len, tenure); | 635 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(len, tenure); |
625 if (object->IsFailure()) return object; | 636 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 637 } |
626 result = String::cast(object); | 638 result = String::cast(object); |
627 String* first = cs->first(); | 639 String* first = cs->first(); |
628 int first_length = first->length(); | 640 int first_length = first->length(); |
629 char* dest = SeqAsciiString::cast(result)->GetChars(); | 641 char* dest = SeqAsciiString::cast(result)->GetChars(); |
630 WriteToFlat(first, dest, 0, first_length); | 642 WriteToFlat(first, dest, 0, first_length); |
631 String* second = cs->second(); | 643 String* second = cs->second(); |
632 WriteToFlat(second, | 644 WriteToFlat(second, |
633 dest + first_length, | 645 dest + first_length, |
634 0, | 646 0, |
635 len - first_length); | 647 len - first_length); |
636 } else { | 648 } else { |
637 object = Heap::AllocateRawTwoByteString(len, tenure); | 649 { MaybeObject* maybe_object = |
638 if (object->IsFailure()) return object; | 650 Heap::AllocateRawTwoByteString(len, tenure); |
| 651 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 652 } |
639 result = String::cast(object); | 653 result = String::cast(object); |
640 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | 654 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
641 String* first = cs->first(); | 655 String* first = cs->first(); |
642 int first_length = first->length(); | 656 int first_length = first->length(); |
643 WriteToFlat(first, dest, 0, first_length); | 657 WriteToFlat(first, dest, 0, first_length); |
644 String* second = cs->second(); | 658 String* second = cs->second(); |
645 WriteToFlat(second, | 659 WriteToFlat(second, |
646 dest + first_length, | 660 dest + first_length, |
647 0, | 661 0, |
648 len - first_length); | 662 len - first_length); |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 String* inferred_name = constructor->shared()->inferred_name(); | 1176 String* inferred_name = constructor->shared()->inferred_name(); |
1163 if (inferred_name->length() > 0) return inferred_name; | 1177 if (inferred_name->length() > 0) return inferred_name; |
1164 Object* proto = GetPrototype(); | 1178 Object* proto = GetPrototype(); |
1165 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1179 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
1166 } | 1180 } |
1167 // If the constructor is not present, return "Object". | 1181 // If the constructor is not present, return "Object". |
1168 return Heap::Object_symbol(); | 1182 return Heap::Object_symbol(); |
1169 } | 1183 } |
1170 | 1184 |
1171 | 1185 |
1172 Object* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1186 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
1173 String* name, | 1187 String* name, |
1174 Object* value) { | 1188 Object* value) { |
1175 int index = new_map->PropertyIndexFor(name); | 1189 int index = new_map->PropertyIndexFor(name); |
1176 if (map()->unused_property_fields() == 0) { | 1190 if (map()->unused_property_fields() == 0) { |
1177 ASSERT(map()->unused_property_fields() == 0); | 1191 ASSERT(map()->unused_property_fields() == 0); |
1178 int new_unused = new_map->unused_property_fields(); | 1192 int new_unused = new_map->unused_property_fields(); |
1179 Object* values = | 1193 Object* values; |
1180 properties()->CopySize(properties()->length() + new_unused + 1); | 1194 { MaybeObject* maybe_values = |
1181 if (values->IsFailure()) return values; | 1195 properties()->CopySize(properties()->length() + new_unused + 1); |
| 1196 if (!maybe_values->ToObject(&values)) return maybe_values; |
| 1197 } |
1182 set_properties(FixedArray::cast(values)); | 1198 set_properties(FixedArray::cast(values)); |
1183 } | 1199 } |
1184 set_map(new_map); | 1200 set_map(new_map); |
1185 return FastPropertyAtPut(index, value); | 1201 return FastPropertyAtPut(index, value); |
1186 } | 1202 } |
1187 | 1203 |
1188 | 1204 |
1189 Object* JSObject::AddFastProperty(String* name, | 1205 MaybeObject* JSObject::AddFastProperty(String* name, |
1190 Object* value, | 1206 Object* value, |
1191 PropertyAttributes attributes) { | 1207 PropertyAttributes attributes) { |
1192 // Normalize the object if the name is an actual string (not the | 1208 // Normalize the object if the name is an actual string (not the |
1193 // hidden symbols) and is not a real identifier. | 1209 // hidden symbols) and is not a real identifier. |
1194 StringInputBuffer buffer(name); | 1210 StringInputBuffer buffer(name); |
1195 if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) { | 1211 if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) { |
1196 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1212 Object* obj; |
1197 if (obj->IsFailure()) return obj; | 1213 { MaybeObject* maybe_obj = |
| 1214 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1215 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1216 } |
1198 return AddSlowProperty(name, value, attributes); | 1217 return AddSlowProperty(name, value, attributes); |
1199 } | 1218 } |
1200 | 1219 |
1201 DescriptorArray* old_descriptors = map()->instance_descriptors(); | 1220 DescriptorArray* old_descriptors = map()->instance_descriptors(); |
1202 // Compute the new index for new field. | 1221 // Compute the new index for new field. |
1203 int index = map()->NextFreePropertyIndex(); | 1222 int index = map()->NextFreePropertyIndex(); |
1204 | 1223 |
1205 // Allocate new instance descriptors with (name, index) added | 1224 // Allocate new instance descriptors with (name, index) added |
1206 FieldDescriptor new_field(name, index, attributes); | 1225 FieldDescriptor new_field(name, index, attributes); |
1207 Object* new_descriptors = | 1226 Object* new_descriptors; |
1208 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); | 1227 { MaybeObject* maybe_new_descriptors = |
1209 if (new_descriptors->IsFailure()) return new_descriptors; | 1228 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); |
| 1229 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
| 1230 return maybe_new_descriptors; |
| 1231 } |
| 1232 } |
1210 | 1233 |
1211 // Only allow map transition if the object's map is NOT equal to the | 1234 // Only allow map transition if the object's map is NOT equal to the |
1212 // global object_function's map and there is not a transition for name. | 1235 // global object_function's map and there is not a transition for name. |
1213 bool allow_map_transition = | 1236 bool allow_map_transition = |
1214 !old_descriptors->Contains(name) && | 1237 !old_descriptors->Contains(name) && |
1215 (Top::context()->global_context()->object_function()->map() != map()); | 1238 (Top::context()->global_context()->object_function()->map() != map()); |
1216 | 1239 |
1217 ASSERT(index < map()->inobject_properties() || | 1240 ASSERT(index < map()->inobject_properties() || |
1218 (index - map()->inobject_properties()) < properties()->length() || | 1241 (index - map()->inobject_properties()) < properties()->length() || |
1219 map()->unused_property_fields() == 0); | 1242 map()->unused_property_fields() == 0); |
1220 // Allocate a new map for the object. | 1243 // Allocate a new map for the object. |
1221 Object* r = map()->CopyDropDescriptors(); | 1244 Object* r; |
1222 if (r->IsFailure()) return r; | 1245 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); |
| 1246 if (!maybe_r->ToObject(&r)) return maybe_r; |
| 1247 } |
1223 Map* new_map = Map::cast(r); | 1248 Map* new_map = Map::cast(r); |
1224 if (allow_map_transition) { | 1249 if (allow_map_transition) { |
1225 // Allocate new instance descriptors for the old map with map transition. | 1250 // Allocate new instance descriptors for the old map with map transition. |
1226 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); | 1251 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); |
1227 Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); | 1252 Object* r; |
1228 if (r->IsFailure()) return r; | 1253 { MaybeObject* maybe_r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); |
| 1254 if (!maybe_r->ToObject(&r)) return maybe_r; |
| 1255 } |
1229 old_descriptors = DescriptorArray::cast(r); | 1256 old_descriptors = DescriptorArray::cast(r); |
1230 } | 1257 } |
1231 | 1258 |
1232 if (map()->unused_property_fields() == 0) { | 1259 if (map()->unused_property_fields() == 0) { |
1233 if (properties()->length() > MaxFastProperties()) { | 1260 if (properties()->length() > MaxFastProperties()) { |
1234 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1261 Object* obj; |
1235 if (obj->IsFailure()) return obj; | 1262 { MaybeObject* maybe_obj = |
| 1263 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1264 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1265 } |
1236 return AddSlowProperty(name, value, attributes); | 1266 return AddSlowProperty(name, value, attributes); |
1237 } | 1267 } |
1238 // Make room for the new value | 1268 // Make room for the new value |
1239 Object* values = | 1269 Object* values; |
1240 properties()->CopySize(properties()->length() + kFieldsAdded); | 1270 { MaybeObject* maybe_values = |
1241 if (values->IsFailure()) return values; | 1271 properties()->CopySize(properties()->length() + kFieldsAdded); |
| 1272 if (!maybe_values->ToObject(&values)) return maybe_values; |
| 1273 } |
1242 set_properties(FixedArray::cast(values)); | 1274 set_properties(FixedArray::cast(values)); |
1243 new_map->set_unused_property_fields(kFieldsAdded - 1); | 1275 new_map->set_unused_property_fields(kFieldsAdded - 1); |
1244 } else { | 1276 } else { |
1245 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); | 1277 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); |
1246 } | 1278 } |
1247 // We have now allocated all the necessary objects. | 1279 // We have now allocated all the necessary objects. |
1248 // All the changes can be applied at once, so they are atomic. | 1280 // All the changes can be applied at once, so they are atomic. |
1249 map()->set_instance_descriptors(old_descriptors); | 1281 map()->set_instance_descriptors(old_descriptors); |
1250 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1282 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
1251 set_map(new_map); | 1283 set_map(new_map); |
1252 return FastPropertyAtPut(index, value); | 1284 return FastPropertyAtPut(index, value); |
1253 } | 1285 } |
1254 | 1286 |
1255 | 1287 |
1256 Object* JSObject::AddConstantFunctionProperty(String* name, | 1288 MaybeObject* JSObject::AddConstantFunctionProperty( |
1257 JSFunction* function, | 1289 String* name, |
1258 PropertyAttributes attributes) { | 1290 JSFunction* function, |
| 1291 PropertyAttributes attributes) { |
1259 ASSERT(!Heap::InNewSpace(function)); | 1292 ASSERT(!Heap::InNewSpace(function)); |
1260 | 1293 |
1261 // Allocate new instance descriptors with (name, function) added | 1294 // Allocate new instance descriptors with (name, function) added |
1262 ConstantFunctionDescriptor d(name, function, attributes); | 1295 ConstantFunctionDescriptor d(name, function, attributes); |
1263 Object* new_descriptors = | 1296 Object* new_descriptors; |
1264 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); | 1297 { MaybeObject* maybe_new_descriptors = |
1265 if (new_descriptors->IsFailure()) return new_descriptors; | 1298 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); |
| 1299 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
| 1300 return maybe_new_descriptors; |
| 1301 } |
| 1302 } |
1266 | 1303 |
1267 // Allocate a new map for the object. | 1304 // Allocate a new map for the object. |
1268 Object* new_map = map()->CopyDropDescriptors(); | 1305 Object* new_map; |
1269 if (new_map->IsFailure()) return new_map; | 1306 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 1307 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 1308 } |
1270 | 1309 |
1271 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); | 1310 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); |
1272 Map::cast(new_map)->set_instance_descriptors(descriptors); | 1311 Map::cast(new_map)->set_instance_descriptors(descriptors); |
1273 Map* old_map = map(); | 1312 Map* old_map = map(); |
1274 set_map(Map::cast(new_map)); | 1313 set_map(Map::cast(new_map)); |
1275 | 1314 |
1276 // If the old map is the global object map (from new Object()), | 1315 // If the old map is the global object map (from new Object()), |
1277 // then transitions are not added to it, so we are done. | 1316 // then transitions are not added to it, so we are done. |
1278 if (old_map == Top::context()->global_context()->object_function()->map()) { | 1317 if (old_map == Top::context()->global_context()->object_function()->map()) { |
1279 return function; | 1318 return function; |
1280 } | 1319 } |
1281 | 1320 |
1282 // Do not add CONSTANT_TRANSITIONS to global objects | 1321 // Do not add CONSTANT_TRANSITIONS to global objects |
1283 if (IsGlobalObject()) { | 1322 if (IsGlobalObject()) { |
1284 return function; | 1323 return function; |
1285 } | 1324 } |
1286 | 1325 |
1287 // Add a CONSTANT_TRANSITION descriptor to the old map, | 1326 // Add a CONSTANT_TRANSITION descriptor to the old map, |
1288 // so future assignments to this property on other objects | 1327 // so future assignments to this property on other objects |
1289 // of the same type will create a normal field, not a constant function. | 1328 // of the same type will create a normal field, not a constant function. |
1290 // Don't do this for special properties, with non-trival attributes. | 1329 // Don't do this for special properties, with non-trival attributes. |
1291 if (attributes != NONE) { | 1330 if (attributes != NONE) { |
1292 return function; | 1331 return function; |
1293 } | 1332 } |
1294 ConstTransitionDescriptor mark(name, Map::cast(new_map)); | 1333 ConstTransitionDescriptor mark(name, Map::cast(new_map)); |
1295 new_descriptors = | 1334 { MaybeObject* maybe_new_descriptors = |
1296 old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS); | 1335 old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS); |
1297 if (new_descriptors->IsFailure()) { | 1336 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
1298 return function; // We have accomplished the main goal, so return success. | 1337 // We have accomplished the main goal, so return success. |
| 1338 return function; |
| 1339 } |
1299 } | 1340 } |
1300 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1341 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
1301 | 1342 |
1302 return function; | 1343 return function; |
1303 } | 1344 } |
1304 | 1345 |
1305 | 1346 |
1306 // Add property in slow mode | 1347 // Add property in slow mode |
1307 Object* JSObject::AddSlowProperty(String* name, | 1348 MaybeObject* JSObject::AddSlowProperty(String* name, |
1308 Object* value, | 1349 Object* value, |
1309 PropertyAttributes attributes) { | 1350 PropertyAttributes attributes) { |
1310 ASSERT(!HasFastProperties()); | 1351 ASSERT(!HasFastProperties()); |
1311 StringDictionary* dict = property_dictionary(); | 1352 StringDictionary* dict = property_dictionary(); |
1312 Object* store_value = value; | 1353 Object* store_value = value; |
1313 if (IsGlobalObject()) { | 1354 if (IsGlobalObject()) { |
1314 // In case name is an orphaned property reuse the cell. | 1355 // In case name is an orphaned property reuse the cell. |
1315 int entry = dict->FindEntry(name); | 1356 int entry = dict->FindEntry(name); |
1316 if (entry != StringDictionary::kNotFound) { | 1357 if (entry != StringDictionary::kNotFound) { |
1317 store_value = dict->ValueAt(entry); | 1358 store_value = dict->ValueAt(entry); |
1318 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1359 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
1319 // Assign an enumeration index to the property and update | 1360 // Assign an enumeration index to the property and update |
1320 // SetNextEnumerationIndex. | 1361 // SetNextEnumerationIndex. |
1321 int index = dict->NextEnumerationIndex(); | 1362 int index = dict->NextEnumerationIndex(); |
1322 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); | 1363 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
1323 dict->SetNextEnumerationIndex(index + 1); | 1364 dict->SetNextEnumerationIndex(index + 1); |
1324 dict->SetEntry(entry, name, store_value, details); | 1365 dict->SetEntry(entry, name, store_value, details); |
1325 return value; | 1366 return value; |
1326 } | 1367 } |
1327 store_value = Heap::AllocateJSGlobalPropertyCell(value); | 1368 { MaybeObject* maybe_store_value = |
1328 if (store_value->IsFailure()) return store_value; | 1369 Heap::AllocateJSGlobalPropertyCell(value); |
| 1370 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 1371 } |
1329 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1372 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
1330 } | 1373 } |
1331 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1374 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
1332 Object* result = dict->Add(name, store_value, details); | 1375 Object* result; |
1333 if (result->IsFailure()) return result; | 1376 { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
| 1377 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1378 } |
1334 if (dict != result) set_properties(StringDictionary::cast(result)); | 1379 if (dict != result) set_properties(StringDictionary::cast(result)); |
1335 return value; | 1380 return value; |
1336 } | 1381 } |
1337 | 1382 |
1338 | 1383 |
1339 Object* JSObject::AddProperty(String* name, | 1384 MaybeObject* JSObject::AddProperty(String* name, |
1340 Object* value, | 1385 Object* value, |
1341 PropertyAttributes attributes) { | 1386 PropertyAttributes attributes) { |
1342 ASSERT(!IsJSGlobalProxy()); | 1387 ASSERT(!IsJSGlobalProxy()); |
1343 if (!map()->is_extensible()) { | 1388 if (!map()->is_extensible()) { |
1344 Handle<Object> args[1] = {Handle<String>(name)}; | 1389 Handle<Object> args[1] = {Handle<String>(name)}; |
1345 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 1390 return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
1346 HandleVector(args, 1))); | 1391 HandleVector(args, 1))); |
1347 } | 1392 } |
1348 if (HasFastProperties()) { | 1393 if (HasFastProperties()) { |
1349 // Ensure the descriptor array does not get too big. | 1394 // Ensure the descriptor array does not get too big. |
1350 if (map()->instance_descriptors()->number_of_descriptors() < | 1395 if (map()->instance_descriptors()->number_of_descriptors() < |
1351 DescriptorArray::kMaxNumberOfDescriptors) { | 1396 DescriptorArray::kMaxNumberOfDescriptors) { |
1352 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { | 1397 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { |
1353 return AddConstantFunctionProperty(name, | 1398 return AddConstantFunctionProperty(name, |
1354 JSFunction::cast(value), | 1399 JSFunction::cast(value), |
1355 attributes); | 1400 attributes); |
1356 } else { | 1401 } else { |
1357 return AddFastProperty(name, value, attributes); | 1402 return AddFastProperty(name, value, attributes); |
1358 } | 1403 } |
1359 } else { | 1404 } else { |
1360 // Normalize the object to prevent very large instance descriptors. | 1405 // Normalize the object to prevent very large instance descriptors. |
1361 // This eliminates unwanted N^2 allocation and lookup behavior. | 1406 // This eliminates unwanted N^2 allocation and lookup behavior. |
1362 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1407 Object* obj; |
1363 if (obj->IsFailure()) return obj; | 1408 { MaybeObject* maybe_obj = |
| 1409 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1410 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1411 } |
1364 } | 1412 } |
1365 } | 1413 } |
1366 return AddSlowProperty(name, value, attributes); | 1414 return AddSlowProperty(name, value, attributes); |
1367 } | 1415 } |
1368 | 1416 |
1369 | 1417 |
1370 Object* JSObject::SetPropertyPostInterceptor(String* name, | 1418 MaybeObject* JSObject::SetPropertyPostInterceptor( |
1371 Object* value, | 1419 String* name, |
1372 PropertyAttributes attributes) { | 1420 Object* value, |
| 1421 PropertyAttributes attributes) { |
1373 // Check local property, ignore interceptor. | 1422 // Check local property, ignore interceptor. |
1374 LookupResult result; | 1423 LookupResult result; |
1375 LocalLookupRealNamedProperty(name, &result); | 1424 LocalLookupRealNamedProperty(name, &result); |
1376 if (result.IsFound()) { | 1425 if (result.IsFound()) { |
1377 // An existing property, a map transition or a null descriptor was | 1426 // An existing property, a map transition or a null descriptor was |
1378 // found. Use set property to handle all these cases. | 1427 // found. Use set property to handle all these cases. |
1379 return SetProperty(&result, name, value, attributes); | 1428 return SetProperty(&result, name, value, attributes); |
1380 } | 1429 } |
1381 // Add a new real property. | 1430 // Add a new real property. |
1382 return AddProperty(name, value, attributes); | 1431 return AddProperty(name, value, attributes); |
1383 } | 1432 } |
1384 | 1433 |
1385 | 1434 |
1386 Object* JSObject::ReplaceSlowProperty(String* name, | 1435 MaybeObject* JSObject::ReplaceSlowProperty(String* name, |
1387 Object* value, | 1436 Object* value, |
1388 PropertyAttributes attributes) { | 1437 PropertyAttributes attributes) { |
1389 StringDictionary* dictionary = property_dictionary(); | 1438 StringDictionary* dictionary = property_dictionary(); |
1390 int old_index = dictionary->FindEntry(name); | 1439 int old_index = dictionary->FindEntry(name); |
1391 int new_enumeration_index = 0; // 0 means "Use the next available index." | 1440 int new_enumeration_index = 0; // 0 means "Use the next available index." |
1392 if (old_index != -1) { | 1441 if (old_index != -1) { |
1393 // All calls to ReplaceSlowProperty have had all transitions removed. | 1442 // All calls to ReplaceSlowProperty have had all transitions removed. |
1394 ASSERT(!dictionary->DetailsAt(old_index).IsTransition()); | 1443 ASSERT(!dictionary->DetailsAt(old_index).IsTransition()); |
1395 new_enumeration_index = dictionary->DetailsAt(old_index).index(); | 1444 new_enumeration_index = dictionary->DetailsAt(old_index).index(); |
1396 } | 1445 } |
1397 | 1446 |
1398 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); | 1447 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); |
1399 return SetNormalizedProperty(name, value, new_details); | 1448 return SetNormalizedProperty(name, value, new_details); |
1400 } | 1449 } |
1401 | 1450 |
1402 | 1451 |
1403 Object* JSObject::ConvertDescriptorToFieldAndMapTransition( | 1452 MaybeObject* JSObject::ConvertDescriptorToFieldAndMapTransition( |
1404 String* name, | 1453 String* name, |
1405 Object* new_value, | 1454 Object* new_value, |
1406 PropertyAttributes attributes) { | 1455 PropertyAttributes attributes) { |
1407 Map* old_map = map(); | 1456 Map* old_map = map(); |
1408 Object* result = ConvertDescriptorToField(name, new_value, attributes); | 1457 Object* result; |
1409 if (result->IsFailure()) return result; | 1458 { MaybeObject* maybe_result = |
| 1459 ConvertDescriptorToField(name, new_value, attributes); |
| 1460 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1461 } |
1410 // If we get to this point we have succeeded - do not return failure | 1462 // If we get to this point we have succeeded - do not return failure |
1411 // after this point. Later stuff is optional. | 1463 // after this point. Later stuff is optional. |
1412 if (!HasFastProperties()) { | 1464 if (!HasFastProperties()) { |
1413 return result; | 1465 return result; |
1414 } | 1466 } |
1415 // Do not add transitions to the map of "new Object()". | 1467 // Do not add transitions to the map of "new Object()". |
1416 if (map() == Top::context()->global_context()->object_function()->map()) { | 1468 if (map() == Top::context()->global_context()->object_function()->map()) { |
1417 return result; | 1469 return result; |
1418 } | 1470 } |
1419 | 1471 |
1420 MapTransitionDescriptor transition(name, | 1472 MapTransitionDescriptor transition(name, |
1421 map(), | 1473 map(), |
1422 attributes); | 1474 attributes); |
1423 Object* new_descriptors = | 1475 Object* new_descriptors; |
1424 old_map->instance_descriptors()-> | 1476 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> |
1425 CopyInsert(&transition, KEEP_TRANSITIONS); | 1477 CopyInsert(&transition, KEEP_TRANSITIONS); |
1426 if (new_descriptors->IsFailure()) return result; // Yes, return _result_. | 1478 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
| 1479 return result; // Yes, return _result_. |
| 1480 } |
| 1481 } |
1427 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1482 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
1428 return result; | 1483 return result; |
1429 } | 1484 } |
1430 | 1485 |
1431 | 1486 |
1432 Object* JSObject::ConvertDescriptorToField(String* name, | 1487 MaybeObject* JSObject::ConvertDescriptorToField(String* name, |
1433 Object* new_value, | 1488 Object* new_value, |
1434 PropertyAttributes attributes) { | 1489 PropertyAttributes attributes) { |
1435 if (map()->unused_property_fields() == 0 && | 1490 if (map()->unused_property_fields() == 0 && |
1436 properties()->length() > MaxFastProperties()) { | 1491 properties()->length() > MaxFastProperties()) { |
1437 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1492 Object* obj; |
1438 if (obj->IsFailure()) return obj; | 1493 { MaybeObject* maybe_obj = |
| 1494 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1495 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1496 } |
1439 return ReplaceSlowProperty(name, new_value, attributes); | 1497 return ReplaceSlowProperty(name, new_value, attributes); |
1440 } | 1498 } |
1441 | 1499 |
1442 int index = map()->NextFreePropertyIndex(); | 1500 int index = map()->NextFreePropertyIndex(); |
1443 FieldDescriptor new_field(name, index, attributes); | 1501 FieldDescriptor new_field(name, index, attributes); |
1444 // Make a new DescriptorArray replacing an entry with FieldDescriptor. | 1502 // Make a new DescriptorArray replacing an entry with FieldDescriptor. |
1445 Object* descriptors_unchecked = map()->instance_descriptors()-> | 1503 Object* descriptors_unchecked; |
1446 CopyInsert(&new_field, REMOVE_TRANSITIONS); | 1504 { MaybeObject* maybe_descriptors_unchecked = map()->instance_descriptors()-> |
1447 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; | 1505 CopyInsert(&new_field, REMOVE_TRANSITIONS); |
| 1506 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { |
| 1507 return maybe_descriptors_unchecked; |
| 1508 } |
| 1509 } |
1448 DescriptorArray* new_descriptors = | 1510 DescriptorArray* new_descriptors = |
1449 DescriptorArray::cast(descriptors_unchecked); | 1511 DescriptorArray::cast(descriptors_unchecked); |
1450 | 1512 |
1451 // Make a new map for the object. | 1513 // Make a new map for the object. |
1452 Object* new_map_unchecked = map()->CopyDropDescriptors(); | 1514 Object* new_map_unchecked; |
1453 if (new_map_unchecked->IsFailure()) return new_map_unchecked; | 1515 { MaybeObject* maybe_new_map_unchecked = map()->CopyDropDescriptors(); |
| 1516 if (!maybe_new_map_unchecked->ToObject(&new_map_unchecked)) { |
| 1517 return maybe_new_map_unchecked; |
| 1518 } |
| 1519 } |
1454 Map* new_map = Map::cast(new_map_unchecked); | 1520 Map* new_map = Map::cast(new_map_unchecked); |
1455 new_map->set_instance_descriptors(new_descriptors); | 1521 new_map->set_instance_descriptors(new_descriptors); |
1456 | 1522 |
1457 // Make new properties array if necessary. | 1523 // Make new properties array if necessary. |
1458 FixedArray* new_properties = 0; // Will always be NULL or a valid pointer. | 1524 FixedArray* new_properties = 0; // Will always be NULL or a valid pointer. |
1459 int new_unused_property_fields = map()->unused_property_fields() - 1; | 1525 int new_unused_property_fields = map()->unused_property_fields() - 1; |
1460 if (map()->unused_property_fields() == 0) { | 1526 if (map()->unused_property_fields() == 0) { |
1461 new_unused_property_fields = kFieldsAdded - 1; | 1527 new_unused_property_fields = kFieldsAdded - 1; |
1462 Object* new_properties_unchecked = | 1528 Object* new_properties_object; |
1463 properties()->CopySize(properties()->length() + kFieldsAdded); | 1529 { MaybeObject* maybe_new_properties_object = |
1464 if (new_properties_unchecked->IsFailure()) return new_properties_unchecked; | 1530 properties()->CopySize(properties()->length() + kFieldsAdded); |
1465 new_properties = FixedArray::cast(new_properties_unchecked); | 1531 if (!maybe_new_properties_object->ToObject(&new_properties_object)) { |
| 1532 return maybe_new_properties_object; |
| 1533 } |
| 1534 } |
| 1535 new_properties = FixedArray::cast(new_properties_object); |
1466 } | 1536 } |
1467 | 1537 |
1468 // Update pointers to commit changes. | 1538 // Update pointers to commit changes. |
1469 // Object points to the new map. | 1539 // Object points to the new map. |
1470 new_map->set_unused_property_fields(new_unused_property_fields); | 1540 new_map->set_unused_property_fields(new_unused_property_fields); |
1471 set_map(new_map); | 1541 set_map(new_map); |
1472 if (new_properties) { | 1542 if (new_properties) { |
1473 set_properties(FixedArray::cast(new_properties)); | 1543 set_properties(FixedArray::cast(new_properties)); |
1474 } | 1544 } |
1475 return FastPropertyAtPut(index, new_value); | 1545 return FastPropertyAtPut(index, new_value); |
1476 } | 1546 } |
1477 | 1547 |
1478 | 1548 |
1479 | 1549 |
1480 Object* JSObject::SetPropertyWithInterceptor(String* name, | 1550 MaybeObject* JSObject::SetPropertyWithInterceptor( |
1481 Object* value, | 1551 String* name, |
1482 PropertyAttributes attributes) { | 1552 Object* value, |
| 1553 PropertyAttributes attributes) { |
1483 HandleScope scope; | 1554 HandleScope scope; |
1484 Handle<JSObject> this_handle(this); | 1555 Handle<JSObject> this_handle(this); |
1485 Handle<String> name_handle(name); | 1556 Handle<String> name_handle(name); |
1486 Handle<Object> value_handle(value); | 1557 Handle<Object> value_handle(value); |
1487 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1558 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
1488 if (!interceptor->setter()->IsUndefined()) { | 1559 if (!interceptor->setter()->IsUndefined()) { |
1489 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1560 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
1490 CustomArguments args(interceptor->data(), this, this); | 1561 CustomArguments args(interceptor->data(), this, this); |
1491 v8::AccessorInfo info(args.end()); | 1562 v8::AccessorInfo info(args.end()); |
1492 v8::NamedPropertySetter setter = | 1563 v8::NamedPropertySetter setter = |
1493 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1564 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
1494 v8::Handle<v8::Value> result; | 1565 v8::Handle<v8::Value> result; |
1495 { | 1566 { |
1496 // Leaving JavaScript. | 1567 // Leaving JavaScript. |
1497 VMState state(EXTERNAL); | 1568 VMState state(EXTERNAL); |
1498 Handle<Object> value_unhole(value->IsTheHole() ? | 1569 Handle<Object> value_unhole(value->IsTheHole() ? |
1499 Heap::undefined_value() : | 1570 Heap::undefined_value() : |
1500 value); | 1571 value); |
1501 result = setter(v8::Utils::ToLocal(name_handle), | 1572 result = setter(v8::Utils::ToLocal(name_handle), |
1502 v8::Utils::ToLocal(value_unhole), | 1573 v8::Utils::ToLocal(value_unhole), |
1503 info); | 1574 info); |
1504 } | 1575 } |
1505 RETURN_IF_SCHEDULED_EXCEPTION(); | 1576 RETURN_IF_SCHEDULED_EXCEPTION(); |
1506 if (!result.IsEmpty()) return *value_handle; | 1577 if (!result.IsEmpty()) return *value_handle; |
1507 } | 1578 } |
1508 Object* raw_result = this_handle->SetPropertyPostInterceptor(*name_handle, | 1579 MaybeObject* raw_result = |
1509 *value_handle, | 1580 this_handle->SetPropertyPostInterceptor(*name_handle, |
1510 attributes); | 1581 *value_handle, |
| 1582 attributes); |
1511 RETURN_IF_SCHEDULED_EXCEPTION(); | 1583 RETURN_IF_SCHEDULED_EXCEPTION(); |
1512 return raw_result; | 1584 return raw_result; |
1513 } | 1585 } |
1514 | 1586 |
1515 | 1587 |
1516 Object* JSObject::SetProperty(String* name, | 1588 MaybeObject* JSObject::SetProperty(String* name, |
1517 Object* value, | 1589 Object* value, |
1518 PropertyAttributes attributes) { | 1590 PropertyAttributes attributes) { |
1519 LookupResult result; | 1591 LookupResult result; |
1520 LocalLookup(name, &result); | 1592 LocalLookup(name, &result); |
1521 return SetProperty(&result, name, value, attributes); | 1593 return SetProperty(&result, name, value, attributes); |
1522 } | 1594 } |
1523 | 1595 |
1524 | 1596 |
1525 Object* JSObject::SetPropertyWithCallback(Object* structure, | 1597 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
1526 String* name, | 1598 String* name, |
1527 Object* value, | 1599 Object* value, |
1528 JSObject* holder) { | 1600 JSObject* holder) { |
1529 HandleScope scope; | 1601 HandleScope scope; |
1530 | 1602 |
1531 // We should never get here to initialize a const with the hole | 1603 // We should never get here to initialize a const with the hole |
1532 // value since a const declaration would conflict with the setter. | 1604 // value since a const declaration would conflict with the setter. |
1533 ASSERT(!value->IsTheHole()); | 1605 ASSERT(!value->IsTheHole()); |
1534 Handle<Object> value_handle(value); | 1606 Handle<Object> value_handle(value); |
1535 | 1607 |
1536 // To accommodate both the old and the new api we switch on the | 1608 // To accommodate both the old and the new api we switch on the |
1537 // data structure used to store the callbacks. Eventually proxy | 1609 // data structure used to store the callbacks. Eventually proxy |
1538 // callbacks should be phased out. | 1610 // callbacks should be phased out. |
1539 if (structure->IsProxy()) { | 1611 if (structure->IsProxy()) { |
1540 AccessorDescriptor* callback = | 1612 AccessorDescriptor* callback = |
1541 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); | 1613 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); |
1542 Object* obj = (callback->setter)(this, value, callback->data); | 1614 MaybeObject* obj = (callback->setter)(this, value, callback->data); |
1543 RETURN_IF_SCHEDULED_EXCEPTION(); | 1615 RETURN_IF_SCHEDULED_EXCEPTION(); |
1544 if (obj->IsFailure()) return obj; | 1616 if (obj->IsFailure()) return obj; |
1545 return *value_handle; | 1617 return *value_handle; |
1546 } | 1618 } |
1547 | 1619 |
1548 if (structure->IsAccessorInfo()) { | 1620 if (structure->IsAccessorInfo()) { |
1549 // api style callbacks | 1621 // api style callbacks |
1550 AccessorInfo* data = AccessorInfo::cast(structure); | 1622 AccessorInfo* data = AccessorInfo::cast(structure); |
1551 Object* call_obj = data->setter(); | 1623 Object* call_obj = data->setter(); |
1552 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); | 1624 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); |
(...skipping 24 matching lines...) Expand all Loading... |
1577 return Top::Throw(*Factory::NewTypeError("no_setter_in_callback", | 1649 return Top::Throw(*Factory::NewTypeError("no_setter_in_callback", |
1578 HandleVector(args, 2))); | 1650 HandleVector(args, 2))); |
1579 } | 1651 } |
1580 } | 1652 } |
1581 | 1653 |
1582 UNREACHABLE(); | 1654 UNREACHABLE(); |
1583 return NULL; | 1655 return NULL; |
1584 } | 1656 } |
1585 | 1657 |
1586 | 1658 |
1587 Object* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, | 1659 MaybeObject* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, |
1588 Object* value) { | 1660 Object* value) { |
1589 Handle<Object> value_handle(value); | 1661 Handle<Object> value_handle(value); |
1590 Handle<JSFunction> fun(JSFunction::cast(setter)); | 1662 Handle<JSFunction> fun(JSFunction::cast(setter)); |
1591 Handle<JSObject> self(this); | 1663 Handle<JSObject> self(this); |
1592 #ifdef ENABLE_DEBUGGER_SUPPORT | 1664 #ifdef ENABLE_DEBUGGER_SUPPORT |
1593 // Handle stepping into a setter if step into is active. | 1665 // Handle stepping into a setter if step into is active. |
1594 if (Debug::StepInActive()) { | 1666 if (Debug::StepInActive()) { |
1595 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); | 1667 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); |
1596 } | 1668 } |
1597 #endif | 1669 #endif |
1598 bool has_pending_exception; | 1670 bool has_pending_exception; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 pt != Heap::null_value(); | 1792 pt != Heap::null_value(); |
1721 pt = JSObject::cast(pt)->GetPrototype()) { | 1793 pt = JSObject::cast(pt)->GetPrototype()) { |
1722 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1794 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
1723 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; | 1795 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; |
1724 } | 1796 } |
1725 result->NotFound(); | 1797 result->NotFound(); |
1726 } | 1798 } |
1727 | 1799 |
1728 | 1800 |
1729 // We only need to deal with CALLBACKS and INTERCEPTORS | 1801 // We only need to deal with CALLBACKS and INTERCEPTORS |
1730 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 1802 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, |
1731 String* name, | 1803 String* name, |
1732 Object* value) { | 1804 Object* value) { |
1733 if (!result->IsProperty()) { | 1805 if (!result->IsProperty()) { |
1734 LookupCallbackSetterInPrototypes(name, result); | 1806 LookupCallbackSetterInPrototypes(name, result); |
1735 } | 1807 } |
1736 | 1808 |
1737 if (result->IsProperty()) { | 1809 if (result->IsProperty()) { |
1738 if (!result->IsReadOnly()) { | 1810 if (!result->IsReadOnly()) { |
1739 switch (result->type()) { | 1811 switch (result->type()) { |
1740 case CALLBACKS: { | 1812 case CALLBACKS: { |
1741 Object* obj = result->GetCallbackObject(); | 1813 Object* obj = result->GetCallbackObject(); |
1742 if (obj->IsAccessorInfo()) { | 1814 if (obj->IsAccessorInfo()) { |
(...skipping 24 matching lines...) Expand all Loading... |
1767 } | 1839 } |
1768 } | 1840 } |
1769 | 1841 |
1770 HandleScope scope; | 1842 HandleScope scope; |
1771 Handle<Object> value_handle(value); | 1843 Handle<Object> value_handle(value); |
1772 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1844 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
1773 return *value_handle; | 1845 return *value_handle; |
1774 } | 1846 } |
1775 | 1847 |
1776 | 1848 |
1777 Object* JSObject::SetProperty(LookupResult* result, | 1849 MaybeObject* JSObject::SetProperty(LookupResult* result, |
1778 String* name, | 1850 String* name, |
1779 Object* value, | 1851 Object* value, |
1780 PropertyAttributes attributes) { | 1852 PropertyAttributes attributes) { |
1781 // Make sure that the top context does not change when doing callbacks or | 1853 // Make sure that the top context does not change when doing callbacks or |
1782 // interceptor calls. | 1854 // interceptor calls. |
1783 AssertNoContextChange ncc; | 1855 AssertNoContextChange ncc; |
1784 | 1856 |
1785 // Optimization for 2-byte strings often used as keys in a decompression | 1857 // Optimization for 2-byte strings often used as keys in a decompression |
1786 // dictionary. We make these short keys into symbols to avoid constantly | 1858 // dictionary. We make these short keys into symbols to avoid constantly |
1787 // reallocating them. | 1859 // reallocating them. |
1788 if (!name->IsSymbol() && name->length() <= 2) { | 1860 if (!name->IsSymbol() && name->length() <= 2) { |
1789 Object* symbol_version = Heap::LookupSymbol(name); | 1861 Object* symbol_version; |
1790 if (!symbol_version->IsFailure()) name = String::cast(symbol_version); | 1862 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); |
| 1863 if (maybe_symbol_version->ToObject(&symbol_version)) { |
| 1864 name = String::cast(symbol_version); |
| 1865 } |
| 1866 } |
1791 } | 1867 } |
1792 | 1868 |
1793 // Check access rights if needed. | 1869 // Check access rights if needed. |
1794 if (IsAccessCheckNeeded() | 1870 if (IsAccessCheckNeeded() |
1795 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1871 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
1796 return SetPropertyWithFailedAccessCheck(result, name, value); | 1872 return SetPropertyWithFailedAccessCheck(result, name, value); |
1797 } | 1873 } |
1798 | 1874 |
1799 if (IsJSGlobalProxy()) { | 1875 if (IsJSGlobalProxy()) { |
1800 Object* proto = GetPrototype(); | 1876 Object* proto = GetPrototype(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1876 return value; | 1952 return value; |
1877 } | 1953 } |
1878 | 1954 |
1879 | 1955 |
1880 // Set a real local property, even if it is READ_ONLY. If the property is not | 1956 // Set a real local property, even if it is READ_ONLY. If the property is not |
1881 // present, add it with attributes NONE. This code is an exact clone of | 1957 // present, add it with attributes NONE. This code is an exact clone of |
1882 // SetProperty, with the check for IsReadOnly and the check for a | 1958 // SetProperty, with the check for IsReadOnly and the check for a |
1883 // callback setter removed. The two lines looking up the LookupResult | 1959 // callback setter removed. The two lines looking up the LookupResult |
1884 // result are also added. If one of the functions is changed, the other | 1960 // result are also added. If one of the functions is changed, the other |
1885 // should be. | 1961 // should be. |
1886 Object* JSObject::IgnoreAttributesAndSetLocalProperty( | 1962 MaybeObject* JSObject::IgnoreAttributesAndSetLocalProperty( |
1887 String* name, | 1963 String* name, |
1888 Object* value, | 1964 Object* value, |
1889 PropertyAttributes attributes) { | 1965 PropertyAttributes attributes) { |
1890 // Make sure that the top context does not change when doing callbacks or | 1966 // Make sure that the top context does not change when doing callbacks or |
1891 // interceptor calls. | 1967 // interceptor calls. |
1892 AssertNoContextChange ncc; | 1968 AssertNoContextChange ncc; |
1893 LookupResult result; | 1969 LookupResult result; |
1894 LocalLookup(name, &result); | 1970 LocalLookup(name, &result); |
1895 // Check access rights if needed. | 1971 // Check access rights if needed. |
1896 if (IsAccessCheckNeeded() | 1972 if (IsAccessCheckNeeded() |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 if (HasLocalElement(index)) return NONE; | 2150 if (HasLocalElement(index)) return NONE; |
2075 return ABSENT; | 2151 return ABSENT; |
2076 } | 2152 } |
2077 // Named property. | 2153 // Named property. |
2078 LookupResult result; | 2154 LookupResult result; |
2079 LocalLookup(name, &result); | 2155 LocalLookup(name, &result); |
2080 return GetPropertyAttribute(this, &result, name, false); | 2156 return GetPropertyAttribute(this, &result, name, false); |
2081 } | 2157 } |
2082 | 2158 |
2083 | 2159 |
2084 Object* NormalizedMapCache::Get(JSObject* obj, PropertyNormalizationMode mode) { | 2160 MaybeObject* NormalizedMapCache::Get(JSObject* obj, |
| 2161 PropertyNormalizationMode mode) { |
2085 Map* fast = obj->map(); | 2162 Map* fast = obj->map(); |
2086 int index = Hash(fast) % kEntries; | 2163 int index = Hash(fast) % kEntries; |
2087 Object* result = get(index); | 2164 Object* result = get(index); |
2088 if (result->IsMap() && CheckHit(Map::cast(result), fast, mode)) { | 2165 if (result->IsMap() && CheckHit(Map::cast(result), fast, mode)) { |
2089 #ifdef DEBUG | 2166 #ifdef DEBUG |
2090 if (FLAG_enable_slow_asserts) { | 2167 if (FLAG_enable_slow_asserts) { |
2091 // The cached map should match newly created normalized map bit-by-bit. | 2168 // The cached map should match newly created normalized map bit-by-bit. |
2092 Object* fresh = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); | 2169 Object* fresh; |
2093 if (!fresh->IsFailure()) { | 2170 { MaybeObject* maybe_fresh = |
2094 ASSERT(memcmp(Map::cast(fresh)->address(), | 2171 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); |
2095 Map::cast(result)->address(), | 2172 if (maybe_fresh->ToObject(&fresh)) { |
2096 Map::kSize) == 0); | 2173 ASSERT(memcmp(Map::cast(fresh)->address(), |
| 2174 Map::cast(result)->address(), |
| 2175 Map::kSize) == 0); |
| 2176 } |
2097 } | 2177 } |
2098 } | 2178 } |
2099 #endif | 2179 #endif |
2100 return result; | 2180 return result; |
2101 } | 2181 } |
2102 | 2182 |
2103 result = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); | 2183 { MaybeObject* maybe_result = |
2104 if (result->IsFailure()) return result; | 2184 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); |
| 2185 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2186 } |
2105 set(index, result); | 2187 set(index, result); |
2106 Counters::normalized_maps.Increment(); | 2188 Counters::normalized_maps.Increment(); |
2107 | 2189 |
2108 return result; | 2190 return result; |
2109 } | 2191 } |
2110 | 2192 |
2111 | 2193 |
2112 void NormalizedMapCache::Clear() { | 2194 void NormalizedMapCache::Clear() { |
2113 int entries = length(); | 2195 int entries = length(); |
2114 for (int i = 0; i != entries; i++) { | 2196 for (int i = 0; i != entries; i++) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 slow->prototype() == fast->prototype() && | 2228 slow->prototype() == fast->prototype() && |
2147 slow->inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ? | 2229 slow->inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ? |
2148 0 : | 2230 0 : |
2149 fast->inobject_properties()) && | 2231 fast->inobject_properties()) && |
2150 slow->instance_type() == fast->instance_type() && | 2232 slow->instance_type() == fast->instance_type() && |
2151 slow->bit_field() == fast->bit_field() && | 2233 slow->bit_field() == fast->bit_field() && |
2152 (slow->bit_field2() & ~(1<<Map::kIsShared)) == fast->bit_field2(); | 2234 (slow->bit_field2() & ~(1<<Map::kIsShared)) == fast->bit_field2(); |
2153 } | 2235 } |
2154 | 2236 |
2155 | 2237 |
2156 Object* JSObject::UpdateMapCodeCache(String* name, Code* code) { | 2238 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) { |
2157 if (map()->is_shared()) { | 2239 if (map()->is_shared()) { |
2158 // Fast case maps are never marked as shared. | 2240 // Fast case maps are never marked as shared. |
2159 ASSERT(!HasFastProperties()); | 2241 ASSERT(!HasFastProperties()); |
2160 // Replace the map with an identical copy that can be safely modified. | 2242 // Replace the map with an identical copy that can be safely modified. |
2161 Object* obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, | 2243 Object* obj; |
2162 UNIQUE_NORMALIZED_MAP); | 2244 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, |
2163 if (obj->IsFailure()) return obj; | 2245 UNIQUE_NORMALIZED_MAP); |
| 2246 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2247 } |
2164 Counters::normalized_maps.Increment(); | 2248 Counters::normalized_maps.Increment(); |
2165 | 2249 |
2166 set_map(Map::cast(obj)); | 2250 set_map(Map::cast(obj)); |
2167 } | 2251 } |
2168 return map()->UpdateCodeCache(name, code); | 2252 return map()->UpdateCodeCache(name, code); |
2169 } | 2253 } |
2170 | 2254 |
2171 | 2255 |
2172 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 2256 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
2173 int expected_additional_properties) { | 2257 int expected_additional_properties) { |
2174 if (!HasFastProperties()) return this; | 2258 if (!HasFastProperties()) return this; |
2175 | 2259 |
2176 // The global object is always normalized. | 2260 // The global object is always normalized. |
2177 ASSERT(!IsGlobalObject()); | 2261 ASSERT(!IsGlobalObject()); |
2178 | 2262 |
2179 // Allocate new content. | 2263 // Allocate new content. |
2180 int property_count = map()->NumberOfDescribedProperties(); | 2264 int property_count = map()->NumberOfDescribedProperties(); |
2181 if (expected_additional_properties > 0) { | 2265 if (expected_additional_properties > 0) { |
2182 property_count += expected_additional_properties; | 2266 property_count += expected_additional_properties; |
2183 } else { | 2267 } else { |
2184 property_count += 2; // Make space for two more properties. | 2268 property_count += 2; // Make space for two more properties. |
2185 } | 2269 } |
2186 Object* obj = | 2270 Object* obj; |
2187 StringDictionary::Allocate(property_count); | 2271 { MaybeObject* maybe_obj = |
2188 if (obj->IsFailure()) return obj; | 2272 StringDictionary::Allocate(property_count); |
| 2273 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2274 } |
2189 StringDictionary* dictionary = StringDictionary::cast(obj); | 2275 StringDictionary* dictionary = StringDictionary::cast(obj); |
2190 | 2276 |
2191 DescriptorArray* descs = map()->instance_descriptors(); | 2277 DescriptorArray* descs = map()->instance_descriptors(); |
2192 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 2278 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
2193 PropertyDetails details = descs->GetDetails(i); | 2279 PropertyDetails details = descs->GetDetails(i); |
2194 switch (details.type()) { | 2280 switch (details.type()) { |
2195 case CONSTANT_FUNCTION: { | 2281 case CONSTANT_FUNCTION: { |
2196 PropertyDetails d = | 2282 PropertyDetails d = |
2197 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2283 PropertyDetails(details.attributes(), NORMAL, details.index()); |
2198 Object* value = descs->GetConstantFunction(i); | 2284 Object* value = descs->GetConstantFunction(i); |
2199 Object* result = dictionary->Add(descs->GetKey(i), value, d); | 2285 Object* result; |
2200 if (result->IsFailure()) return result; | 2286 { MaybeObject* maybe_result = |
| 2287 dictionary->Add(descs->GetKey(i), value, d); |
| 2288 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2289 } |
2201 dictionary = StringDictionary::cast(result); | 2290 dictionary = StringDictionary::cast(result); |
2202 break; | 2291 break; |
2203 } | 2292 } |
2204 case FIELD: { | 2293 case FIELD: { |
2205 PropertyDetails d = | 2294 PropertyDetails d = |
2206 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2295 PropertyDetails(details.attributes(), NORMAL, details.index()); |
2207 Object* value = FastPropertyAt(descs->GetFieldIndex(i)); | 2296 Object* value = FastPropertyAt(descs->GetFieldIndex(i)); |
2208 Object* result = dictionary->Add(descs->GetKey(i), value, d); | 2297 Object* result; |
2209 if (result->IsFailure()) return result; | 2298 { MaybeObject* maybe_result = |
| 2299 dictionary->Add(descs->GetKey(i), value, d); |
| 2300 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2301 } |
2210 dictionary = StringDictionary::cast(result); | 2302 dictionary = StringDictionary::cast(result); |
2211 break; | 2303 break; |
2212 } | 2304 } |
2213 case CALLBACKS: { | 2305 case CALLBACKS: { |
2214 PropertyDetails d = | 2306 PropertyDetails d = |
2215 PropertyDetails(details.attributes(), CALLBACKS, details.index()); | 2307 PropertyDetails(details.attributes(), CALLBACKS, details.index()); |
2216 Object* value = descs->GetCallbacksObject(i); | 2308 Object* value = descs->GetCallbacksObject(i); |
2217 Object* result = dictionary->Add(descs->GetKey(i), value, d); | 2309 Object* result; |
2218 if (result->IsFailure()) return result; | 2310 { MaybeObject* maybe_result = |
| 2311 dictionary->Add(descs->GetKey(i), value, d); |
| 2312 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2313 } |
2219 dictionary = StringDictionary::cast(result); | 2314 dictionary = StringDictionary::cast(result); |
2220 break; | 2315 break; |
2221 } | 2316 } |
2222 case MAP_TRANSITION: | 2317 case MAP_TRANSITION: |
2223 case CONSTANT_TRANSITION: | 2318 case CONSTANT_TRANSITION: |
2224 case NULL_DESCRIPTOR: | 2319 case NULL_DESCRIPTOR: |
2225 case INTERCEPTOR: | 2320 case INTERCEPTOR: |
2226 break; | 2321 break; |
2227 default: | 2322 default: |
2228 UNREACHABLE(); | 2323 UNREACHABLE(); |
2229 } | 2324 } |
2230 } | 2325 } |
2231 | 2326 |
2232 // Copy the next enumeration index from instance descriptor. | 2327 // Copy the next enumeration index from instance descriptor. |
2233 int index = map()->instance_descriptors()->NextEnumerationIndex(); | 2328 int index = map()->instance_descriptors()->NextEnumerationIndex(); |
2234 dictionary->SetNextEnumerationIndex(index); | 2329 dictionary->SetNextEnumerationIndex(index); |
2235 | 2330 |
2236 obj = Top::context()->global_context()-> | 2331 { MaybeObject* maybe_obj = Top::context()->global_context()-> |
2237 normalized_map_cache()->Get(this, mode); | 2332 normalized_map_cache()->Get(this, mode); |
2238 if (obj->IsFailure()) return obj; | 2333 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2334 } |
2239 Map* new_map = Map::cast(obj); | 2335 Map* new_map = Map::cast(obj); |
2240 | 2336 |
2241 // We have now successfully allocated all the necessary objects. | 2337 // We have now successfully allocated all the necessary objects. |
2242 // Changes can now be made with the guarantee that all of them take effect. | 2338 // Changes can now be made with the guarantee that all of them take effect. |
2243 | 2339 |
2244 // Resize the object in the heap if necessary. | 2340 // Resize the object in the heap if necessary. |
2245 int new_instance_size = new_map->instance_size(); | 2341 int new_instance_size = new_map->instance_size(); |
2246 int instance_size_delta = map()->instance_size() - new_instance_size; | 2342 int instance_size_delta = map()->instance_size() - new_instance_size; |
2247 ASSERT(instance_size_delta >= 0); | 2343 ASSERT(instance_size_delta >= 0); |
2248 Heap::CreateFillerObjectAt(this->address() + new_instance_size, | 2344 Heap::CreateFillerObjectAt(this->address() + new_instance_size, |
2249 instance_size_delta); | 2345 instance_size_delta); |
2250 | 2346 |
2251 set_map(new_map); | 2347 set_map(new_map); |
2252 | 2348 |
2253 set_properties(dictionary); | 2349 set_properties(dictionary); |
2254 | 2350 |
2255 Counters::props_to_dictionary.Increment(); | 2351 Counters::props_to_dictionary.Increment(); |
2256 | 2352 |
2257 #ifdef DEBUG | 2353 #ifdef DEBUG |
2258 if (FLAG_trace_normalization) { | 2354 if (FLAG_trace_normalization) { |
2259 PrintF("Object properties have been normalized:\n"); | 2355 PrintF("Object properties have been normalized:\n"); |
2260 Print(); | 2356 Print(); |
2261 } | 2357 } |
2262 #endif | 2358 #endif |
2263 return this; | 2359 return this; |
2264 } | 2360 } |
2265 | 2361 |
2266 | 2362 |
2267 Object* JSObject::TransformToFastProperties(int unused_property_fields) { | 2363 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
2268 if (HasFastProperties()) return this; | 2364 if (HasFastProperties()) return this; |
2269 ASSERT(!IsGlobalObject()); | 2365 ASSERT(!IsGlobalObject()); |
2270 return property_dictionary()-> | 2366 return property_dictionary()-> |
2271 TransformPropertiesToFastFor(this, unused_property_fields); | 2367 TransformPropertiesToFastFor(this, unused_property_fields); |
2272 } | 2368 } |
2273 | 2369 |
2274 | 2370 |
2275 Object* JSObject::NormalizeElements() { | 2371 MaybeObject* JSObject::NormalizeElements() { |
2276 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 2372 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
2277 if (HasDictionaryElements()) return this; | 2373 if (HasDictionaryElements()) return this; |
2278 ASSERT(map()->has_fast_elements()); | 2374 ASSERT(map()->has_fast_elements()); |
2279 | 2375 |
2280 Object* obj = map()->GetSlowElementsMap(); | 2376 Object* obj; |
2281 if (obj->IsFailure()) return obj; | 2377 { MaybeObject* maybe_obj = map()->GetSlowElementsMap(); |
| 2378 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2379 } |
2282 Map* new_map = Map::cast(obj); | 2380 Map* new_map = Map::cast(obj); |
2283 | 2381 |
2284 // Get number of entries. | 2382 // Get number of entries. |
2285 FixedArray* array = FixedArray::cast(elements()); | 2383 FixedArray* array = FixedArray::cast(elements()); |
2286 | 2384 |
2287 // Compute the effective length. | 2385 // Compute the effective length. |
2288 int length = IsJSArray() ? | 2386 int length = IsJSArray() ? |
2289 Smi::cast(JSArray::cast(this)->length())->value() : | 2387 Smi::cast(JSArray::cast(this)->length())->value() : |
2290 array->length(); | 2388 array->length(); |
2291 obj = NumberDictionary::Allocate(length); | 2389 { MaybeObject* maybe_obj = NumberDictionary::Allocate(length); |
2292 if (obj->IsFailure()) return obj; | 2390 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2391 } |
2293 NumberDictionary* dictionary = NumberDictionary::cast(obj); | 2392 NumberDictionary* dictionary = NumberDictionary::cast(obj); |
2294 // Copy entries. | 2393 // Copy entries. |
2295 for (int i = 0; i < length; i++) { | 2394 for (int i = 0; i < length; i++) { |
2296 Object* value = array->get(i); | 2395 Object* value = array->get(i); |
2297 if (!value->IsTheHole()) { | 2396 if (!value->IsTheHole()) { |
2298 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 2397 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
2299 Object* result = dictionary->AddNumberEntry(i, array->get(i), details); | 2398 Object* result; |
2300 if (result->IsFailure()) return result; | 2399 { MaybeObject* maybe_result = |
| 2400 dictionary->AddNumberEntry(i, array->get(i), details); |
| 2401 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2402 } |
2301 dictionary = NumberDictionary::cast(result); | 2403 dictionary = NumberDictionary::cast(result); |
2302 } | 2404 } |
2303 } | 2405 } |
2304 // Switch to using the dictionary as the backing storage for | 2406 // Switch to using the dictionary as the backing storage for |
2305 // elements. Set the new map first to satify the elements type | 2407 // elements. Set the new map first to satify the elements type |
2306 // assert in set_elements(). | 2408 // assert in set_elements(). |
2307 set_map(new_map); | 2409 set_map(new_map); |
2308 set_elements(dictionary); | 2410 set_elements(dictionary); |
2309 | 2411 |
2310 Counters::elements_to_dictionary.Increment(); | 2412 Counters::elements_to_dictionary.Increment(); |
2311 | 2413 |
2312 #ifdef DEBUG | 2414 #ifdef DEBUG |
2313 if (FLAG_trace_normalization) { | 2415 if (FLAG_trace_normalization) { |
2314 PrintF("Object elements have been normalized:\n"); | 2416 PrintF("Object elements have been normalized:\n"); |
2315 Print(); | 2417 Print(); |
2316 } | 2418 } |
2317 #endif | 2419 #endif |
2318 | 2420 |
2319 return this; | 2421 return this; |
2320 } | 2422 } |
2321 | 2423 |
2322 | 2424 |
2323 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { | 2425 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, |
| 2426 DeleteMode mode) { |
2324 // Check local property, ignore interceptor. | 2427 // Check local property, ignore interceptor. |
2325 LookupResult result; | 2428 LookupResult result; |
2326 LocalLookupRealNamedProperty(name, &result); | 2429 LocalLookupRealNamedProperty(name, &result); |
2327 if (!result.IsProperty()) return Heap::true_value(); | 2430 if (!result.IsProperty()) return Heap::true_value(); |
2328 | 2431 |
2329 // Normalize object if needed. | 2432 // Normalize object if needed. |
2330 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2433 Object* obj; |
2331 if (obj->IsFailure()) return obj; | 2434 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2435 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2436 } |
2332 | 2437 |
2333 return DeleteNormalizedProperty(name, mode); | 2438 return DeleteNormalizedProperty(name, mode); |
2334 } | 2439 } |
2335 | 2440 |
2336 | 2441 |
2337 Object* JSObject::DeletePropertyWithInterceptor(String* name) { | 2442 MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) { |
2338 HandleScope scope; | 2443 HandleScope scope; |
2339 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 2444 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
2340 Handle<String> name_handle(name); | 2445 Handle<String> name_handle(name); |
2341 Handle<JSObject> this_handle(this); | 2446 Handle<JSObject> this_handle(this); |
2342 if (!interceptor->deleter()->IsUndefined()) { | 2447 if (!interceptor->deleter()->IsUndefined()) { |
2343 v8::NamedPropertyDeleter deleter = | 2448 v8::NamedPropertyDeleter deleter = |
2344 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); | 2449 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); |
2345 LOG(ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); | 2450 LOG(ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); |
2346 CustomArguments args(interceptor->data(), this, this); | 2451 CustomArguments args(interceptor->data(), this, this); |
2347 v8::AccessorInfo info(args.end()); | 2452 v8::AccessorInfo info(args.end()); |
2348 v8::Handle<v8::Boolean> result; | 2453 v8::Handle<v8::Boolean> result; |
2349 { | 2454 { |
2350 // Leaving JavaScript. | 2455 // Leaving JavaScript. |
2351 VMState state(EXTERNAL); | 2456 VMState state(EXTERNAL); |
2352 result = deleter(v8::Utils::ToLocal(name_handle), info); | 2457 result = deleter(v8::Utils::ToLocal(name_handle), info); |
2353 } | 2458 } |
2354 RETURN_IF_SCHEDULED_EXCEPTION(); | 2459 RETURN_IF_SCHEDULED_EXCEPTION(); |
2355 if (!result.IsEmpty()) { | 2460 if (!result.IsEmpty()) { |
2356 ASSERT(result->IsBoolean()); | 2461 ASSERT(result->IsBoolean()); |
2357 return *v8::Utils::OpenHandle(*result); | 2462 return *v8::Utils::OpenHandle(*result); |
2358 } | 2463 } |
2359 } | 2464 } |
2360 Object* raw_result = | 2465 MaybeObject* raw_result = |
2361 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 2466 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); |
2362 RETURN_IF_SCHEDULED_EXCEPTION(); | 2467 RETURN_IF_SCHEDULED_EXCEPTION(); |
2363 return raw_result; | 2468 return raw_result; |
2364 } | 2469 } |
2365 | 2470 |
2366 | 2471 |
2367 Object* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2472 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, |
2368 DeleteMode mode) { | 2473 DeleteMode mode) { |
2369 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 2474 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
2370 switch (GetElementsKind()) { | 2475 switch (GetElementsKind()) { |
2371 case FAST_ELEMENTS: { | 2476 case FAST_ELEMENTS: { |
2372 Object* obj = EnsureWritableFastElements(); | 2477 Object* obj; |
2373 if (obj->IsFailure()) return obj; | 2478 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 2479 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2480 } |
2374 uint32_t length = IsJSArray() ? | 2481 uint32_t length = IsJSArray() ? |
2375 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2482 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
2376 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2483 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
2377 if (index < length) { | 2484 if (index < length) { |
2378 FixedArray::cast(elements())->set_the_hole(index); | 2485 FixedArray::cast(elements())->set_the_hole(index); |
2379 } | 2486 } |
2380 break; | 2487 break; |
2381 } | 2488 } |
2382 case DICTIONARY_ELEMENTS: { | 2489 case DICTIONARY_ELEMENTS: { |
2383 NumberDictionary* dictionary = element_dictionary(); | 2490 NumberDictionary* dictionary = element_dictionary(); |
2384 int entry = dictionary->FindEntry(index); | 2491 int entry = dictionary->FindEntry(index); |
2385 if (entry != NumberDictionary::kNotFound) { | 2492 if (entry != NumberDictionary::kNotFound) { |
2386 return dictionary->DeleteProperty(entry, mode); | 2493 return dictionary->DeleteProperty(entry, mode); |
2387 } | 2494 } |
2388 break; | 2495 break; |
2389 } | 2496 } |
2390 default: | 2497 default: |
2391 UNREACHABLE(); | 2498 UNREACHABLE(); |
2392 break; | 2499 break; |
2393 } | 2500 } |
2394 return Heap::true_value(); | 2501 return Heap::true_value(); |
2395 } | 2502 } |
2396 | 2503 |
2397 | 2504 |
2398 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2505 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
2399 // Make sure that the top context does not change when doing | 2506 // Make sure that the top context does not change when doing |
2400 // callbacks or interceptor calls. | 2507 // callbacks or interceptor calls. |
2401 AssertNoContextChange ncc; | 2508 AssertNoContextChange ncc; |
2402 HandleScope scope; | 2509 HandleScope scope; |
2403 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 2510 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
2404 if (interceptor->deleter()->IsUndefined()) return Heap::false_value(); | 2511 if (interceptor->deleter()->IsUndefined()) return Heap::false_value(); |
2405 v8::IndexedPropertyDeleter deleter = | 2512 v8::IndexedPropertyDeleter deleter = |
2406 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); | 2513 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); |
2407 Handle<JSObject> this_handle(this); | 2514 Handle<JSObject> this_handle(this); |
2408 LOG(ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); | 2515 LOG(ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); |
2409 CustomArguments args(interceptor->data(), this, this); | 2516 CustomArguments args(interceptor->data(), this, this); |
2410 v8::AccessorInfo info(args.end()); | 2517 v8::AccessorInfo info(args.end()); |
2411 v8::Handle<v8::Boolean> result; | 2518 v8::Handle<v8::Boolean> result; |
2412 { | 2519 { |
2413 // Leaving JavaScript. | 2520 // Leaving JavaScript. |
2414 VMState state(EXTERNAL); | 2521 VMState state(EXTERNAL); |
2415 result = deleter(index, info); | 2522 result = deleter(index, info); |
2416 } | 2523 } |
2417 RETURN_IF_SCHEDULED_EXCEPTION(); | 2524 RETURN_IF_SCHEDULED_EXCEPTION(); |
2418 if (!result.IsEmpty()) { | 2525 if (!result.IsEmpty()) { |
2419 ASSERT(result->IsBoolean()); | 2526 ASSERT(result->IsBoolean()); |
2420 return *v8::Utils::OpenHandle(*result); | 2527 return *v8::Utils::OpenHandle(*result); |
2421 } | 2528 } |
2422 Object* raw_result = | 2529 MaybeObject* raw_result = |
2423 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); | 2530 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); |
2424 RETURN_IF_SCHEDULED_EXCEPTION(); | 2531 RETURN_IF_SCHEDULED_EXCEPTION(); |
2425 return raw_result; | 2532 return raw_result; |
2426 } | 2533 } |
2427 | 2534 |
2428 | 2535 |
2429 Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 2536 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
2430 // Check access rights if needed. | 2537 // Check access rights if needed. |
2431 if (IsAccessCheckNeeded() && | 2538 if (IsAccessCheckNeeded() && |
2432 !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 2539 !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
2433 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2540 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
2434 return Heap::false_value(); | 2541 return Heap::false_value(); |
2435 } | 2542 } |
2436 | 2543 |
2437 if (IsJSGlobalProxy()) { | 2544 if (IsJSGlobalProxy()) { |
2438 Object* proto = GetPrototype(); | 2545 Object* proto = GetPrototype(); |
2439 if (proto->IsNull()) return Heap::false_value(); | 2546 if (proto->IsNull()) return Heap::false_value(); |
2440 ASSERT(proto->IsJSGlobalObject()); | 2547 ASSERT(proto->IsJSGlobalObject()); |
2441 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); | 2548 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); |
2442 } | 2549 } |
2443 | 2550 |
2444 if (HasIndexedInterceptor()) { | 2551 if (HasIndexedInterceptor()) { |
2445 // Skip interceptor if forcing deletion. | 2552 // Skip interceptor if forcing deletion. |
2446 if (mode == FORCE_DELETION) { | 2553 if (mode == FORCE_DELETION) { |
2447 return DeleteElementPostInterceptor(index, mode); | 2554 return DeleteElementPostInterceptor(index, mode); |
2448 } | 2555 } |
2449 return DeleteElementWithInterceptor(index); | 2556 return DeleteElementWithInterceptor(index); |
2450 } | 2557 } |
2451 | 2558 |
2452 switch (GetElementsKind()) { | 2559 switch (GetElementsKind()) { |
2453 case FAST_ELEMENTS: { | 2560 case FAST_ELEMENTS: { |
2454 Object* obj = EnsureWritableFastElements(); | 2561 Object* obj; |
2455 if (obj->IsFailure()) return obj; | 2562 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 2563 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2564 } |
2456 uint32_t length = IsJSArray() ? | 2565 uint32_t length = IsJSArray() ? |
2457 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2566 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
2458 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2567 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
2459 if (index < length) { | 2568 if (index < length) { |
2460 FixedArray::cast(elements())->set_the_hole(index); | 2569 FixedArray::cast(elements())->set_the_hole(index); |
2461 } | 2570 } |
2462 break; | 2571 break; |
2463 } | 2572 } |
2464 case PIXEL_ELEMENTS: | 2573 case PIXEL_ELEMENTS: |
2465 case EXTERNAL_BYTE_ELEMENTS: | 2574 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 15 matching lines...) Expand all Loading... |
2481 break; | 2590 break; |
2482 } | 2591 } |
2483 default: | 2592 default: |
2484 UNREACHABLE(); | 2593 UNREACHABLE(); |
2485 break; | 2594 break; |
2486 } | 2595 } |
2487 return Heap::true_value(); | 2596 return Heap::true_value(); |
2488 } | 2597 } |
2489 | 2598 |
2490 | 2599 |
2491 Object* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 2600 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
2492 // ECMA-262, 3rd, 8.6.2.5 | 2601 // ECMA-262, 3rd, 8.6.2.5 |
2493 ASSERT(name->IsString()); | 2602 ASSERT(name->IsString()); |
2494 | 2603 |
2495 // Check access rights if needed. | 2604 // Check access rights if needed. |
2496 if (IsAccessCheckNeeded() && | 2605 if (IsAccessCheckNeeded() && |
2497 !Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) { | 2606 !Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) { |
2498 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2607 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
2499 return Heap::false_value(); | 2608 return Heap::false_value(); |
2500 } | 2609 } |
2501 | 2610 |
(...skipping 17 matching lines...) Expand all Loading... |
2519 } | 2628 } |
2520 // Check for interceptor. | 2629 // Check for interceptor. |
2521 if (result.type() == INTERCEPTOR) { | 2630 if (result.type() == INTERCEPTOR) { |
2522 // Skip interceptor if forcing a deletion. | 2631 // Skip interceptor if forcing a deletion. |
2523 if (mode == FORCE_DELETION) { | 2632 if (mode == FORCE_DELETION) { |
2524 return DeletePropertyPostInterceptor(name, mode); | 2633 return DeletePropertyPostInterceptor(name, mode); |
2525 } | 2634 } |
2526 return DeletePropertyWithInterceptor(name); | 2635 return DeletePropertyWithInterceptor(name); |
2527 } | 2636 } |
2528 // Normalize object if needed. | 2637 // Normalize object if needed. |
2529 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2638 Object* obj; |
2530 if (obj->IsFailure()) return obj; | 2639 { MaybeObject* maybe_obj = |
| 2640 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2641 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2642 } |
2531 // Make sure the properties are normalized before removing the entry. | 2643 // Make sure the properties are normalized before removing the entry. |
2532 return DeleteNormalizedProperty(name, mode); | 2644 return DeleteNormalizedProperty(name, mode); |
2533 } | 2645 } |
2534 } | 2646 } |
2535 | 2647 |
2536 | 2648 |
2537 // Check whether this object references another object. | 2649 // Check whether this object references another object. |
2538 bool JSObject::ReferencesObject(Object* obj) { | 2650 bool JSObject::ReferencesObject(Object* obj) { |
2539 AssertNoAllocation no_alloc; | 2651 AssertNoAllocation no_alloc; |
2540 | 2652 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2626 if (context->has_extension()) { | 2738 if (context->has_extension()) { |
2627 return context->extension()->ReferencesObject(obj); | 2739 return context->extension()->ReferencesObject(obj); |
2628 } | 2740 } |
2629 } | 2741 } |
2630 | 2742 |
2631 // No references to object. | 2743 // No references to object. |
2632 return false; | 2744 return false; |
2633 } | 2745 } |
2634 | 2746 |
2635 | 2747 |
2636 Object* JSObject::PreventExtensions() { | 2748 MaybeObject* JSObject::PreventExtensions() { |
2637 // If there are fast elements we normalize. | 2749 // If there are fast elements we normalize. |
2638 if (HasFastElements()) { | 2750 if (HasFastElements()) { |
2639 Object* ok = NormalizeElements(); | 2751 Object* ok; |
2640 if (ok->IsFailure()) return ok; | 2752 { MaybeObject* maybe_ok = NormalizeElements(); |
| 2753 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 2754 } |
2641 } | 2755 } |
2642 // Make sure that we never go back to fast case. | 2756 // Make sure that we never go back to fast case. |
2643 element_dictionary()->set_requires_slow_elements(); | 2757 element_dictionary()->set_requires_slow_elements(); |
2644 | 2758 |
2645 // Do a map transition, other objects with this map may still | 2759 // Do a map transition, other objects with this map may still |
2646 // be extensible. | 2760 // be extensible. |
2647 Object* new_map = map()->CopyDropTransitions(); | 2761 Object* new_map; |
2648 if (new_map->IsFailure()) return new_map; | 2762 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); |
| 2763 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 2764 } |
2649 Map::cast(new_map)->set_is_extensible(false); | 2765 Map::cast(new_map)->set_is_extensible(false); |
2650 set_map(Map::cast(new_map)); | 2766 set_map(Map::cast(new_map)); |
2651 ASSERT(!map()->is_extensible()); | 2767 ASSERT(!map()->is_extensible()); |
2652 return new_map; | 2768 return new_map; |
2653 } | 2769 } |
2654 | 2770 |
2655 | 2771 |
2656 // Tests for the fast common case for property enumeration: | 2772 // Tests for the fast common case for property enumeration: |
2657 // - This object and all prototypes has an enum cache (which means that it has | 2773 // - This object and all prototypes has an enum cache (which means that it has |
2658 // no interceptors and needs no access checks). | 2774 // no interceptors and needs no access checks). |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2772 for (Object* current = this; | 2888 for (Object* current = this; |
2773 current != Heap::null_value(); | 2889 current != Heap::null_value(); |
2774 current = JSObject::cast(current)->GetPrototype()) { | 2890 current = JSObject::cast(current)->GetPrototype()) { |
2775 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 2891 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
2776 if (result->IsProperty() && result->type() == CALLBACKS) return; | 2892 if (result->IsProperty() && result->type() == CALLBACKS) return; |
2777 } | 2893 } |
2778 result->NotFound(); | 2894 result->NotFound(); |
2779 } | 2895 } |
2780 | 2896 |
2781 | 2897 |
2782 Object* JSObject::DefineGetterSetter(String* name, | 2898 MaybeObject* JSObject::DefineGetterSetter(String* name, |
2783 PropertyAttributes attributes) { | 2899 PropertyAttributes attributes) { |
2784 // Make sure that the top context does not change when doing callbacks or | 2900 // Make sure that the top context does not change when doing callbacks or |
2785 // interceptor calls. | 2901 // interceptor calls. |
2786 AssertNoContextChange ncc; | 2902 AssertNoContextChange ncc; |
2787 | 2903 |
2788 // Try to flatten before operating on the string. | 2904 // Try to flatten before operating on the string. |
2789 name->TryFlatten(); | 2905 name->TryFlatten(); |
2790 | 2906 |
2791 if (!CanSetCallback(name)) { | 2907 if (!CanSetCallback(name)) { |
2792 return Heap::undefined_value(); | 2908 return Heap::undefined_value(); |
2793 } | 2909 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2843 // Need to preserve old getters/setters. | 2959 // Need to preserve old getters/setters. |
2844 if (obj->IsFixedArray()) { | 2960 if (obj->IsFixedArray()) { |
2845 // Use set to update attributes. | 2961 // Use set to update attributes. |
2846 return SetPropertyCallback(name, obj, attributes); | 2962 return SetPropertyCallback(name, obj, attributes); |
2847 } | 2963 } |
2848 } | 2964 } |
2849 } | 2965 } |
2850 } | 2966 } |
2851 | 2967 |
2852 // Allocate the fixed array to hold getter and setter. | 2968 // Allocate the fixed array to hold getter and setter. |
2853 Object* structure = Heap::AllocateFixedArray(2, TENURED); | 2969 Object* structure; |
2854 if (structure->IsFailure()) return structure; | 2970 { MaybeObject* maybe_structure = Heap::AllocateFixedArray(2, TENURED); |
| 2971 if (!maybe_structure->ToObject(&structure)) return maybe_structure; |
| 2972 } |
2855 | 2973 |
2856 if (is_element) { | 2974 if (is_element) { |
2857 return SetElementCallback(index, structure, attributes); | 2975 return SetElementCallback(index, structure, attributes); |
2858 } else { | 2976 } else { |
2859 return SetPropertyCallback(name, structure, attributes); | 2977 return SetPropertyCallback(name, structure, attributes); |
2860 } | 2978 } |
2861 } | 2979 } |
2862 | 2980 |
2863 | 2981 |
2864 bool JSObject::CanSetCallback(String* name) { | 2982 bool JSObject::CanSetCallback(String* name) { |
(...skipping 13 matching lines...) Expand all Loading... |
2878 if (obj->IsAccessorInfo() && | 2996 if (obj->IsAccessorInfo() && |
2879 AccessorInfo::cast(obj)->prohibits_overwriting()) { | 2997 AccessorInfo::cast(obj)->prohibits_overwriting()) { |
2880 return false; | 2998 return false; |
2881 } | 2999 } |
2882 } | 3000 } |
2883 | 3001 |
2884 return true; | 3002 return true; |
2885 } | 3003 } |
2886 | 3004 |
2887 | 3005 |
2888 Object* JSObject::SetElementCallback(uint32_t index, | 3006 MaybeObject* JSObject::SetElementCallback(uint32_t index, |
2889 Object* structure, | 3007 Object* structure, |
2890 PropertyAttributes attributes) { | 3008 PropertyAttributes attributes) { |
2891 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 3009 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
2892 | 3010 |
2893 // Normalize elements to make this operation simple. | 3011 // Normalize elements to make this operation simple. |
2894 Object* ok = NormalizeElements(); | 3012 Object* ok; |
2895 if (ok->IsFailure()) return ok; | 3013 { MaybeObject* maybe_ok = NormalizeElements(); |
| 3014 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3015 } |
2896 | 3016 |
2897 // Update the dictionary with the new CALLBACKS property. | 3017 // Update the dictionary with the new CALLBACKS property. |
2898 Object* dict = | 3018 Object* dict; |
2899 element_dictionary()->Set(index, structure, details); | 3019 { MaybeObject* maybe_dict = |
2900 if (dict->IsFailure()) return dict; | 3020 element_dictionary()->Set(index, structure, details); |
| 3021 if (!maybe_dict->ToObject(&dict)) return maybe_dict; |
| 3022 } |
2901 | 3023 |
2902 NumberDictionary* elements = NumberDictionary::cast(dict); | 3024 NumberDictionary* elements = NumberDictionary::cast(dict); |
2903 elements->set_requires_slow_elements(); | 3025 elements->set_requires_slow_elements(); |
2904 // Set the potential new dictionary on the object. | 3026 // Set the potential new dictionary on the object. |
2905 set_elements(elements); | 3027 set_elements(elements); |
2906 | 3028 |
2907 return structure; | 3029 return structure; |
2908 } | 3030 } |
2909 | 3031 |
2910 | 3032 |
2911 Object* JSObject::SetPropertyCallback(String* name, | 3033 MaybeObject* JSObject::SetPropertyCallback(String* name, |
2912 Object* structure, | 3034 Object* structure, |
2913 PropertyAttributes attributes) { | 3035 PropertyAttributes attributes) { |
2914 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 3036 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
2915 | 3037 |
2916 bool convert_back_to_fast = HasFastProperties() && | 3038 bool convert_back_to_fast = HasFastProperties() && |
2917 (map()->instance_descriptors()->number_of_descriptors() | 3039 (map()->instance_descriptors()->number_of_descriptors() |
2918 < DescriptorArray::kMaxNumberOfDescriptors); | 3040 < DescriptorArray::kMaxNumberOfDescriptors); |
2919 | 3041 |
2920 // Normalize object to make this operation simple. | 3042 // Normalize object to make this operation simple. |
2921 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 3043 Object* ok; |
2922 if (ok->IsFailure()) return ok; | 3044 { MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 3045 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3046 } |
2923 | 3047 |
2924 // For the global object allocate a new map to invalidate the global inline | 3048 // For the global object allocate a new map to invalidate the global inline |
2925 // caches which have a global property cell reference directly in the code. | 3049 // caches which have a global property cell reference directly in the code. |
2926 if (IsGlobalObject()) { | 3050 if (IsGlobalObject()) { |
2927 Object* new_map = map()->CopyDropDescriptors(); | 3051 Object* new_map; |
2928 if (new_map->IsFailure()) return new_map; | 3052 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 3053 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 3054 } |
2929 set_map(Map::cast(new_map)); | 3055 set_map(Map::cast(new_map)); |
2930 } | 3056 } |
2931 | 3057 |
2932 // Update the dictionary with the new CALLBACKS property. | 3058 // Update the dictionary with the new CALLBACKS property. |
2933 Object* result = SetNormalizedProperty(name, structure, details); | 3059 Object* result; |
2934 if (result->IsFailure()) return result; | 3060 { MaybeObject* maybe_result = SetNormalizedProperty(name, structure, details); |
| 3061 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3062 } |
2935 | 3063 |
2936 if (convert_back_to_fast) { | 3064 if (convert_back_to_fast) { |
2937 ok = TransformToFastProperties(0); | 3065 { MaybeObject* maybe_ok = TransformToFastProperties(0); |
2938 if (ok->IsFailure()) return ok; | 3066 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3067 } |
2939 } | 3068 } |
2940 return result; | 3069 return result; |
2941 } | 3070 } |
2942 | 3071 |
2943 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, | 3072 MaybeObject* JSObject::DefineAccessor(String* name, |
2944 PropertyAttributes attributes) { | 3073 bool is_getter, |
| 3074 JSFunction* fun, |
| 3075 PropertyAttributes attributes) { |
2945 // Check access rights if needed. | 3076 // Check access rights if needed. |
2946 if (IsAccessCheckNeeded() && | 3077 if (IsAccessCheckNeeded() && |
2947 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 3078 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
2948 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 3079 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
2949 return Heap::undefined_value(); | 3080 return Heap::undefined_value(); |
2950 } | 3081 } |
2951 | 3082 |
2952 if (IsJSGlobalProxy()) { | 3083 if (IsJSGlobalProxy()) { |
2953 Object* proto = GetPrototype(); | 3084 Object* proto = GetPrototype(); |
2954 if (proto->IsNull()) return this; | 3085 if (proto->IsNull()) return this; |
2955 ASSERT(proto->IsJSGlobalObject()); | 3086 ASSERT(proto->IsJSGlobalObject()); |
2956 return JSObject::cast(proto)->DefineAccessor(name, is_getter, | 3087 return JSObject::cast(proto)->DefineAccessor(name, is_getter, |
2957 fun, attributes); | 3088 fun, attributes); |
2958 } | 3089 } |
2959 | 3090 |
2960 Object* array = DefineGetterSetter(name, attributes); | 3091 Object* array; |
2961 if (array->IsFailure() || array->IsUndefined()) return array; | 3092 { MaybeObject* maybe_array = DefineGetterSetter(name, attributes); |
| 3093 if (!maybe_array->ToObject(&array)) return maybe_array; |
| 3094 } |
| 3095 if (array->IsUndefined()) return array; |
2962 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); | 3096 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); |
2963 return this; | 3097 return this; |
2964 } | 3098 } |
2965 | 3099 |
2966 | 3100 |
2967 Object* JSObject::DefineAccessor(AccessorInfo* info) { | 3101 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { |
2968 String* name = String::cast(info->name()); | 3102 String* name = String::cast(info->name()); |
2969 // Check access rights if needed. | 3103 // Check access rights if needed. |
2970 if (IsAccessCheckNeeded() && | 3104 if (IsAccessCheckNeeded() && |
2971 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 3105 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
2972 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 3106 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
2973 return Heap::undefined_value(); | 3107 return Heap::undefined_value(); |
2974 } | 3108 } |
2975 | 3109 |
2976 if (IsJSGlobalProxy()) { | 3110 if (IsJSGlobalProxy()) { |
2977 Object* proto = GetPrototype(); | 3111 Object* proto = GetPrototype(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3012 // Ignore getters and setters on pixel and external array | 3146 // Ignore getters and setters on pixel and external array |
3013 // elements. | 3147 // elements. |
3014 return Heap::undefined_value(); | 3148 return Heap::undefined_value(); |
3015 case DICTIONARY_ELEMENTS: | 3149 case DICTIONARY_ELEMENTS: |
3016 break; | 3150 break; |
3017 default: | 3151 default: |
3018 UNREACHABLE(); | 3152 UNREACHABLE(); |
3019 break; | 3153 break; |
3020 } | 3154 } |
3021 | 3155 |
3022 Object* ok = SetElementCallback(index, info, info->property_attributes()); | 3156 Object* ok; |
3023 if (ok->IsFailure()) return ok; | 3157 { MaybeObject* maybe_ok = |
| 3158 SetElementCallback(index, info, info->property_attributes()); |
| 3159 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3160 } |
3024 } else { | 3161 } else { |
3025 // Lookup the name. | 3162 // Lookup the name. |
3026 LookupResult result; | 3163 LookupResult result; |
3027 LocalLookup(name, &result); | 3164 LocalLookup(name, &result); |
3028 // ES5 forbids turning a property into an accessor if it's not | 3165 // ES5 forbids turning a property into an accessor if it's not |
3029 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). | 3166 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). |
3030 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { | 3167 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { |
3031 return Heap::undefined_value(); | 3168 return Heap::undefined_value(); |
3032 } | 3169 } |
3033 Object* ok = SetPropertyCallback(name, info, info->property_attributes()); | 3170 Object* ok; |
3034 if (ok->IsFailure()) return ok; | 3171 { MaybeObject* maybe_ok = |
| 3172 SetPropertyCallback(name, info, info->property_attributes()); |
| 3173 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3174 } |
3035 } | 3175 } |
3036 | 3176 |
3037 return this; | 3177 return this; |
3038 } | 3178 } |
3039 | 3179 |
3040 | 3180 |
3041 Object* JSObject::LookupAccessor(String* name, bool is_getter) { | 3181 Object* JSObject::LookupAccessor(String* name, bool is_getter) { |
3042 // Make sure that the top context does not change when doing callbacks or | 3182 // Make sure that the top context does not change when doing callbacks or |
3043 // interceptor calls. | 3183 // interceptor calls. |
3044 AssertNoContextChange ncc; | 3184 AssertNoContextChange ncc; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3107 } | 3247 } |
3108 } | 3248 } |
3109 } | 3249 } |
3110 return Heap::undefined_value(); | 3250 return Heap::undefined_value(); |
3111 } else { | 3251 } else { |
3112 return property_dictionary()->SlowReverseLookup(value); | 3252 return property_dictionary()->SlowReverseLookup(value); |
3113 } | 3253 } |
3114 } | 3254 } |
3115 | 3255 |
3116 | 3256 |
3117 Object* Map::CopyDropDescriptors() { | 3257 MaybeObject* Map::CopyDropDescriptors() { |
3118 Object* result = Heap::AllocateMap(instance_type(), instance_size()); | 3258 Object* result; |
3119 if (result->IsFailure()) return result; | 3259 { MaybeObject* maybe_result = |
| 3260 Heap::AllocateMap(instance_type(), instance_size()); |
| 3261 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3262 } |
3120 Map::cast(result)->set_prototype(prototype()); | 3263 Map::cast(result)->set_prototype(prototype()); |
3121 Map::cast(result)->set_constructor(constructor()); | 3264 Map::cast(result)->set_constructor(constructor()); |
3122 // Don't copy descriptors, so map transitions always remain a forest. | 3265 // Don't copy descriptors, so map transitions always remain a forest. |
3123 // If we retained the same descriptors we would have two maps | 3266 // If we retained the same descriptors we would have two maps |
3124 // pointing to the same transition which is bad because the garbage | 3267 // pointing to the same transition which is bad because the garbage |
3125 // collector relies on being able to reverse pointers from transitions | 3268 // collector relies on being able to reverse pointers from transitions |
3126 // to maps. If properties need to be retained use CopyDropTransitions. | 3269 // to maps. If properties need to be retained use CopyDropTransitions. |
3127 Map::cast(result)->set_instance_descriptors(Heap::empty_descriptor_array()); | 3270 Map::cast(result)->set_instance_descriptors(Heap::empty_descriptor_array()); |
3128 // Please note instance_type and instance_size are set when allocated. | 3271 // Please note instance_type and instance_size are set when allocated. |
3129 Map::cast(result)->set_inobject_properties(inobject_properties()); | 3272 Map::cast(result)->set_inobject_properties(inobject_properties()); |
3130 Map::cast(result)->set_unused_property_fields(unused_property_fields()); | 3273 Map::cast(result)->set_unused_property_fields(unused_property_fields()); |
3131 | 3274 |
3132 // If the map has pre-allocated properties always start out with a descriptor | 3275 // If the map has pre-allocated properties always start out with a descriptor |
3133 // array describing these properties. | 3276 // array describing these properties. |
3134 if (pre_allocated_property_fields() > 0) { | 3277 if (pre_allocated_property_fields() > 0) { |
3135 ASSERT(constructor()->IsJSFunction()); | 3278 ASSERT(constructor()->IsJSFunction()); |
3136 JSFunction* ctor = JSFunction::cast(constructor()); | 3279 JSFunction* ctor = JSFunction::cast(constructor()); |
3137 Object* descriptors = | 3280 Object* descriptors; |
3138 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); | 3281 { MaybeObject* maybe_descriptors = |
3139 if (descriptors->IsFailure()) return descriptors; | 3282 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); |
| 3283 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; |
| 3284 } |
3140 Map::cast(result)->set_instance_descriptors( | 3285 Map::cast(result)->set_instance_descriptors( |
3141 DescriptorArray::cast(descriptors)); | 3286 DescriptorArray::cast(descriptors)); |
3142 Map::cast(result)->set_pre_allocated_property_fields( | 3287 Map::cast(result)->set_pre_allocated_property_fields( |
3143 pre_allocated_property_fields()); | 3288 pre_allocated_property_fields()); |
3144 } | 3289 } |
3145 Map::cast(result)->set_bit_field(bit_field()); | 3290 Map::cast(result)->set_bit_field(bit_field()); |
3146 Map::cast(result)->set_bit_field2(bit_field2()); | 3291 Map::cast(result)->set_bit_field2(bit_field2()); |
3147 Map::cast(result)->set_is_shared(false); | 3292 Map::cast(result)->set_is_shared(false); |
3148 Map::cast(result)->ClearCodeCache(); | 3293 Map::cast(result)->ClearCodeCache(); |
3149 return result; | 3294 return result; |
3150 } | 3295 } |
3151 | 3296 |
3152 | 3297 |
3153 Object* Map::CopyNormalized(PropertyNormalizationMode mode, | 3298 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, |
3154 NormalizedMapSharingMode sharing) { | 3299 NormalizedMapSharingMode sharing) { |
3155 int new_instance_size = instance_size(); | 3300 int new_instance_size = instance_size(); |
3156 if (mode == CLEAR_INOBJECT_PROPERTIES) { | 3301 if (mode == CLEAR_INOBJECT_PROPERTIES) { |
3157 new_instance_size -= inobject_properties() * kPointerSize; | 3302 new_instance_size -= inobject_properties() * kPointerSize; |
3158 } | 3303 } |
3159 | 3304 |
3160 Object* result = Heap::AllocateMap(instance_type(), new_instance_size); | 3305 Object* result; |
3161 if (result->IsFailure()) return result; | 3306 { MaybeObject* maybe_result = |
| 3307 Heap::AllocateMap(instance_type(), new_instance_size); |
| 3308 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3309 } |
3162 | 3310 |
3163 if (mode != CLEAR_INOBJECT_PROPERTIES) { | 3311 if (mode != CLEAR_INOBJECT_PROPERTIES) { |
3164 Map::cast(result)->set_inobject_properties(inobject_properties()); | 3312 Map::cast(result)->set_inobject_properties(inobject_properties()); |
3165 } | 3313 } |
3166 | 3314 |
3167 Map::cast(result)->set_prototype(prototype()); | 3315 Map::cast(result)->set_prototype(prototype()); |
3168 Map::cast(result)->set_constructor(constructor()); | 3316 Map::cast(result)->set_constructor(constructor()); |
3169 | 3317 |
3170 Map::cast(result)->set_bit_field(bit_field()); | 3318 Map::cast(result)->set_bit_field(bit_field()); |
3171 Map::cast(result)->set_bit_field2(bit_field2()); | 3319 Map::cast(result)->set_bit_field2(bit_field2()); |
3172 | 3320 |
3173 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP); | 3321 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP); |
3174 | 3322 |
3175 #ifdef DEBUG | 3323 #ifdef DEBUG |
3176 if (Map::cast(result)->is_shared()) { | 3324 if (Map::cast(result)->is_shared()) { |
3177 Map::cast(result)->SharedMapVerify(); | 3325 Map::cast(result)->SharedMapVerify(); |
3178 } | 3326 } |
3179 #endif | 3327 #endif |
3180 | 3328 |
3181 return result; | 3329 return result; |
3182 } | 3330 } |
3183 | 3331 |
3184 | 3332 |
3185 Object* Map::CopyDropTransitions() { | 3333 MaybeObject* Map::CopyDropTransitions() { |
3186 Object* new_map = CopyDropDescriptors(); | 3334 Object* new_map; |
3187 if (new_map->IsFailure()) return new_map; | 3335 { MaybeObject* maybe_new_map = CopyDropDescriptors(); |
3188 Object* descriptors = instance_descriptors()->RemoveTransitions(); | 3336 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
3189 if (descriptors->IsFailure()) return descriptors; | 3337 } |
| 3338 Object* descriptors; |
| 3339 { MaybeObject* maybe_descriptors = |
| 3340 instance_descriptors()->RemoveTransitions(); |
| 3341 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; |
| 3342 } |
3190 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); | 3343 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); |
3191 return new_map; | 3344 return new_map; |
3192 } | 3345 } |
3193 | 3346 |
3194 | 3347 |
3195 Object* Map::UpdateCodeCache(String* name, Code* code) { | 3348 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { |
3196 // Allocate the code cache if not present. | 3349 // Allocate the code cache if not present. |
3197 if (code_cache()->IsFixedArray()) { | 3350 if (code_cache()->IsFixedArray()) { |
3198 Object* result = Heap::AllocateCodeCache(); | 3351 Object* result; |
3199 if (result->IsFailure()) return result; | 3352 { MaybeObject* maybe_result = Heap::AllocateCodeCache(); |
| 3353 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3354 } |
3200 set_code_cache(result); | 3355 set_code_cache(result); |
3201 } | 3356 } |
3202 | 3357 |
3203 // Update the code cache. | 3358 // Update the code cache. |
3204 return CodeCache::cast(code_cache())->Update(name, code); | 3359 return CodeCache::cast(code_cache())->Update(name, code); |
3205 } | 3360 } |
3206 | 3361 |
3207 | 3362 |
3208 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { | 3363 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { |
3209 // Do a lookup if a code cache exists. | 3364 // Do a lookup if a code cache exists. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3266 if (!map_done) continue; | 3421 if (!map_done) continue; |
3267 *map_or_index_field = Heap::fixed_array_map(); | 3422 *map_or_index_field = Heap::fixed_array_map(); |
3268 Map* prev = current->map(); | 3423 Map* prev = current->map(); |
3269 current->set_map(Heap::meta_map()); | 3424 current->set_map(Heap::meta_map()); |
3270 callback(current, data); | 3425 callback(current, data); |
3271 current = prev; | 3426 current = prev; |
3272 } | 3427 } |
3273 } | 3428 } |
3274 | 3429 |
3275 | 3430 |
3276 Object* CodeCache::Update(String* name, Code* code) { | 3431 MaybeObject* CodeCache::Update(String* name, Code* code) { |
3277 ASSERT(code->ic_state() == MONOMORPHIC); | 3432 ASSERT(code->ic_state() == MONOMORPHIC); |
3278 | 3433 |
3279 // The number of monomorphic stubs for normal load/store/call IC's can grow to | 3434 // The number of monomorphic stubs for normal load/store/call IC's can grow to |
3280 // a large number and therefore they need to go into a hash table. They are | 3435 // a large number and therefore they need to go into a hash table. They are |
3281 // used to load global properties from cells. | 3436 // used to load global properties from cells. |
3282 if (code->type() == NORMAL) { | 3437 if (code->type() == NORMAL) { |
3283 // Make sure that a hash table is allocated for the normal load code cache. | 3438 // Make sure that a hash table is allocated for the normal load code cache. |
3284 if (normal_type_cache()->IsUndefined()) { | 3439 if (normal_type_cache()->IsUndefined()) { |
3285 Object* result = | 3440 Object* result; |
3286 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); | 3441 { MaybeObject* maybe_result = |
3287 if (result->IsFailure()) return result; | 3442 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); |
| 3443 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3444 } |
3288 set_normal_type_cache(result); | 3445 set_normal_type_cache(result); |
3289 } | 3446 } |
3290 return UpdateNormalTypeCache(name, code); | 3447 return UpdateNormalTypeCache(name, code); |
3291 } else { | 3448 } else { |
3292 ASSERT(default_cache()->IsFixedArray()); | 3449 ASSERT(default_cache()->IsFixedArray()); |
3293 return UpdateDefaultCache(name, code); | 3450 return UpdateDefaultCache(name, code); |
3294 } | 3451 } |
3295 } | 3452 } |
3296 | 3453 |
3297 | 3454 |
3298 Object* CodeCache::UpdateDefaultCache(String* name, Code* code) { | 3455 MaybeObject* CodeCache::UpdateDefaultCache(String* name, Code* code) { |
3299 // When updating the default code cache we disregard the type encoded in the | 3456 // When updating the default code cache we disregard the type encoded in the |
3300 // flags. This allows call constant stubs to overwrite call field | 3457 // flags. This allows call constant stubs to overwrite call field |
3301 // stubs, etc. | 3458 // stubs, etc. |
3302 Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); | 3459 Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); |
3303 | 3460 |
3304 // First check whether we can update existing code cache without | 3461 // First check whether we can update existing code cache without |
3305 // extending it. | 3462 // extending it. |
3306 FixedArray* cache = default_cache(); | 3463 FixedArray* cache = default_cache(); |
3307 int length = cache->length(); | 3464 int length = cache->length(); |
3308 int deleted_index = -1; | 3465 int deleted_index = -1; |
(...skipping 25 matching lines...) Expand all Loading... |
3334 cache->set(deleted_index + kCodeCacheEntryNameOffset, name); | 3491 cache->set(deleted_index + kCodeCacheEntryNameOffset, name); |
3335 cache->set(deleted_index + kCodeCacheEntryCodeOffset, code); | 3492 cache->set(deleted_index + kCodeCacheEntryCodeOffset, code); |
3336 return this; | 3493 return this; |
3337 } | 3494 } |
3338 | 3495 |
3339 // Extend the code cache with some new entries (at least one). Must be a | 3496 // Extend the code cache with some new entries (at least one). Must be a |
3340 // multiple of the entry size. | 3497 // multiple of the entry size. |
3341 int new_length = length + ((length >> 1)) + kCodeCacheEntrySize; | 3498 int new_length = length + ((length >> 1)) + kCodeCacheEntrySize; |
3342 new_length = new_length - new_length % kCodeCacheEntrySize; | 3499 new_length = new_length - new_length % kCodeCacheEntrySize; |
3343 ASSERT((new_length % kCodeCacheEntrySize) == 0); | 3500 ASSERT((new_length % kCodeCacheEntrySize) == 0); |
3344 Object* result = cache->CopySize(new_length); | 3501 Object* result; |
3345 if (result->IsFailure()) return result; | 3502 { MaybeObject* maybe_result = cache->CopySize(new_length); |
| 3503 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3504 } |
3346 | 3505 |
3347 // Add the (name, code) pair to the new cache. | 3506 // Add the (name, code) pair to the new cache. |
3348 cache = FixedArray::cast(result); | 3507 cache = FixedArray::cast(result); |
3349 cache->set(length + kCodeCacheEntryNameOffset, name); | 3508 cache->set(length + kCodeCacheEntryNameOffset, name); |
3350 cache->set(length + kCodeCacheEntryCodeOffset, code); | 3509 cache->set(length + kCodeCacheEntryCodeOffset, code); |
3351 set_default_cache(cache); | 3510 set_default_cache(cache); |
3352 return this; | 3511 return this; |
3353 } | 3512 } |
3354 | 3513 |
3355 | 3514 |
3356 Object* CodeCache::UpdateNormalTypeCache(String* name, Code* code) { | 3515 MaybeObject* CodeCache::UpdateNormalTypeCache(String* name, Code* code) { |
3357 // Adding a new entry can cause a new cache to be allocated. | 3516 // Adding a new entry can cause a new cache to be allocated. |
3358 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3517 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
3359 Object* new_cache = cache->Put(name, code); | 3518 Object* new_cache; |
3360 if (new_cache->IsFailure()) return new_cache; | 3519 { MaybeObject* maybe_new_cache = cache->Put(name, code); |
| 3520 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; |
| 3521 } |
3361 set_normal_type_cache(new_cache); | 3522 set_normal_type_cache(new_cache); |
3362 return this; | 3523 return this; |
3363 } | 3524 } |
3364 | 3525 |
3365 | 3526 |
3366 Object* CodeCache::Lookup(String* name, Code::Flags flags) { | 3527 Object* CodeCache::Lookup(String* name, Code::Flags flags) { |
3367 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { | 3528 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { |
3368 return LookupNormalTypeCache(name, flags); | 3529 return LookupNormalTypeCache(name, flags); |
3369 } else { | 3530 } else { |
3370 return LookupDefaultCache(name, flags); | 3531 return LookupDefaultCache(name, flags); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3468 | 3629 |
3469 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); } | 3630 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); } |
3470 | 3631 |
3471 uint32_t HashForObject(Object* obj) { | 3632 uint32_t HashForObject(Object* obj) { |
3472 FixedArray* pair = FixedArray::cast(obj); | 3633 FixedArray* pair = FixedArray::cast(obj); |
3473 String* name = String::cast(pair->get(0)); | 3634 String* name = String::cast(pair->get(0)); |
3474 Code* code = Code::cast(pair->get(1)); | 3635 Code* code = Code::cast(pair->get(1)); |
3475 return NameFlagsHashHelper(name, code->flags()); | 3636 return NameFlagsHashHelper(name, code->flags()); |
3476 } | 3637 } |
3477 | 3638 |
3478 Object* AsObject() { | 3639 MUST_USE_RESULT MaybeObject* AsObject() { |
3479 ASSERT(code_ != NULL); | 3640 ASSERT(code_ != NULL); |
3480 Object* obj = Heap::AllocateFixedArray(2); | 3641 Object* obj; |
3481 if (obj->IsFailure()) return obj; | 3642 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2); |
| 3643 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3644 } |
3482 FixedArray* pair = FixedArray::cast(obj); | 3645 FixedArray* pair = FixedArray::cast(obj); |
3483 pair->set(0, name_); | 3646 pair->set(0, name_); |
3484 pair->set(1, code_); | 3647 pair->set(1, code_); |
3485 return pair; | 3648 return pair; |
3486 } | 3649 } |
3487 | 3650 |
3488 private: | 3651 private: |
3489 String* name_; | 3652 String* name_; |
3490 Code::Flags flags_; | 3653 Code::Flags flags_; |
3491 Code* code_; | 3654 Code* code_; |
3492 }; | 3655 }; |
3493 | 3656 |
3494 | 3657 |
3495 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { | 3658 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { |
3496 CodeCacheHashTableKey key(name, flags); | 3659 CodeCacheHashTableKey key(name, flags); |
3497 int entry = FindEntry(&key); | 3660 int entry = FindEntry(&key); |
3498 if (entry == kNotFound) return Heap::undefined_value(); | 3661 if (entry == kNotFound) return Heap::undefined_value(); |
3499 return get(EntryToIndex(entry) + 1); | 3662 return get(EntryToIndex(entry) + 1); |
3500 } | 3663 } |
3501 | 3664 |
3502 | 3665 |
3503 Object* CodeCacheHashTable::Put(String* name, Code* code) { | 3666 MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) { |
3504 CodeCacheHashTableKey key(name, code); | 3667 CodeCacheHashTableKey key(name, code); |
3505 Object* obj = EnsureCapacity(1, &key); | 3668 Object* obj; |
3506 if (obj->IsFailure()) return obj; | 3669 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 3670 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3671 } |
3507 | 3672 |
3508 // Don't use this, as the table might have grown. | 3673 // Don't use this, as the table might have grown. |
3509 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj); | 3674 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj); |
3510 | 3675 |
3511 int entry = cache->FindInsertionEntry(key.Hash()); | 3676 int entry = cache->FindInsertionEntry(key.Hash()); |
3512 Object* k = key.AsObject(); | 3677 Object* k; |
3513 if (k->IsFailure()) return k; | 3678 { MaybeObject* maybe_k = key.AsObject(); |
| 3679 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 3680 } |
3514 | 3681 |
3515 cache->set(EntryToIndex(entry), k); | 3682 cache->set(EntryToIndex(entry), k); |
3516 cache->set(EntryToIndex(entry) + 1, code); | 3683 cache->set(EntryToIndex(entry) + 1, code); |
3517 cache->ElementAdded(); | 3684 cache->ElementAdded(); |
3518 return cache; | 3685 return cache; |
3519 } | 3686 } |
3520 | 3687 |
3521 | 3688 |
3522 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { | 3689 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { |
3523 CodeCacheHashTableKey key(name, flags); | 3690 CodeCacheHashTableKey key(name, flags); |
(...skipping 17 matching lines...) Expand all Loading... |
3541 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; | 3708 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; |
3542 if (element->IsString() && | 3709 if (element->IsString() && |
3543 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 3710 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
3544 return true; | 3711 return true; |
3545 } | 3712 } |
3546 } | 3713 } |
3547 return false; | 3714 return false; |
3548 } | 3715 } |
3549 | 3716 |
3550 | 3717 |
3551 Object* FixedArray::AddKeysFromJSArray(JSArray* array) { | 3718 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
3552 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements()); | 3719 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements()); |
3553 switch (array->GetElementsKind()) { | 3720 switch (array->GetElementsKind()) { |
3554 case JSObject::FAST_ELEMENTS: | 3721 case JSObject::FAST_ELEMENTS: |
3555 return UnionOfKeys(FixedArray::cast(array->elements())); | 3722 return UnionOfKeys(FixedArray::cast(array->elements())); |
3556 case JSObject::DICTIONARY_ELEMENTS: { | 3723 case JSObject::DICTIONARY_ELEMENTS: { |
3557 NumberDictionary* dict = array->element_dictionary(); | 3724 NumberDictionary* dict = array->element_dictionary(); |
3558 int size = dict->NumberOfElements(); | 3725 int size = dict->NumberOfElements(); |
3559 | 3726 |
3560 // Allocate a temporary fixed array. | 3727 // Allocate a temporary fixed array. |
3561 Object* object = Heap::AllocateFixedArray(size); | 3728 Object* object; |
3562 if (object->IsFailure()) return object; | 3729 { MaybeObject* maybe_object = Heap::AllocateFixedArray(size); |
| 3730 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 3731 } |
3563 FixedArray* key_array = FixedArray::cast(object); | 3732 FixedArray* key_array = FixedArray::cast(object); |
3564 | 3733 |
3565 int capacity = dict->Capacity(); | 3734 int capacity = dict->Capacity(); |
3566 int pos = 0; | 3735 int pos = 0; |
3567 // Copy the elements from the JSArray to the temporary fixed array. | 3736 // Copy the elements from the JSArray to the temporary fixed array. |
3568 for (int i = 0; i < capacity; i++) { | 3737 for (int i = 0; i < capacity; i++) { |
3569 if (dict->IsKey(dict->KeyAt(i))) { | 3738 if (dict->IsKey(dict->KeyAt(i))) { |
3570 key_array->set(pos++, dict->ValueAt(i)); | 3739 key_array->set(pos++, dict->ValueAt(i)); |
3571 } | 3740 } |
3572 } | 3741 } |
3573 // Compute the union of this and the temporary fixed array. | 3742 // Compute the union of this and the temporary fixed array. |
3574 return UnionOfKeys(key_array); | 3743 return UnionOfKeys(key_array); |
3575 } | 3744 } |
3576 default: | 3745 default: |
3577 UNREACHABLE(); | 3746 UNREACHABLE(); |
3578 } | 3747 } |
3579 UNREACHABLE(); | 3748 UNREACHABLE(); |
3580 return Heap::null_value(); // Failure case needs to "return" a value. | 3749 return Heap::null_value(); // Failure case needs to "return" a value. |
3581 } | 3750 } |
3582 | 3751 |
3583 | 3752 |
3584 Object* FixedArray::UnionOfKeys(FixedArray* other) { | 3753 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
3585 int len0 = length(); | 3754 int len0 = length(); |
3586 #ifdef DEBUG | 3755 #ifdef DEBUG |
3587 if (FLAG_enable_slow_asserts) { | 3756 if (FLAG_enable_slow_asserts) { |
3588 for (int i = 0; i < len0; i++) { | 3757 for (int i = 0; i < len0; i++) { |
3589 ASSERT(get(i)->IsString() || get(i)->IsNumber()); | 3758 ASSERT(get(i)->IsString() || get(i)->IsNumber()); |
3590 } | 3759 } |
3591 } | 3760 } |
3592 #endif | 3761 #endif |
3593 int len1 = other->length(); | 3762 int len1 = other->length(); |
3594 // Optimize if 'other' is empty. | 3763 // Optimize if 'other' is empty. |
3595 // We cannot optimize if 'this' is empty, as other may have holes | 3764 // We cannot optimize if 'this' is empty, as other may have holes |
3596 // or non keys. | 3765 // or non keys. |
3597 if (len1 == 0) return this; | 3766 if (len1 == 0) return this; |
3598 | 3767 |
3599 // Compute how many elements are not in this. | 3768 // Compute how many elements are not in this. |
3600 int extra = 0; | 3769 int extra = 0; |
3601 for (int y = 0; y < len1; y++) { | 3770 for (int y = 0; y < len1; y++) { |
3602 Object* value = other->get(y); | 3771 Object* value = other->get(y); |
3603 if (!value->IsTheHole() && !HasKey(this, value)) extra++; | 3772 if (!value->IsTheHole() && !HasKey(this, value)) extra++; |
3604 } | 3773 } |
3605 | 3774 |
3606 if (extra == 0) return this; | 3775 if (extra == 0) return this; |
3607 | 3776 |
3608 // Allocate the result | 3777 // Allocate the result |
3609 Object* obj = Heap::AllocateFixedArray(len0 + extra); | 3778 Object* obj; |
3610 if (obj->IsFailure()) return obj; | 3779 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(len0 + extra); |
| 3780 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3781 } |
3611 // Fill in the content | 3782 // Fill in the content |
3612 AssertNoAllocation no_gc; | 3783 AssertNoAllocation no_gc; |
3613 FixedArray* result = FixedArray::cast(obj); | 3784 FixedArray* result = FixedArray::cast(obj); |
3614 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 3785 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
3615 for (int i = 0; i < len0; i++) { | 3786 for (int i = 0; i < len0; i++) { |
3616 Object* e = get(i); | 3787 Object* e = get(i); |
3617 ASSERT(e->IsString() || e->IsNumber()); | 3788 ASSERT(e->IsString() || e->IsNumber()); |
3618 result->set(i, e, mode); | 3789 result->set(i, e, mode); |
3619 } | 3790 } |
3620 // Fill in the extra keys. | 3791 // Fill in the extra keys. |
3621 int index = 0; | 3792 int index = 0; |
3622 for (int y = 0; y < len1; y++) { | 3793 for (int y = 0; y < len1; y++) { |
3623 Object* value = other->get(y); | 3794 Object* value = other->get(y); |
3624 if (!value->IsTheHole() && !HasKey(this, value)) { | 3795 if (!value->IsTheHole() && !HasKey(this, value)) { |
3625 Object* e = other->get(y); | 3796 Object* e = other->get(y); |
3626 ASSERT(e->IsString() || e->IsNumber()); | 3797 ASSERT(e->IsString() || e->IsNumber()); |
3627 result->set(len0 + index, e, mode); | 3798 result->set(len0 + index, e, mode); |
3628 index++; | 3799 index++; |
3629 } | 3800 } |
3630 } | 3801 } |
3631 ASSERT(extra == index); | 3802 ASSERT(extra == index); |
3632 return result; | 3803 return result; |
3633 } | 3804 } |
3634 | 3805 |
3635 | 3806 |
3636 Object* FixedArray::CopySize(int new_length) { | 3807 MaybeObject* FixedArray::CopySize(int new_length) { |
3637 if (new_length == 0) return Heap::empty_fixed_array(); | 3808 if (new_length == 0) return Heap::empty_fixed_array(); |
3638 Object* obj = Heap::AllocateFixedArray(new_length); | 3809 Object* obj; |
3639 if (obj->IsFailure()) return obj; | 3810 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(new_length); |
| 3811 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3812 } |
3640 FixedArray* result = FixedArray::cast(obj); | 3813 FixedArray* result = FixedArray::cast(obj); |
3641 // Copy the content | 3814 // Copy the content |
3642 AssertNoAllocation no_gc; | 3815 AssertNoAllocation no_gc; |
3643 int len = length(); | 3816 int len = length(); |
3644 if (new_length < len) len = new_length; | 3817 if (new_length < len) len = new_length; |
3645 result->set_map(map()); | 3818 result->set_map(map()); |
3646 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 3819 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
3647 for (int i = 0; i < len; i++) { | 3820 for (int i = 0; i < len; i++) { |
3648 result->set(i, get(i), mode); | 3821 result->set(i, get(i), mode); |
3649 } | 3822 } |
(...skipping 14 matching lines...) Expand all Loading... |
3664 bool FixedArray::IsEqualTo(FixedArray* other) { | 3837 bool FixedArray::IsEqualTo(FixedArray* other) { |
3665 if (length() != other->length()) return false; | 3838 if (length() != other->length()) return false; |
3666 for (int i = 0 ; i < length(); ++i) { | 3839 for (int i = 0 ; i < length(); ++i) { |
3667 if (get(i) != other->get(i)) return false; | 3840 if (get(i) != other->get(i)) return false; |
3668 } | 3841 } |
3669 return true; | 3842 return true; |
3670 } | 3843 } |
3671 #endif | 3844 #endif |
3672 | 3845 |
3673 | 3846 |
3674 Object* DescriptorArray::Allocate(int number_of_descriptors) { | 3847 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) { |
3675 if (number_of_descriptors == 0) { | 3848 if (number_of_descriptors == 0) { |
3676 return Heap::empty_descriptor_array(); | 3849 return Heap::empty_descriptor_array(); |
3677 } | 3850 } |
3678 // Allocate the array of keys. | 3851 // Allocate the array of keys. |
3679 Object* array = | 3852 Object* array; |
3680 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); | 3853 { MaybeObject* maybe_array = |
3681 if (array->IsFailure()) return array; | 3854 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); |
| 3855 if (!maybe_array->ToObject(&array)) return maybe_array; |
| 3856 } |
3682 // Do not use DescriptorArray::cast on incomplete object. | 3857 // Do not use DescriptorArray::cast on incomplete object. |
3683 FixedArray* result = FixedArray::cast(array); | 3858 FixedArray* result = FixedArray::cast(array); |
3684 | 3859 |
3685 // Allocate the content array and set it in the descriptor array. | 3860 // Allocate the content array and set it in the descriptor array. |
3686 array = Heap::AllocateFixedArray(number_of_descriptors << 1); | 3861 { MaybeObject* maybe_array = |
3687 if (array->IsFailure()) return array; | 3862 Heap::AllocateFixedArray(number_of_descriptors << 1); |
| 3863 if (!maybe_array->ToObject(&array)) return maybe_array; |
| 3864 } |
3688 result->set(kContentArrayIndex, array); | 3865 result->set(kContentArrayIndex, array); |
3689 result->set(kEnumerationIndexIndex, | 3866 result->set(kEnumerationIndexIndex, |
3690 Smi::FromInt(PropertyDetails::kInitialIndex)); | 3867 Smi::FromInt(PropertyDetails::kInitialIndex)); |
3691 return result; | 3868 return result; |
3692 } | 3869 } |
3693 | 3870 |
3694 | 3871 |
3695 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, | 3872 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, |
3696 FixedArray* new_cache) { | 3873 FixedArray* new_cache) { |
3697 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); | 3874 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); |
3698 if (HasEnumCache()) { | 3875 if (HasEnumCache()) { |
3699 FixedArray::cast(get(kEnumerationIndexIndex))-> | 3876 FixedArray::cast(get(kEnumerationIndexIndex))-> |
3700 set(kEnumCacheBridgeCacheIndex, new_cache); | 3877 set(kEnumCacheBridgeCacheIndex, new_cache); |
3701 } else { | 3878 } else { |
3702 if (IsEmpty()) return; // Do nothing for empty descriptor array. | 3879 if (IsEmpty()) return; // Do nothing for empty descriptor array. |
3703 FixedArray::cast(bridge_storage)-> | 3880 FixedArray::cast(bridge_storage)-> |
3704 set(kEnumCacheBridgeCacheIndex, new_cache); | 3881 set(kEnumCacheBridgeCacheIndex, new_cache); |
3705 fast_set(FixedArray::cast(bridge_storage), | 3882 fast_set(FixedArray::cast(bridge_storage), |
3706 kEnumCacheBridgeEnumIndex, | 3883 kEnumCacheBridgeEnumIndex, |
3707 get(kEnumerationIndexIndex)); | 3884 get(kEnumerationIndexIndex)); |
3708 set(kEnumerationIndexIndex, bridge_storage); | 3885 set(kEnumerationIndexIndex, bridge_storage); |
3709 } | 3886 } |
3710 } | 3887 } |
3711 | 3888 |
3712 | 3889 |
3713 Object* DescriptorArray::CopyInsert(Descriptor* descriptor, | 3890 MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor, |
3714 TransitionFlag transition_flag) { | 3891 TransitionFlag transition_flag) { |
3715 // Transitions are only kept when inserting another transition. | 3892 // Transitions are only kept when inserting another transition. |
3716 // This precondition is not required by this function's implementation, but | 3893 // This precondition is not required by this function's implementation, but |
3717 // is currently required by the semantics of maps, so we check it. | 3894 // is currently required by the semantics of maps, so we check it. |
3718 // Conversely, we filter after replacing, so replacing a transition and | 3895 // Conversely, we filter after replacing, so replacing a transition and |
3719 // removing all other transitions is not supported. | 3896 // removing all other transitions is not supported. |
3720 bool remove_transitions = transition_flag == REMOVE_TRANSITIONS; | 3897 bool remove_transitions = transition_flag == REMOVE_TRANSITIONS; |
3721 ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition()); | 3898 ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition()); |
3722 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); | 3899 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); |
3723 | 3900 |
3724 // Ensure the key is a symbol. | 3901 // Ensure the key is a symbol. |
3725 Object* result = descriptor->KeyToSymbol(); | 3902 Object* result; |
3726 if (result->IsFailure()) return result; | 3903 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
| 3904 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3905 } |
3727 | 3906 |
3728 int transitions = 0; | 3907 int transitions = 0; |
3729 int null_descriptors = 0; | 3908 int null_descriptors = 0; |
3730 if (remove_transitions) { | 3909 if (remove_transitions) { |
3731 for (int i = 0; i < number_of_descriptors(); i++) { | 3910 for (int i = 0; i < number_of_descriptors(); i++) { |
3732 if (IsTransition(i)) transitions++; | 3911 if (IsTransition(i)) transitions++; |
3733 if (IsNullDescriptor(i)) null_descriptors++; | 3912 if (IsNullDescriptor(i)) null_descriptors++; |
3734 } | 3913 } |
3735 } else { | 3914 } else { |
3736 for (int i = 0; i < number_of_descriptors(); i++) { | 3915 for (int i = 0; i < number_of_descriptors(); i++) { |
(...skipping 19 matching lines...) Expand all Loading... |
3756 t == FIELD || | 3935 t == FIELD || |
3757 t == CALLBACKS || | 3936 t == CALLBACKS || |
3758 t == INTERCEPTOR) { | 3937 t == INTERCEPTOR) { |
3759 keep_enumeration_index = true; | 3938 keep_enumeration_index = true; |
3760 } else if (remove_transitions) { | 3939 } else if (remove_transitions) { |
3761 // Replaced descriptor has been counted as removed if it is | 3940 // Replaced descriptor has been counted as removed if it is |
3762 // a transition that will be replaced. Adjust count in this case. | 3941 // a transition that will be replaced. Adjust count in this case. |
3763 ++new_size; | 3942 ++new_size; |
3764 } | 3943 } |
3765 } | 3944 } |
3766 result = Allocate(new_size); | 3945 { MaybeObject* maybe_result = Allocate(new_size); |
3767 if (result->IsFailure()) return result; | 3946 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3947 } |
3768 DescriptorArray* new_descriptors = DescriptorArray::cast(result); | 3948 DescriptorArray* new_descriptors = DescriptorArray::cast(result); |
3769 // Set the enumeration index in the descriptors and set the enumeration index | 3949 // Set the enumeration index in the descriptors and set the enumeration index |
3770 // in the result. | 3950 // in the result. |
3771 int enumeration_index = NextEnumerationIndex(); | 3951 int enumeration_index = NextEnumerationIndex(); |
3772 if (!descriptor->GetDetails().IsTransition()) { | 3952 if (!descriptor->GetDetails().IsTransition()) { |
3773 if (keep_enumeration_index) { | 3953 if (keep_enumeration_index) { |
3774 descriptor->SetEnumerationIndex( | 3954 descriptor->SetEnumerationIndex( |
3775 PropertyDetails(GetDetails(index)).index()); | 3955 PropertyDetails(GetDetails(index)).index()); |
3776 } else { | 3956 } else { |
3777 descriptor->SetEnumerationIndex(enumeration_index); | 3957 descriptor->SetEnumerationIndex(enumeration_index); |
(...skipping 27 matching lines...) Expand all Loading... |
3805 new_descriptors->CopyFrom(to_index++, this, from_index); | 3985 new_descriptors->CopyFrom(to_index++, this, from_index); |
3806 } | 3986 } |
3807 | 3987 |
3808 ASSERT(to_index == new_descriptors->number_of_descriptors()); | 3988 ASSERT(to_index == new_descriptors->number_of_descriptors()); |
3809 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | 3989 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
3810 | 3990 |
3811 return new_descriptors; | 3991 return new_descriptors; |
3812 } | 3992 } |
3813 | 3993 |
3814 | 3994 |
3815 Object* DescriptorArray::RemoveTransitions() { | 3995 MaybeObject* DescriptorArray::RemoveTransitions() { |
3816 // Remove all transitions and null descriptors. Return a copy of the array | 3996 // Remove all transitions and null descriptors. Return a copy of the array |
3817 // with all transitions removed, or a Failure object if the new array could | 3997 // with all transitions removed, or a Failure object if the new array could |
3818 // not be allocated. | 3998 // not be allocated. |
3819 | 3999 |
3820 // Compute the size of the map transition entries to be removed. | 4000 // Compute the size of the map transition entries to be removed. |
3821 int num_removed = 0; | 4001 int num_removed = 0; |
3822 for (int i = 0; i < number_of_descriptors(); i++) { | 4002 for (int i = 0; i < number_of_descriptors(); i++) { |
3823 if (!IsProperty(i)) num_removed++; | 4003 if (!IsProperty(i)) num_removed++; |
3824 } | 4004 } |
3825 | 4005 |
3826 // Allocate the new descriptor array. | 4006 // Allocate the new descriptor array. |
3827 Object* result = Allocate(number_of_descriptors() - num_removed); | 4007 Object* result; |
3828 if (result->IsFailure()) return result; | 4008 { MaybeObject* maybe_result = Allocate(number_of_descriptors() - num_removed); |
| 4009 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4010 } |
3829 DescriptorArray* new_descriptors = DescriptorArray::cast(result); | 4011 DescriptorArray* new_descriptors = DescriptorArray::cast(result); |
3830 | 4012 |
3831 // Copy the content. | 4013 // Copy the content. |
3832 int next_descriptor = 0; | 4014 int next_descriptor = 0; |
3833 for (int i = 0; i < number_of_descriptors(); i++) { | 4015 for (int i = 0; i < number_of_descriptors(); i++) { |
3834 if (IsProperty(i)) new_descriptors->CopyFrom(next_descriptor++, this, i); | 4016 if (IsProperty(i)) new_descriptors->CopyFrom(next_descriptor++, this, i); |
3835 } | 4017 } |
3836 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); | 4018 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); |
3837 | 4019 |
3838 return new_descriptors; | 4020 return new_descriptors; |
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5056 // Process the remaining characters without updating the array | 5238 // Process the remaining characters without updating the array |
5057 // index. | 5239 // index. |
5058 while (buffer->has_more()) { | 5240 while (buffer->has_more()) { |
5059 hasher.AddCharacterNoIndex(buffer->GetNext()); | 5241 hasher.AddCharacterNoIndex(buffer->GetNext()); |
5060 } | 5242 } |
5061 | 5243 |
5062 return hasher.GetHashField(); | 5244 return hasher.GetHashField(); |
5063 } | 5245 } |
5064 | 5246 |
5065 | 5247 |
5066 Object* String::SubString(int start, int end, PretenureFlag pretenure) { | 5248 MaybeObject* String::SubString(int start, int end, PretenureFlag pretenure) { |
5067 if (start == 0 && end == length()) return this; | 5249 if (start == 0 && end == length()) return this; |
5068 Object* result = Heap::AllocateSubString(this, start, end, pretenure); | 5250 MaybeObject* result = Heap::AllocateSubString(this, start, end, pretenure); |
5069 return result; | 5251 return result; |
5070 } | 5252 } |
5071 | 5253 |
5072 | 5254 |
5073 void String::PrintOn(FILE* file) { | 5255 void String::PrintOn(FILE* file) { |
5074 int length = this->length(); | 5256 int length = this->length(); |
5075 for (int i = 0; i < length; i++) { | 5257 for (int i = 0; i < length; i++) { |
5076 fprintf(file, "%c", Get(i)); | 5258 fprintf(file, "%c", Get(i)); |
5077 } | 5259 } |
5078 } | 5260 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5159 // Put the value in the initial map field until an initial map is | 5341 // Put the value in the initial map field until an initial map is |
5160 // needed. At that point, a new initial map is created and the | 5342 // needed. At that point, a new initial map is created and the |
5161 // prototype is put into the initial map where it belongs. | 5343 // prototype is put into the initial map where it belongs. |
5162 set_prototype_or_initial_map(value); | 5344 set_prototype_or_initial_map(value); |
5163 } | 5345 } |
5164 Heap::ClearInstanceofCache(); | 5346 Heap::ClearInstanceofCache(); |
5165 return value; | 5347 return value; |
5166 } | 5348 } |
5167 | 5349 |
5168 | 5350 |
5169 Object* JSFunction::SetPrototype(Object* value) { | 5351 MaybeObject* JSFunction::SetPrototype(Object* value) { |
5170 ASSERT(should_have_prototype()); | 5352 ASSERT(should_have_prototype()); |
5171 Object* construct_prototype = value; | 5353 Object* construct_prototype = value; |
5172 | 5354 |
5173 // If the value is not a JSObject, store the value in the map's | 5355 // If the value is not a JSObject, store the value in the map's |
5174 // constructor field so it can be accessed. Also, set the prototype | 5356 // constructor field so it can be accessed. Also, set the prototype |
5175 // used for constructing objects to the original object prototype. | 5357 // used for constructing objects to the original object prototype. |
5176 // See ECMA-262 13.2.2. | 5358 // See ECMA-262 13.2.2. |
5177 if (!value->IsJSObject()) { | 5359 if (!value->IsJSObject()) { |
5178 // Copy the map so this does not affect unrelated functions. | 5360 // Copy the map so this does not affect unrelated functions. |
5179 // Remove map transitions because they point to maps with a | 5361 // Remove map transitions because they point to maps with a |
5180 // different prototype. | 5362 // different prototype. |
5181 Object* new_map = map()->CopyDropTransitions(); | 5363 Object* new_map; |
5182 if (new_map->IsFailure()) return new_map; | 5364 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); |
| 5365 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 5366 } |
5183 set_map(Map::cast(new_map)); | 5367 set_map(Map::cast(new_map)); |
5184 map()->set_constructor(value); | 5368 map()->set_constructor(value); |
5185 map()->set_non_instance_prototype(true); | 5369 map()->set_non_instance_prototype(true); |
5186 construct_prototype = | 5370 construct_prototype = |
5187 Top::context()->global_context()->initial_object_prototype(); | 5371 Top::context()->global_context()->initial_object_prototype(); |
5188 } else { | 5372 } else { |
5189 map()->set_non_instance_prototype(false); | 5373 map()->set_non_instance_prototype(false); |
5190 } | 5374 } |
5191 | 5375 |
5192 return SetInstancePrototype(construct_prototype); | 5376 return SetInstancePrototype(construct_prototype); |
(...skipping 12 matching lines...) Expand all Loading... |
5205 shared()->set_instance_class_name(name); | 5389 shared()->set_instance_class_name(name); |
5206 return this; | 5390 return this; |
5207 } | 5391 } |
5208 | 5392 |
5209 | 5393 |
5210 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { | 5394 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { |
5211 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); | 5395 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); |
5212 } | 5396 } |
5213 | 5397 |
5214 | 5398 |
5215 Object* Oddball::Initialize(const char* to_string, Object* to_number) { | 5399 MaybeObject* Oddball::Initialize(const char* to_string, Object* to_number) { |
5216 Object* symbol = Heap::LookupAsciiSymbol(to_string); | 5400 Object* symbol; |
5217 if (symbol->IsFailure()) return symbol; | 5401 { MaybeObject* maybe_symbol = Heap::LookupAsciiSymbol(to_string); |
| 5402 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; |
| 5403 } |
5218 set_to_string(String::cast(symbol)); | 5404 set_to_string(String::cast(symbol)); |
5219 set_to_number(to_number); | 5405 set_to_number(to_number); |
5220 return this; | 5406 return this; |
5221 } | 5407 } |
5222 | 5408 |
5223 | 5409 |
5224 String* SharedFunctionInfo::DebugName() { | 5410 String* SharedFunctionInfo::DebugName() { |
5225 Object* n = name(); | 5411 Object* n = name(); |
5226 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); | 5412 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); |
5227 return String::cast(n); | 5413 return String::cast(n); |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5696 PrintF("\n"); | 5882 PrintF("\n"); |
5697 | 5883 |
5698 PrintF("RelocInfo (size = %d)\n", relocation_size()); | 5884 PrintF("RelocInfo (size = %d)\n", relocation_size()); |
5699 for (RelocIterator it(this); !it.done(); it.next()) | 5885 for (RelocIterator it(this); !it.done(); it.next()) |
5700 it.rinfo()->Print(); | 5886 it.rinfo()->Print(); |
5701 PrintF("\n"); | 5887 PrintF("\n"); |
5702 } | 5888 } |
5703 #endif // ENABLE_DISASSEMBLER | 5889 #endif // ENABLE_DISASSEMBLER |
5704 | 5890 |
5705 | 5891 |
5706 Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) { | 5892 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, |
| 5893 int length) { |
5707 // We should never end in here with a pixel or external array. | 5894 // We should never end in here with a pixel or external array. |
5708 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 5895 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
5709 | 5896 |
5710 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); | 5897 Object* obj; |
5711 if (obj->IsFailure()) return obj; | 5898 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 5899 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5900 } |
5712 FixedArray* elems = FixedArray::cast(obj); | 5901 FixedArray* elems = FixedArray::cast(obj); |
5713 | 5902 |
5714 obj = map()->GetFastElementsMap(); | 5903 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
5715 if (obj->IsFailure()) return obj; | 5904 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5905 } |
5716 Map* new_map = Map::cast(obj); | 5906 Map* new_map = Map::cast(obj); |
5717 | 5907 |
5718 AssertNoAllocation no_gc; | 5908 AssertNoAllocation no_gc; |
5719 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); | 5909 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); |
5720 switch (GetElementsKind()) { | 5910 switch (GetElementsKind()) { |
5721 case FAST_ELEMENTS: { | 5911 case FAST_ELEMENTS: { |
5722 FixedArray* old_elements = FixedArray::cast(elements()); | 5912 FixedArray* old_elements = FixedArray::cast(elements()); |
5723 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); | 5913 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); |
5724 // Fill out the new array with this content and array holes. | 5914 // Fill out the new array with this content and array holes. |
5725 for (uint32_t i = 0; i < old_length; i++) { | 5915 for (uint32_t i = 0; i < old_length; i++) { |
(...skipping 21 matching lines...) Expand all Loading... |
5747 set_elements(elems); | 5937 set_elements(elems); |
5748 | 5938 |
5749 if (IsJSArray()) { | 5939 if (IsJSArray()) { |
5750 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 5940 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
5751 } | 5941 } |
5752 | 5942 |
5753 return this; | 5943 return this; |
5754 } | 5944 } |
5755 | 5945 |
5756 | 5946 |
5757 Object* JSObject::SetSlowElements(Object* len) { | 5947 MaybeObject* JSObject::SetSlowElements(Object* len) { |
5758 // We should never end in here with a pixel or external array. | 5948 // We should never end in here with a pixel or external array. |
5759 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 5949 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
5760 | 5950 |
5761 uint32_t new_length = static_cast<uint32_t>(len->Number()); | 5951 uint32_t new_length = static_cast<uint32_t>(len->Number()); |
5762 | 5952 |
5763 switch (GetElementsKind()) { | 5953 switch (GetElementsKind()) { |
5764 case FAST_ELEMENTS: { | 5954 case FAST_ELEMENTS: { |
5765 // Make sure we never try to shrink dense arrays into sparse arrays. | 5955 // Make sure we never try to shrink dense arrays into sparse arrays. |
5766 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= | 5956 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= |
5767 new_length); | 5957 new_length); |
5768 Object* obj = NormalizeElements(); | 5958 Object* obj; |
5769 if (obj->IsFailure()) return obj; | 5959 { MaybeObject* maybe_obj = NormalizeElements(); |
| 5960 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5961 } |
5770 | 5962 |
5771 // Update length for JSArrays. | 5963 // Update length for JSArrays. |
5772 if (IsJSArray()) JSArray::cast(this)->set_length(len); | 5964 if (IsJSArray()) JSArray::cast(this)->set_length(len); |
5773 break; | 5965 break; |
5774 } | 5966 } |
5775 case DICTIONARY_ELEMENTS: { | 5967 case DICTIONARY_ELEMENTS: { |
5776 if (IsJSArray()) { | 5968 if (IsJSArray()) { |
5777 uint32_t old_length = | 5969 uint32_t old_length = |
5778 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); | 5970 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); |
5779 element_dictionary()->RemoveNumberEntries(new_length, old_length), | 5971 element_dictionary()->RemoveNumberEntries(new_length, old_length), |
5780 JSArray::cast(this)->set_length(len); | 5972 JSArray::cast(this)->set_length(len); |
5781 } | 5973 } |
5782 break; | 5974 break; |
5783 } | 5975 } |
5784 default: | 5976 default: |
5785 UNREACHABLE(); | 5977 UNREACHABLE(); |
5786 break; | 5978 break; |
5787 } | 5979 } |
5788 return this; | 5980 return this; |
5789 } | 5981 } |
5790 | 5982 |
5791 | 5983 |
5792 Object* JSArray::Initialize(int capacity) { | 5984 MaybeObject* JSArray::Initialize(int capacity) { |
5793 ASSERT(capacity >= 0); | 5985 ASSERT(capacity >= 0); |
5794 set_length(Smi::FromInt(0)); | 5986 set_length(Smi::FromInt(0)); |
5795 FixedArray* new_elements; | 5987 FixedArray* new_elements; |
5796 if (capacity == 0) { | 5988 if (capacity == 0) { |
5797 new_elements = Heap::empty_fixed_array(); | 5989 new_elements = Heap::empty_fixed_array(); |
5798 } else { | 5990 } else { |
5799 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); | 5991 Object* obj; |
5800 if (obj->IsFailure()) return obj; | 5992 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 5993 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5994 } |
5801 new_elements = FixedArray::cast(obj); | 5995 new_elements = FixedArray::cast(obj); |
5802 } | 5996 } |
5803 set_elements(new_elements); | 5997 set_elements(new_elements); |
5804 return this; | 5998 return this; |
5805 } | 5999 } |
5806 | 6000 |
5807 | 6001 |
5808 void JSArray::Expand(int required_size) { | 6002 void JSArray::Expand(int required_size) { |
5809 Handle<JSArray> self(this); | 6003 Handle<JSArray> self(this); |
5810 Handle<FixedArray> old_backing(FixedArray::cast(elements())); | 6004 Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
5811 int old_size = old_backing->length(); | 6005 int old_size = old_backing->length(); |
5812 int new_size = required_size > old_size ? required_size : old_size; | 6006 int new_size = required_size > old_size ? required_size : old_size; |
5813 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); | 6007 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); |
5814 // Can't use this any more now because we may have had a GC! | 6008 // Can't use this any more now because we may have had a GC! |
5815 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); | 6009 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
5816 self->SetContent(*new_backing); | 6010 self->SetContent(*new_backing); |
5817 } | 6011 } |
5818 | 6012 |
5819 | 6013 |
5820 // Computes the new capacity when expanding the elements of a JSObject. | 6014 // Computes the new capacity when expanding the elements of a JSObject. |
5821 static int NewElementsCapacity(int old_capacity) { | 6015 static int NewElementsCapacity(int old_capacity) { |
5822 // (old_capacity + 50%) + 16 | 6016 // (old_capacity + 50%) + 16 |
5823 return old_capacity + (old_capacity >> 1) + 16; | 6017 return old_capacity + (old_capacity >> 1) + 16; |
5824 } | 6018 } |
5825 | 6019 |
5826 | 6020 |
5827 static Object* ArrayLengthRangeError() { | 6021 static Failure* ArrayLengthRangeError() { |
5828 HandleScope scope; | 6022 HandleScope scope; |
5829 return Top::Throw(*Factory::NewRangeError("invalid_array_length", | 6023 return Top::Throw(*Factory::NewRangeError("invalid_array_length", |
5830 HandleVector<Object>(NULL, 0))); | 6024 HandleVector<Object>(NULL, 0))); |
5831 } | 6025 } |
5832 | 6026 |
5833 | 6027 |
5834 Object* JSObject::SetElementsLength(Object* len) { | 6028 MaybeObject* JSObject::SetElementsLength(Object* len) { |
5835 // We should never end in here with a pixel or external array. | 6029 // We should never end in here with a pixel or external array. |
5836 ASSERT(AllowsSetElementsLength()); | 6030 ASSERT(AllowsSetElementsLength()); |
5837 | 6031 |
5838 Object* smi_length = len->ToSmi(); | 6032 MaybeObject* maybe_smi_length = len->ToSmi(); |
5839 if (smi_length->IsSmi()) { | 6033 Object* smi_length = Smi::FromInt(0); |
| 6034 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
5840 const int value = Smi::cast(smi_length)->value(); | 6035 const int value = Smi::cast(smi_length)->value(); |
5841 if (value < 0) return ArrayLengthRangeError(); | 6036 if (value < 0) return ArrayLengthRangeError(); |
5842 switch (GetElementsKind()) { | 6037 switch (GetElementsKind()) { |
5843 case FAST_ELEMENTS: { | 6038 case FAST_ELEMENTS: { |
5844 int old_capacity = FixedArray::cast(elements())->length(); | 6039 int old_capacity = FixedArray::cast(elements())->length(); |
5845 if (value <= old_capacity) { | 6040 if (value <= old_capacity) { |
5846 if (IsJSArray()) { | 6041 if (IsJSArray()) { |
5847 Object* obj = EnsureWritableFastElements(); | 6042 Object* obj; |
5848 if (obj->IsFailure()) return obj; | 6043 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 6044 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6045 } |
5849 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 6046 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
5850 // NOTE: We may be able to optimize this by removing the | 6047 // NOTE: We may be able to optimize this by removing the |
5851 // last part of the elements backing storage array and | 6048 // last part of the elements backing storage array and |
5852 // setting the capacity to the new size. | 6049 // setting the capacity to the new size. |
5853 for (int i = value; i < old_length; i++) { | 6050 for (int i = value; i < old_length; i++) { |
5854 FixedArray::cast(elements())->set_the_hole(i); | 6051 FixedArray::cast(elements())->set_the_hole(i); |
5855 } | 6052 } |
5856 JSArray::cast(this)->set_length(Smi::cast(smi_length)); | 6053 JSArray::cast(this)->set_length(Smi::cast(smi_length)); |
5857 } | 6054 } |
5858 return this; | 6055 return this; |
5859 } | 6056 } |
5860 int min = NewElementsCapacity(old_capacity); | 6057 int min = NewElementsCapacity(old_capacity); |
5861 int new_capacity = value > min ? value : min; | 6058 int new_capacity = value > min ? value : min; |
5862 if (new_capacity <= kMaxFastElementsLength || | 6059 if (new_capacity <= kMaxFastElementsLength || |
5863 !ShouldConvertToSlowElements(new_capacity)) { | 6060 !ShouldConvertToSlowElements(new_capacity)) { |
5864 Object* obj = SetFastElementsCapacityAndLength(new_capacity, value); | 6061 Object* obj; |
5865 if (obj->IsFailure()) return obj; | 6062 { MaybeObject* maybe_obj = |
| 6063 SetFastElementsCapacityAndLength(new_capacity, value); |
| 6064 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6065 } |
5866 return this; | 6066 return this; |
5867 } | 6067 } |
5868 break; | 6068 break; |
5869 } | 6069 } |
5870 case DICTIONARY_ELEMENTS: { | 6070 case DICTIONARY_ELEMENTS: { |
5871 if (IsJSArray()) { | 6071 if (IsJSArray()) { |
5872 if (value == 0) { | 6072 if (value == 0) { |
5873 // If the length of a slow array is reset to zero, we clear | 6073 // If the length of a slow array is reset to zero, we clear |
5874 // the array and flush backing storage. This has the added | 6074 // the array and flush backing storage. This has the added |
5875 // benefit that the array returns to fast mode. | 6075 // benefit that the array returns to fast mode. |
5876 Object* obj = ResetElements(); | 6076 Object* obj; |
5877 if (obj->IsFailure()) return obj; | 6077 { MaybeObject* maybe_obj = ResetElements(); |
| 6078 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6079 } |
5878 } else { | 6080 } else { |
5879 // Remove deleted elements. | 6081 // Remove deleted elements. |
5880 uint32_t old_length = | 6082 uint32_t old_length = |
5881 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); | 6083 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); |
5882 element_dictionary()->RemoveNumberEntries(value, old_length); | 6084 element_dictionary()->RemoveNumberEntries(value, old_length); |
5883 } | 6085 } |
5884 JSArray::cast(this)->set_length(Smi::cast(smi_length)); | 6086 JSArray::cast(this)->set_length(Smi::cast(smi_length)); |
5885 } | 6087 } |
5886 return this; | 6088 return this; |
5887 } | 6089 } |
5888 default: | 6090 default: |
5889 UNREACHABLE(); | 6091 UNREACHABLE(); |
5890 break; | 6092 break; |
5891 } | 6093 } |
5892 } | 6094 } |
5893 | 6095 |
5894 // General slow case. | 6096 // General slow case. |
5895 if (len->IsNumber()) { | 6097 if (len->IsNumber()) { |
5896 uint32_t length; | 6098 uint32_t length; |
5897 if (len->ToArrayIndex(&length)) { | 6099 if (len->ToArrayIndex(&length)) { |
5898 return SetSlowElements(len); | 6100 return SetSlowElements(len); |
5899 } else { | 6101 } else { |
5900 return ArrayLengthRangeError(); | 6102 return ArrayLengthRangeError(); |
5901 } | 6103 } |
5902 } | 6104 } |
5903 | 6105 |
5904 // len is not a number so make the array size one and | 6106 // len is not a number so make the array size one and |
5905 // set only element to len. | 6107 // set only element to len. |
5906 Object* obj = Heap::AllocateFixedArray(1); | 6108 Object* obj; |
5907 if (obj->IsFailure()) return obj; | 6109 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(1); |
| 6110 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6111 } |
5908 FixedArray::cast(obj)->set(0, len); | 6112 FixedArray::cast(obj)->set(0, len); |
5909 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 6113 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); |
5910 set_elements(FixedArray::cast(obj)); | 6114 set_elements(FixedArray::cast(obj)); |
5911 return this; | 6115 return this; |
5912 } | 6116 } |
5913 | 6117 |
5914 | 6118 |
5915 Object* JSObject::SetPrototype(Object* value, | 6119 MaybeObject* JSObject::SetPrototype(Object* value, |
5916 bool skip_hidden_prototypes) { | 6120 bool skip_hidden_prototypes) { |
5917 // Silently ignore the change if value is not a JSObject or null. | 6121 // Silently ignore the change if value is not a JSObject or null. |
5918 // SpiderMonkey behaves this way. | 6122 // SpiderMonkey behaves this way. |
5919 if (!value->IsJSObject() && !value->IsNull()) return value; | 6123 if (!value->IsJSObject() && !value->IsNull()) return value; |
5920 | 6124 |
5921 // Before we can set the prototype we need to be sure | 6125 // Before we can set the prototype we need to be sure |
5922 // prototype cycles are prevented. | 6126 // prototype cycles are prevented. |
5923 // It is sufficient to validate that the receiver is not in the new prototype | 6127 // It is sufficient to validate that the receiver is not in the new prototype |
5924 // chain. | 6128 // chain. |
5925 for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) { | 6129 for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) { |
5926 if (JSObject::cast(pt) == this) { | 6130 if (JSObject::cast(pt) == this) { |
(...skipping 11 matching lines...) Expand all Loading... |
5938 // hidden and set the new prototype on that object. | 6142 // hidden and set the new prototype on that object. |
5939 Object* current_proto = real_receiver->GetPrototype(); | 6143 Object* current_proto = real_receiver->GetPrototype(); |
5940 while (current_proto->IsJSObject() && | 6144 while (current_proto->IsJSObject() && |
5941 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 6145 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { |
5942 real_receiver = JSObject::cast(current_proto); | 6146 real_receiver = JSObject::cast(current_proto); |
5943 current_proto = current_proto->GetPrototype(); | 6147 current_proto = current_proto->GetPrototype(); |
5944 } | 6148 } |
5945 } | 6149 } |
5946 | 6150 |
5947 // Set the new prototype of the object. | 6151 // Set the new prototype of the object. |
5948 Object* new_map = real_receiver->map()->CopyDropTransitions(); | 6152 Object* new_map; |
5949 if (new_map->IsFailure()) return new_map; | 6153 { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions(); |
| 6154 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 6155 } |
5950 Map::cast(new_map)->set_prototype(value); | 6156 Map::cast(new_map)->set_prototype(value); |
5951 real_receiver->set_map(Map::cast(new_map)); | 6157 real_receiver->set_map(Map::cast(new_map)); |
5952 | 6158 |
5953 Heap::ClearInstanceofCache(); | 6159 Heap::ClearInstanceofCache(); |
5954 | 6160 |
5955 return value; | 6161 return value; |
5956 } | 6162 } |
5957 | 6163 |
5958 | 6164 |
5959 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { | 6165 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6172 | 6378 |
6173 // Handle [] on String objects. | 6379 // Handle [] on String objects. |
6174 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6380 if (this->IsStringObjectWithCharacterAt(index)) return true; |
6175 | 6381 |
6176 Object* pt = GetPrototype(); | 6382 Object* pt = GetPrototype(); |
6177 if (pt == Heap::null_value()) return false; | 6383 if (pt == Heap::null_value()) return false; |
6178 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6384 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
6179 } | 6385 } |
6180 | 6386 |
6181 | 6387 |
6182 Object* JSObject::SetElementWithInterceptor(uint32_t index, Object* value) { | 6388 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
| 6389 Object* value) { |
6183 // Make sure that the top context does not change when doing | 6390 // Make sure that the top context does not change when doing |
6184 // callbacks or interceptor calls. | 6391 // callbacks or interceptor calls. |
6185 AssertNoContextChange ncc; | 6392 AssertNoContextChange ncc; |
6186 HandleScope scope; | 6393 HandleScope scope; |
6187 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6394 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
6188 Handle<JSObject> this_handle(this); | 6395 Handle<JSObject> this_handle(this); |
6189 Handle<Object> value_handle(value); | 6396 Handle<Object> value_handle(value); |
6190 if (!interceptor->setter()->IsUndefined()) { | 6397 if (!interceptor->setter()->IsUndefined()) { |
6191 v8::IndexedPropertySetter setter = | 6398 v8::IndexedPropertySetter setter = |
6192 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 6399 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
6193 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 6400 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
6194 CustomArguments args(interceptor->data(), this, this); | 6401 CustomArguments args(interceptor->data(), this, this); |
6195 v8::AccessorInfo info(args.end()); | 6402 v8::AccessorInfo info(args.end()); |
6196 v8::Handle<v8::Value> result; | 6403 v8::Handle<v8::Value> result; |
6197 { | 6404 { |
6198 // Leaving JavaScript. | 6405 // Leaving JavaScript. |
6199 VMState state(EXTERNAL); | 6406 VMState state(EXTERNAL); |
6200 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 6407 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
6201 } | 6408 } |
6202 RETURN_IF_SCHEDULED_EXCEPTION(); | 6409 RETURN_IF_SCHEDULED_EXCEPTION(); |
6203 if (!result.IsEmpty()) return *value_handle; | 6410 if (!result.IsEmpty()) return *value_handle; |
6204 } | 6411 } |
6205 Object* raw_result = | 6412 MaybeObject* raw_result = |
6206 this_handle->SetElementWithoutInterceptor(index, *value_handle); | 6413 this_handle->SetElementWithoutInterceptor(index, *value_handle); |
6207 RETURN_IF_SCHEDULED_EXCEPTION(); | 6414 RETURN_IF_SCHEDULED_EXCEPTION(); |
6208 return raw_result; | 6415 return raw_result; |
6209 } | 6416 } |
6210 | 6417 |
6211 | 6418 |
6212 Object* JSObject::GetElementWithCallback(Object* receiver, | 6419 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
6213 Object* structure, | 6420 Object* structure, |
6214 uint32_t index, | 6421 uint32_t index, |
6215 Object* holder) { | 6422 Object* holder) { |
6216 ASSERT(!structure->IsProxy()); | 6423 ASSERT(!structure->IsProxy()); |
6217 | 6424 |
6218 // api style callbacks. | 6425 // api style callbacks. |
6219 if (structure->IsAccessorInfo()) { | 6426 if (structure->IsAccessorInfo()) { |
6220 AccessorInfo* data = AccessorInfo::cast(structure); | 6427 AccessorInfo* data = AccessorInfo::cast(structure); |
6221 Object* fun_obj = data->getter(); | 6428 Object* fun_obj = data->getter(); |
6222 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 6429 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
6223 HandleScope scope; | 6430 HandleScope scope; |
6224 Handle<JSObject> self(JSObject::cast(receiver)); | 6431 Handle<JSObject> self(JSObject::cast(receiver)); |
6225 Handle<JSObject> holder_handle(JSObject::cast(holder)); | 6432 Handle<JSObject> holder_handle(JSObject::cast(holder)); |
(...skipping 22 matching lines...) Expand all Loading... |
6248 } | 6455 } |
6249 // Getter is not a function. | 6456 // Getter is not a function. |
6250 return Heap::undefined_value(); | 6457 return Heap::undefined_value(); |
6251 } | 6458 } |
6252 | 6459 |
6253 UNREACHABLE(); | 6460 UNREACHABLE(); |
6254 return NULL; | 6461 return NULL; |
6255 } | 6462 } |
6256 | 6463 |
6257 | 6464 |
6258 Object* JSObject::SetElementWithCallback(Object* structure, | 6465 MaybeObject* JSObject::SetElementWithCallback(Object* structure, |
6259 uint32_t index, | 6466 uint32_t index, |
6260 Object* value, | 6467 Object* value, |
6261 JSObject* holder) { | 6468 JSObject* holder) { |
6262 HandleScope scope; | 6469 HandleScope scope; |
6263 | 6470 |
6264 // We should never get here to initialize a const with the hole | 6471 // We should never get here to initialize a const with the hole |
6265 // value since a const declaration would conflict with the setter. | 6472 // value since a const declaration would conflict with the setter. |
6266 ASSERT(!value->IsTheHole()); | 6473 ASSERT(!value->IsTheHole()); |
6267 Handle<Object> value_handle(value); | 6474 Handle<Object> value_handle(value); |
6268 | 6475 |
6269 // To accommodate both the old and the new api we switch on the | 6476 // To accommodate both the old and the new api we switch on the |
6270 // data structure used to store the callbacks. Eventually proxy | 6477 // data structure used to store the callbacks. Eventually proxy |
6271 // callbacks should be phased out. | 6478 // callbacks should be phased out. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6307 } | 6514 } |
6308 | 6515 |
6309 UNREACHABLE(); | 6516 UNREACHABLE(); |
6310 return NULL; | 6517 return NULL; |
6311 } | 6518 } |
6312 | 6519 |
6313 | 6520 |
6314 // Adding n elements in fast case is O(n*n). | 6521 // Adding n elements in fast case is O(n*n). |
6315 // Note: revisit design to have dual undefined values to capture absent | 6522 // Note: revisit design to have dual undefined values to capture absent |
6316 // elements. | 6523 // elements. |
6317 Object* JSObject::SetFastElement(uint32_t index, Object* value) { | 6524 MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) { |
6318 ASSERT(HasFastElements()); | 6525 ASSERT(HasFastElements()); |
6319 | 6526 |
6320 Object* elms_obj = EnsureWritableFastElements(); | 6527 Object* elms_obj; |
6321 if (elms_obj->IsFailure()) return elms_obj; | 6528 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); |
| 6529 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 6530 } |
6322 FixedArray* elms = FixedArray::cast(elms_obj); | 6531 FixedArray* elms = FixedArray::cast(elms_obj); |
6323 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 6532 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
6324 | 6533 |
6325 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { | 6534 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { |
6326 if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 6535 if (SetElementWithCallbackSetterInPrototypes(index, value)) { |
6327 return value; | 6536 return value; |
6328 } | 6537 } |
6329 } | 6538 } |
6330 | 6539 |
6331 // Check whether there is extra space in fixed array.. | 6540 // Check whether there is extra space in fixed array.. |
(...skipping 10 matching lines...) Expand all Loading... |
6342 return value; | 6551 return value; |
6343 } | 6552 } |
6344 | 6553 |
6345 // Allow gap in fast case. | 6554 // Allow gap in fast case. |
6346 if ((index - elms_length) < kMaxGap) { | 6555 if ((index - elms_length) < kMaxGap) { |
6347 // Try allocating extra space. | 6556 // Try allocating extra space. |
6348 int new_capacity = NewElementsCapacity(index+1); | 6557 int new_capacity = NewElementsCapacity(index+1); |
6349 if (new_capacity <= kMaxFastElementsLength || | 6558 if (new_capacity <= kMaxFastElementsLength || |
6350 !ShouldConvertToSlowElements(new_capacity)) { | 6559 !ShouldConvertToSlowElements(new_capacity)) { |
6351 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 6560 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
6352 Object* obj = SetFastElementsCapacityAndLength(new_capacity, index + 1); | 6561 Object* obj; |
6353 if (obj->IsFailure()) return obj; | 6562 { MaybeObject* maybe_obj = |
| 6563 SetFastElementsCapacityAndLength(new_capacity, index + 1); |
| 6564 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6565 } |
6354 FixedArray::cast(elements())->set(index, value); | 6566 FixedArray::cast(elements())->set(index, value); |
6355 return value; | 6567 return value; |
6356 } | 6568 } |
6357 } | 6569 } |
6358 | 6570 |
6359 // Otherwise default to slow case. | 6571 // Otherwise default to slow case. |
6360 Object* obj = NormalizeElements(); | 6572 Object* obj; |
6361 if (obj->IsFailure()) return obj; | 6573 { MaybeObject* maybe_obj = NormalizeElements(); |
| 6574 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6575 } |
6362 ASSERT(HasDictionaryElements()); | 6576 ASSERT(HasDictionaryElements()); |
6363 return SetElement(index, value); | 6577 return SetElement(index, value); |
6364 } | 6578 } |
6365 | 6579 |
6366 | 6580 |
6367 Object* JSObject::SetElement(uint32_t index, Object* value) { | 6581 MaybeObject* JSObject::SetElement(uint32_t index, Object* value) { |
6368 // Check access rights if needed. | 6582 // Check access rights if needed. |
6369 if (IsAccessCheckNeeded() && | 6583 if (IsAccessCheckNeeded() && |
6370 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 6584 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
6371 HandleScope scope; | 6585 HandleScope scope; |
6372 Handle<Object> value_handle(value); | 6586 Handle<Object> value_handle(value); |
6373 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6587 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
6374 return *value_handle; | 6588 return *value_handle; |
6375 } | 6589 } |
6376 | 6590 |
6377 if (IsJSGlobalProxy()) { | 6591 if (IsJSGlobalProxy()) { |
6378 Object* proto = GetPrototype(); | 6592 Object* proto = GetPrototype(); |
6379 if (proto->IsNull()) return value; | 6593 if (proto->IsNull()) return value; |
6380 ASSERT(proto->IsJSGlobalObject()); | 6594 ASSERT(proto->IsJSGlobalObject()); |
6381 return JSObject::cast(proto)->SetElement(index, value); | 6595 return JSObject::cast(proto)->SetElement(index, value); |
6382 } | 6596 } |
6383 | 6597 |
6384 // Check for lookup interceptor | 6598 // Check for lookup interceptor |
6385 if (HasIndexedInterceptor()) { | 6599 if (HasIndexedInterceptor()) { |
6386 return SetElementWithInterceptor(index, value); | 6600 return SetElementWithInterceptor(index, value); |
6387 } | 6601 } |
6388 | 6602 |
6389 return SetElementWithoutInterceptor(index, value); | 6603 return SetElementWithoutInterceptor(index, value); |
6390 } | 6604 } |
6391 | 6605 |
6392 | 6606 |
6393 Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) { | 6607 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
| 6608 Object* value) { |
6394 switch (GetElementsKind()) { | 6609 switch (GetElementsKind()) { |
6395 case FAST_ELEMENTS: | 6610 case FAST_ELEMENTS: |
6396 // Fast case. | 6611 // Fast case. |
6397 return SetFastElement(index, value); | 6612 return SetFastElement(index, value); |
6398 case PIXEL_ELEMENTS: { | 6613 case PIXEL_ELEMENTS: { |
6399 PixelArray* pixels = PixelArray::cast(elements()); | 6614 PixelArray* pixels = PixelArray::cast(elements()); |
6400 return pixels->SetValue(index, value); | 6615 return pixels->SetValue(index, value); |
6401 } | 6616 } |
6402 case EXTERNAL_BYTE_ELEMENTS: { | 6617 case EXTERNAL_BYTE_ELEMENTS: { |
6403 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 6618 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6454 } | 6669 } |
6455 // When we set the is_extensible flag to false we always force | 6670 // When we set the is_extensible flag to false we always force |
6456 // the element into dictionary mode (and force them to stay there). | 6671 // the element into dictionary mode (and force them to stay there). |
6457 if (!map()->is_extensible()) { | 6672 if (!map()->is_extensible()) { |
6458 Handle<Object> number(Factory::NewNumberFromUint(index)); | 6673 Handle<Object> number(Factory::NewNumberFromUint(index)); |
6459 Handle<String> index_string(Factory::NumberToString(number)); | 6674 Handle<String> index_string(Factory::NumberToString(number)); |
6460 Handle<Object> args[1] = { index_string }; | 6675 Handle<Object> args[1] = { index_string }; |
6461 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 6676 return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
6462 HandleVector(args, 1))); | 6677 HandleVector(args, 1))); |
6463 } | 6678 } |
6464 Object* result = dictionary->AtNumberPut(index, value); | 6679 Object* result; |
6465 if (result->IsFailure()) return result; | 6680 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value); |
| 6681 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6682 } |
6466 if (elms != FixedArray::cast(result)) { | 6683 if (elms != FixedArray::cast(result)) { |
6467 set_elements(FixedArray::cast(result)); | 6684 set_elements(FixedArray::cast(result)); |
6468 } | 6685 } |
6469 } | 6686 } |
6470 | 6687 |
6471 // Update the array length if this JSObject is an array. | 6688 // Update the array length if this JSObject is an array. |
6472 if (IsJSArray()) { | 6689 if (IsJSArray()) { |
6473 JSArray* array = JSArray::cast(this); | 6690 JSArray* array = JSArray::cast(this); |
6474 Object* return_value = array->JSArrayUpdateLengthFromIndex(index, | 6691 Object* return_value; |
6475 value); | 6692 { MaybeObject* maybe_return_value = |
6476 if (return_value->IsFailure()) return return_value; | 6693 array->JSArrayUpdateLengthFromIndex(index, value); |
| 6694 if (!maybe_return_value->ToObject(&return_value)) { |
| 6695 return maybe_return_value; |
| 6696 } |
| 6697 } |
6477 } | 6698 } |
6478 | 6699 |
6479 // Attempt to put this object back in fast case. | 6700 // Attempt to put this object back in fast case. |
6480 if (ShouldConvertToFastElements()) { | 6701 if (ShouldConvertToFastElements()) { |
6481 uint32_t new_length = 0; | 6702 uint32_t new_length = 0; |
6482 if (IsJSArray()) { | 6703 if (IsJSArray()) { |
6483 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); | 6704 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); |
6484 } else { | 6705 } else { |
6485 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; | 6706 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; |
6486 } | 6707 } |
6487 Object* obj = SetFastElementsCapacityAndLength(new_length, new_length); | 6708 Object* obj; |
6488 if (obj->IsFailure()) return obj; | 6709 { MaybeObject* maybe_obj = |
| 6710 SetFastElementsCapacityAndLength(new_length, new_length); |
| 6711 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6712 } |
6489 #ifdef DEBUG | 6713 #ifdef DEBUG |
6490 if (FLAG_trace_normalization) { | 6714 if (FLAG_trace_normalization) { |
6491 PrintF("Object elements are fast case again:\n"); | 6715 PrintF("Object elements are fast case again:\n"); |
6492 Print(); | 6716 Print(); |
6493 } | 6717 } |
6494 #endif | 6718 #endif |
6495 } | 6719 } |
6496 | 6720 |
6497 return value; | 6721 return value; |
6498 } | 6722 } |
6499 default: | 6723 default: |
6500 UNREACHABLE(); | 6724 UNREACHABLE(); |
6501 break; | 6725 break; |
6502 } | 6726 } |
6503 // All possible cases have been handled above. Add a return to avoid the | 6727 // All possible cases have been handled above. Add a return to avoid the |
6504 // complaints from the compiler. | 6728 // complaints from the compiler. |
6505 UNREACHABLE(); | 6729 UNREACHABLE(); |
6506 return Heap::null_value(); | 6730 return Heap::null_value(); |
6507 } | 6731 } |
6508 | 6732 |
6509 | 6733 |
6510 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) { | 6734 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
| 6735 Object* value) { |
6511 uint32_t old_len = 0; | 6736 uint32_t old_len = 0; |
6512 CHECK(length()->ToArrayIndex(&old_len)); | 6737 CHECK(length()->ToArrayIndex(&old_len)); |
6513 // Check to see if we need to update the length. For now, we make | 6738 // Check to see if we need to update the length. For now, we make |
6514 // sure that the length stays within 32-bits (unsigned). | 6739 // sure that the length stays within 32-bits (unsigned). |
6515 if (index >= old_len && index != 0xffffffff) { | 6740 if (index >= old_len && index != 0xffffffff) { |
6516 Object* len = | 6741 Object* len; |
6517 Heap::NumberFromDouble(static_cast<double>(index) + 1); | 6742 { MaybeObject* maybe_len = |
6518 if (len->IsFailure()) return len; | 6743 Heap::NumberFromDouble(static_cast<double>(index) + 1); |
| 6744 if (!maybe_len->ToObject(&len)) return maybe_len; |
| 6745 } |
6519 set_length(len); | 6746 set_length(len); |
6520 } | 6747 } |
6521 return value; | 6748 return value; |
6522 } | 6749 } |
6523 | 6750 |
6524 | 6751 |
6525 Object* JSObject::GetElementPostInterceptor(JSObject* receiver, | 6752 MaybeObject* JSObject::GetElementPostInterceptor(JSObject* receiver, |
6526 uint32_t index) { | 6753 uint32_t index) { |
6527 // Get element works for both JSObject and JSArray since | 6754 // Get element works for both JSObject and JSArray since |
6528 // JSArray::length cannot change. | 6755 // JSArray::length cannot change. |
6529 switch (GetElementsKind()) { | 6756 switch (GetElementsKind()) { |
6530 case FAST_ELEMENTS: { | 6757 case FAST_ELEMENTS: { |
6531 FixedArray* elms = FixedArray::cast(elements()); | 6758 FixedArray* elms = FixedArray::cast(elements()); |
6532 if (index < static_cast<uint32_t>(elms->length())) { | 6759 if (index < static_cast<uint32_t>(elms->length())) { |
6533 Object* value = elms->get(index); | 6760 Object* value = elms->get(index); |
6534 if (!value->IsTheHole()) return value; | 6761 if (!value->IsTheHole()) return value; |
6535 } | 6762 } |
6536 break; | 6763 break; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6572 break; | 6799 break; |
6573 } | 6800 } |
6574 | 6801 |
6575 // Continue searching via the prototype chain. | 6802 // Continue searching via the prototype chain. |
6576 Object* pt = GetPrototype(); | 6803 Object* pt = GetPrototype(); |
6577 if (pt == Heap::null_value()) return Heap::undefined_value(); | 6804 if (pt == Heap::null_value()) return Heap::undefined_value(); |
6578 return pt->GetElementWithReceiver(receiver, index); | 6805 return pt->GetElementWithReceiver(receiver, index); |
6579 } | 6806 } |
6580 | 6807 |
6581 | 6808 |
6582 Object* JSObject::GetElementWithInterceptor(JSObject* receiver, | 6809 MaybeObject* JSObject::GetElementWithInterceptor(JSObject* receiver, |
6583 uint32_t index) { | 6810 uint32_t index) { |
6584 // Make sure that the top context does not change when doing | 6811 // Make sure that the top context does not change when doing |
6585 // callbacks or interceptor calls. | 6812 // callbacks or interceptor calls. |
6586 AssertNoContextChange ncc; | 6813 AssertNoContextChange ncc; |
6587 HandleScope scope; | 6814 HandleScope scope; |
6588 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6815 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
6589 Handle<JSObject> this_handle(receiver); | 6816 Handle<JSObject> this_handle(receiver); |
6590 Handle<JSObject> holder_handle(this); | 6817 Handle<JSObject> holder_handle(this); |
6591 | 6818 |
6592 if (!interceptor->getter()->IsUndefined()) { | 6819 if (!interceptor->getter()->IsUndefined()) { |
6593 v8::IndexedPropertyGetter getter = | 6820 v8::IndexedPropertyGetter getter = |
6594 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); | 6821 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); |
6595 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); | 6822 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); |
6596 CustomArguments args(interceptor->data(), receiver, this); | 6823 CustomArguments args(interceptor->data(), receiver, this); |
6597 v8::AccessorInfo info(args.end()); | 6824 v8::AccessorInfo info(args.end()); |
6598 v8::Handle<v8::Value> result; | 6825 v8::Handle<v8::Value> result; |
6599 { | 6826 { |
6600 // Leaving JavaScript. | 6827 // Leaving JavaScript. |
6601 VMState state(EXTERNAL); | 6828 VMState state(EXTERNAL); |
6602 result = getter(index, info); | 6829 result = getter(index, info); |
6603 } | 6830 } |
6604 RETURN_IF_SCHEDULED_EXCEPTION(); | 6831 RETURN_IF_SCHEDULED_EXCEPTION(); |
6605 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 6832 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
6606 } | 6833 } |
6607 | 6834 |
6608 Object* raw_result = | 6835 MaybeObject* raw_result = |
6609 holder_handle->GetElementPostInterceptor(*this_handle, index); | 6836 holder_handle->GetElementPostInterceptor(*this_handle, index); |
6610 RETURN_IF_SCHEDULED_EXCEPTION(); | 6837 RETURN_IF_SCHEDULED_EXCEPTION(); |
6611 return raw_result; | 6838 return raw_result; |
6612 } | 6839 } |
6613 | 6840 |
6614 | 6841 |
6615 Object* JSObject::GetElementWithReceiver(JSObject* receiver, uint32_t index) { | 6842 MaybeObject* JSObject::GetElementWithReceiver(JSObject* receiver, |
| 6843 uint32_t index) { |
6616 // Check access rights if needed. | 6844 // Check access rights if needed. |
6617 if (IsAccessCheckNeeded() && | 6845 if (IsAccessCheckNeeded() && |
6618 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 6846 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
6619 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); | 6847 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); |
6620 return Heap::undefined_value(); | 6848 return Heap::undefined_value(); |
6621 } | 6849 } |
6622 | 6850 |
6623 if (HasIndexedInterceptor()) { | 6851 if (HasIndexedInterceptor()) { |
6624 return GetElementWithInterceptor(receiver, index); | 6852 return GetElementWithInterceptor(receiver, index); |
6625 } | 6853 } |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6856 InterceptorInfo* JSObject::GetIndexedInterceptor() { | 7084 InterceptorInfo* JSObject::GetIndexedInterceptor() { |
6857 ASSERT(map()->has_indexed_interceptor()); | 7085 ASSERT(map()->has_indexed_interceptor()); |
6858 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 7086 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
6859 ASSERT(constructor->shared()->IsApiFunction()); | 7087 ASSERT(constructor->shared()->IsApiFunction()); |
6860 Object* result = | 7088 Object* result = |
6861 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 7089 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
6862 return InterceptorInfo::cast(result); | 7090 return InterceptorInfo::cast(result); |
6863 } | 7091 } |
6864 | 7092 |
6865 | 7093 |
6866 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, | 7094 MaybeObject* JSObject::GetPropertyPostInterceptor( |
6867 String* name, | 7095 JSObject* receiver, |
6868 PropertyAttributes* attributes) { | 7096 String* name, |
| 7097 PropertyAttributes* attributes) { |
6869 // Check local property in holder, ignore interceptor. | 7098 // Check local property in holder, ignore interceptor. |
6870 LookupResult result; | 7099 LookupResult result; |
6871 LocalLookupRealNamedProperty(name, &result); | 7100 LocalLookupRealNamedProperty(name, &result); |
6872 if (result.IsProperty()) { | 7101 if (result.IsProperty()) { |
6873 return GetProperty(receiver, &result, name, attributes); | 7102 return GetProperty(receiver, &result, name, attributes); |
6874 } | 7103 } |
6875 // Continue searching via the prototype chain. | 7104 // Continue searching via the prototype chain. |
6876 Object* pt = GetPrototype(); | 7105 Object* pt = GetPrototype(); |
6877 *attributes = ABSENT; | 7106 *attributes = ABSENT; |
6878 if (pt == Heap::null_value()) return Heap::undefined_value(); | 7107 if (pt == Heap::null_value()) return Heap::undefined_value(); |
6879 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 7108 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
6880 } | 7109 } |
6881 | 7110 |
6882 | 7111 |
6883 Object* JSObject::GetLocalPropertyPostInterceptor( | 7112 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
6884 JSObject* receiver, | 7113 JSObject* receiver, |
6885 String* name, | 7114 String* name, |
6886 PropertyAttributes* attributes) { | 7115 PropertyAttributes* attributes) { |
6887 // Check local property in holder, ignore interceptor. | 7116 // Check local property in holder, ignore interceptor. |
6888 LookupResult result; | 7117 LookupResult result; |
6889 LocalLookupRealNamedProperty(name, &result); | 7118 LocalLookupRealNamedProperty(name, &result); |
6890 if (result.IsProperty()) { | 7119 if (result.IsProperty()) { |
6891 return GetProperty(receiver, &result, name, attributes); | 7120 return GetProperty(receiver, &result, name, attributes); |
6892 } | 7121 } |
6893 return Heap::undefined_value(); | 7122 return Heap::undefined_value(); |
6894 } | 7123 } |
6895 | 7124 |
6896 | 7125 |
6897 Object* JSObject::GetPropertyWithInterceptor( | 7126 MaybeObject* JSObject::GetPropertyWithInterceptor( |
6898 JSObject* receiver, | 7127 JSObject* receiver, |
6899 String* name, | 7128 String* name, |
6900 PropertyAttributes* attributes) { | 7129 PropertyAttributes* attributes) { |
6901 InterceptorInfo* interceptor = GetNamedInterceptor(); | 7130 InterceptorInfo* interceptor = GetNamedInterceptor(); |
6902 HandleScope scope; | 7131 HandleScope scope; |
6903 Handle<JSObject> receiver_handle(receiver); | 7132 Handle<JSObject> receiver_handle(receiver); |
6904 Handle<JSObject> holder_handle(this); | 7133 Handle<JSObject> holder_handle(this); |
6905 Handle<String> name_handle(name); | 7134 Handle<String> name_handle(name); |
6906 | 7135 |
6907 if (!interceptor->getter()->IsUndefined()) { | 7136 if (!interceptor->getter()->IsUndefined()) { |
6908 v8::NamedPropertyGetter getter = | 7137 v8::NamedPropertyGetter getter = |
6909 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); | 7138 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); |
6910 LOG(ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); | 7139 LOG(ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); |
6911 CustomArguments args(interceptor->data(), receiver, this); | 7140 CustomArguments args(interceptor->data(), receiver, this); |
6912 v8::AccessorInfo info(args.end()); | 7141 v8::AccessorInfo info(args.end()); |
6913 v8::Handle<v8::Value> result; | 7142 v8::Handle<v8::Value> result; |
6914 { | 7143 { |
6915 // Leaving JavaScript. | 7144 // Leaving JavaScript. |
6916 VMState state(EXTERNAL); | 7145 VMState state(EXTERNAL); |
6917 result = getter(v8::Utils::ToLocal(name_handle), info); | 7146 result = getter(v8::Utils::ToLocal(name_handle), info); |
6918 } | 7147 } |
6919 RETURN_IF_SCHEDULED_EXCEPTION(); | 7148 RETURN_IF_SCHEDULED_EXCEPTION(); |
6920 if (!result.IsEmpty()) { | 7149 if (!result.IsEmpty()) { |
6921 *attributes = NONE; | 7150 *attributes = NONE; |
6922 return *v8::Utils::OpenHandle(*result); | 7151 return *v8::Utils::OpenHandle(*result); |
6923 } | 7152 } |
6924 } | 7153 } |
6925 | 7154 |
6926 Object* result = holder_handle->GetPropertyPostInterceptor( | 7155 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( |
6927 *receiver_handle, | 7156 *receiver_handle, |
6928 *name_handle, | 7157 *name_handle, |
6929 attributes); | 7158 attributes); |
6930 RETURN_IF_SCHEDULED_EXCEPTION(); | 7159 RETURN_IF_SCHEDULED_EXCEPTION(); |
6931 return result; | 7160 return result; |
6932 } | 7161 } |
6933 | 7162 |
6934 | 7163 |
6935 bool JSObject::HasRealNamedProperty(String* key) { | 7164 bool JSObject::HasRealNamedProperty(String* key) { |
6936 // Check access rights if needed. | 7165 // Check access rights if needed. |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7271 return ComputeIntegerHash(key); | 7500 return ComputeIntegerHash(key); |
7272 } | 7501 } |
7273 | 7502 |
7274 | 7503 |
7275 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) { | 7504 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) { |
7276 ASSERT(other->IsNumber()); | 7505 ASSERT(other->IsNumber()); |
7277 return ComputeIntegerHash(static_cast<uint32_t>(other->Number())); | 7506 return ComputeIntegerHash(static_cast<uint32_t>(other->Number())); |
7278 } | 7507 } |
7279 | 7508 |
7280 | 7509 |
7281 Object* NumberDictionaryShape::AsObject(uint32_t key) { | 7510 MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) { |
7282 return Heap::NumberFromUint32(key); | 7511 return Heap::NumberFromUint32(key); |
7283 } | 7512 } |
7284 | 7513 |
7285 | 7514 |
7286 bool StringDictionaryShape::IsMatch(String* key, Object* other) { | 7515 bool StringDictionaryShape::IsMatch(String* key, Object* other) { |
7287 // We know that all entries in a hash table had their hash keys created. | 7516 // We know that all entries in a hash table had their hash keys created. |
7288 // Use that knowledge to have fast failure. | 7517 // Use that knowledge to have fast failure. |
7289 if (key->Hash() != String::cast(other)->Hash()) return false; | 7518 if (key->Hash() != String::cast(other)->Hash()) return false; |
7290 return key->Equals(String::cast(other)); | 7519 return key->Equals(String::cast(other)); |
7291 } | 7520 } |
7292 | 7521 |
7293 | 7522 |
7294 uint32_t StringDictionaryShape::Hash(String* key) { | 7523 uint32_t StringDictionaryShape::Hash(String* key) { |
7295 return key->Hash(); | 7524 return key->Hash(); |
7296 } | 7525 } |
7297 | 7526 |
7298 | 7527 |
7299 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) { | 7528 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) { |
7300 return String::cast(other)->Hash(); | 7529 return String::cast(other)->Hash(); |
7301 } | 7530 } |
7302 | 7531 |
7303 | 7532 |
7304 Object* StringDictionaryShape::AsObject(String* key) { | 7533 MaybeObject* StringDictionaryShape::AsObject(String* key) { |
7305 return key; | 7534 return key; |
7306 } | 7535 } |
7307 | 7536 |
7308 | 7537 |
7309 // StringKey simply carries a string object as key. | 7538 // StringKey simply carries a string object as key. |
7310 class StringKey : public HashTableKey { | 7539 class StringKey : public HashTableKey { |
7311 public: | 7540 public: |
7312 explicit StringKey(String* string) : | 7541 explicit StringKey(String* string) : |
7313 string_(string), | 7542 string_(string), |
7314 hash_(HashForObject(string)) { } | 7543 hash_(HashForObject(string)) { } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7368 return StringSharedHashHelper(source_, shared_); | 7597 return StringSharedHashHelper(source_, shared_); |
7369 } | 7598 } |
7370 | 7599 |
7371 uint32_t HashForObject(Object* obj) { | 7600 uint32_t HashForObject(Object* obj) { |
7372 FixedArray* pair = FixedArray::cast(obj); | 7601 FixedArray* pair = FixedArray::cast(obj); |
7373 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); | 7602 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); |
7374 String* source = String::cast(pair->get(1)); | 7603 String* source = String::cast(pair->get(1)); |
7375 return StringSharedHashHelper(source, shared); | 7604 return StringSharedHashHelper(source, shared); |
7376 } | 7605 } |
7377 | 7606 |
7378 Object* AsObject() { | 7607 MUST_USE_RESULT MaybeObject* AsObject() { |
7379 Object* obj = Heap::AllocateFixedArray(2); | 7608 Object* obj; |
7380 if (obj->IsFailure()) return obj; | 7609 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2); |
| 7610 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7611 } |
7381 FixedArray* pair = FixedArray::cast(obj); | 7612 FixedArray* pair = FixedArray::cast(obj); |
7382 pair->set(0, shared_); | 7613 pair->set(0, shared_); |
7383 pair->set(1, source_); | 7614 pair->set(1, source_); |
7384 return pair; | 7615 return pair; |
7385 } | 7616 } |
7386 | 7617 |
7387 private: | 7618 private: |
7388 String* source_; | 7619 String* source_; |
7389 SharedFunctionInfo* shared_; | 7620 SharedFunctionInfo* shared_; |
7390 }; | 7621 }; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7448 hash_field_ = String::ComputeHashField(&buffer, chars_); | 7679 hash_field_ = String::ComputeHashField(&buffer, chars_); |
7449 uint32_t result = hash_field_ >> String::kHashShift; | 7680 uint32_t result = hash_field_ >> String::kHashShift; |
7450 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 7681 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
7451 return result; | 7682 return result; |
7452 } | 7683 } |
7453 | 7684 |
7454 uint32_t HashForObject(Object* other) { | 7685 uint32_t HashForObject(Object* other) { |
7455 return String::cast(other)->Hash(); | 7686 return String::cast(other)->Hash(); |
7456 } | 7687 } |
7457 | 7688 |
7458 Object* AsObject() { | 7689 MaybeObject* AsObject() { |
7459 if (hash_field_ == 0) Hash(); | 7690 if (hash_field_ == 0) Hash(); |
7460 return Heap::AllocateSymbol(string_, chars_, hash_field_); | 7691 return Heap::AllocateSymbol(string_, chars_, hash_field_); |
7461 } | 7692 } |
7462 | 7693 |
7463 Vector<const char> string_; | 7694 Vector<const char> string_; |
7464 uint32_t hash_field_; | 7695 uint32_t hash_field_; |
7465 int chars_; // Caches the number of characters when computing the hash code. | 7696 int chars_; // Caches the number of characters when computing the hash code. |
7466 }; | 7697 }; |
7467 | 7698 |
7468 | 7699 |
7469 // SymbolKey carries a string/symbol object as key. | 7700 // SymbolKey carries a string/symbol object as key. |
7470 class SymbolKey : public HashTableKey { | 7701 class SymbolKey : public HashTableKey { |
7471 public: | 7702 public: |
7472 explicit SymbolKey(String* string) : string_(string) { } | 7703 explicit SymbolKey(String* string) : string_(string) { } |
7473 | 7704 |
7474 bool IsMatch(Object* string) { | 7705 bool IsMatch(Object* string) { |
7475 return String::cast(string)->Equals(string_); | 7706 return String::cast(string)->Equals(string_); |
7476 } | 7707 } |
7477 | 7708 |
7478 uint32_t Hash() { return string_->Hash(); } | 7709 uint32_t Hash() { return string_->Hash(); } |
7479 | 7710 |
7480 uint32_t HashForObject(Object* other) { | 7711 uint32_t HashForObject(Object* other) { |
7481 return String::cast(other)->Hash(); | 7712 return String::cast(other)->Hash(); |
7482 } | 7713 } |
7483 | 7714 |
7484 Object* AsObject() { | 7715 MaybeObject* AsObject() { |
7485 // Attempt to flatten the string, so that symbols will most often | 7716 // Attempt to flatten the string, so that symbols will most often |
7486 // be flat strings. | 7717 // be flat strings. |
7487 string_ = string_->TryFlattenGetString(); | 7718 string_ = string_->TryFlattenGetString(); |
7488 // Transform string to symbol if possible. | 7719 // Transform string to symbol if possible. |
7489 Map* map = Heap::SymbolMapForString(string_); | 7720 Map* map = Heap::SymbolMapForString(string_); |
7490 if (map != NULL) { | 7721 if (map != NULL) { |
7491 string_->set_map(map); | 7722 string_->set_map(map); |
7492 ASSERT(string_->IsSymbol()); | 7723 ASSERT(string_->IsSymbol()); |
7493 return string_; | 7724 return string_; |
7494 } | 7725 } |
(...skipping 20 matching lines...) Expand all Loading... |
7515 | 7746 |
7516 template<typename Shape, typename Key> | 7747 template<typename Shape, typename Key> |
7517 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 7748 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { |
7518 IteratePointers(v, | 7749 IteratePointers(v, |
7519 kElementsStartOffset, | 7750 kElementsStartOffset, |
7520 kHeaderSize + length() * kPointerSize); | 7751 kHeaderSize + length() * kPointerSize); |
7521 } | 7752 } |
7522 | 7753 |
7523 | 7754 |
7524 template<typename Shape, typename Key> | 7755 template<typename Shape, typename Key> |
7525 Object* HashTable<Shape, Key>::Allocate(int at_least_space_for, | 7756 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for, |
7526 PretenureFlag pretenure) { | 7757 PretenureFlag pretenure) { |
7527 const int kMinCapacity = 32; | 7758 const int kMinCapacity = 32; |
7528 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); | 7759 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); |
7529 if (capacity < kMinCapacity) { | 7760 if (capacity < kMinCapacity) { |
7530 capacity = kMinCapacity; // Guarantee min capacity. | 7761 capacity = kMinCapacity; // Guarantee min capacity. |
7531 } else if (capacity > HashTable::kMaxCapacity) { | 7762 } else if (capacity > HashTable::kMaxCapacity) { |
7532 return Failure::OutOfMemoryException(); | 7763 return Failure::OutOfMemoryException(); |
7533 } | 7764 } |
7534 | 7765 |
7535 Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity), pretenure); | 7766 Object* obj; |
7536 if (!obj->IsFailure()) { | 7767 { MaybeObject* maybe_obj = |
7537 HashTable::cast(obj)->SetNumberOfElements(0); | 7768 Heap::AllocateHashTable(EntryToIndex(capacity), pretenure); |
7538 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 7769 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7539 HashTable::cast(obj)->SetCapacity(capacity); | |
7540 } | 7770 } |
| 7771 HashTable::cast(obj)->SetNumberOfElements(0); |
| 7772 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 7773 HashTable::cast(obj)->SetCapacity(capacity); |
7541 return obj; | 7774 return obj; |
7542 } | 7775 } |
7543 | 7776 |
7544 | 7777 |
7545 // Find entry for key otherwise return kNotFound. | 7778 // Find entry for key otherwise return kNotFound. |
7546 template<typename Shape, typename Key> | 7779 template<typename Shape, typename Key> |
7547 int HashTable<Shape, Key>::FindEntry(Key key) { | 7780 int HashTable<Shape, Key>::FindEntry(Key key) { |
7548 uint32_t capacity = Capacity(); | 7781 uint32_t capacity = Capacity(); |
7549 uint32_t entry = FirstProbe(Shape::Hash(key), capacity); | 7782 uint32_t entry = FirstProbe(Shape::Hash(key), capacity); |
7550 uint32_t count = 1; | 7783 uint32_t count = 1; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7593 return entry; | 7826 return entry; |
7594 } | 7827 } |
7595 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); | 7828 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); |
7596 entry = NextProbe(entry, count++, capacity); | 7829 entry = NextProbe(entry, count++, capacity); |
7597 } | 7830 } |
7598 return kNotFound; | 7831 return kNotFound; |
7599 } | 7832 } |
7600 | 7833 |
7601 | 7834 |
7602 template<typename Shape, typename Key> | 7835 template<typename Shape, typename Key> |
7603 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 7836 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
7604 int capacity = Capacity(); | 7837 int capacity = Capacity(); |
7605 int nof = NumberOfElements() + n; | 7838 int nof = NumberOfElements() + n; |
7606 int nod = NumberOfDeletedElements(); | 7839 int nod = NumberOfDeletedElements(); |
7607 // Return if: | 7840 // Return if: |
7608 // 50% is still free after adding n elements and | 7841 // 50% is still free after adding n elements and |
7609 // at most 50% of the free elements are deleted elements. | 7842 // at most 50% of the free elements are deleted elements. |
7610 if (nod <= (capacity - nof) >> 1) { | 7843 if (nod <= (capacity - nof) >> 1) { |
7611 int needed_free = nof >> 1; | 7844 int needed_free = nof >> 1; |
7612 if (nof + needed_free <= capacity) return this; | 7845 if (nof + needed_free <= capacity) return this; |
7613 } | 7846 } |
7614 | 7847 |
7615 const int kMinCapacityForPretenure = 256; | 7848 const int kMinCapacityForPretenure = 256; |
7616 bool pretenure = | 7849 bool pretenure = |
7617 (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this); | 7850 (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this); |
7618 Object* obj = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); | 7851 Object* obj; |
7619 if (obj->IsFailure()) return obj; | 7852 { MaybeObject* maybe_obj = |
| 7853 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); |
| 7854 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7855 } |
7620 | 7856 |
7621 AssertNoAllocation no_gc; | 7857 AssertNoAllocation no_gc; |
7622 HashTable* table = HashTable::cast(obj); | 7858 HashTable* table = HashTable::cast(obj); |
7623 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); | 7859 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); |
7624 | 7860 |
7625 // Copy prefix to new array. | 7861 // Copy prefix to new array. |
7626 for (int i = kPrefixStartIndex; | 7862 for (int i = kPrefixStartIndex; |
7627 i < kPrefixStartIndex + Shape::kPrefixSize; | 7863 i < kPrefixStartIndex + Shape::kPrefixSize; |
7628 i++) { | 7864 i++) { |
7629 table->set(i, get(i), mode); | 7865 table->set(i, get(i), mode); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7667 template class HashTable<SymbolTableShape, HashTableKey*>; | 7903 template class HashTable<SymbolTableShape, HashTableKey*>; |
7668 | 7904 |
7669 template class HashTable<CompilationCacheShape, HashTableKey*>; | 7905 template class HashTable<CompilationCacheShape, HashTableKey*>; |
7670 | 7906 |
7671 template class HashTable<MapCacheShape, HashTableKey*>; | 7907 template class HashTable<MapCacheShape, HashTableKey*>; |
7672 | 7908 |
7673 template class Dictionary<StringDictionaryShape, String*>; | 7909 template class Dictionary<StringDictionaryShape, String*>; |
7674 | 7910 |
7675 template class Dictionary<NumberDictionaryShape, uint32_t>; | 7911 template class Dictionary<NumberDictionaryShape, uint32_t>; |
7676 | 7912 |
7677 template Object* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( | 7913 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( |
7678 int); | 7914 int); |
7679 | 7915 |
7680 template Object* Dictionary<StringDictionaryShape, String*>::Allocate( | 7916 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( |
7681 int); | 7917 int); |
7682 | 7918 |
7683 template Object* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( | 7919 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( |
7684 uint32_t, Object*); | 7920 uint32_t, Object*); |
7685 | 7921 |
7686 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( | 7922 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( |
7687 Object*); | 7923 Object*); |
7688 | 7924 |
7689 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( | 7925 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( |
7690 Object*); | 7926 Object*); |
7691 | 7927 |
7692 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( | 7928 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( |
7693 FixedArray*, PropertyAttributes); | 7929 FixedArray*, PropertyAttributes); |
7694 | 7930 |
7695 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( | 7931 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( |
7696 int, JSObject::DeleteMode); | 7932 int, JSObject::DeleteMode); |
7697 | 7933 |
7698 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( | 7934 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( |
7699 int, JSObject::DeleteMode); | 7935 int, JSObject::DeleteMode); |
7700 | 7936 |
7701 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( | 7937 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( |
7702 FixedArray*); | 7938 FixedArray*); |
7703 | 7939 |
7704 template int | 7940 template int |
7705 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( | 7941 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( |
7706 PropertyAttributes); | 7942 PropertyAttributes); |
7707 | 7943 |
7708 template Object* Dictionary<StringDictionaryShape, String*>::Add( | 7944 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( |
7709 String*, Object*, PropertyDetails); | 7945 String*, Object*, PropertyDetails); |
7710 | 7946 |
7711 template Object* | 7947 template MaybeObject* |
7712 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); | 7948 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); |
7713 | 7949 |
7714 template int | 7950 template int |
7715 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes( | 7951 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes( |
7716 PropertyAttributes); | 7952 PropertyAttributes); |
7717 | 7953 |
7718 template Object* Dictionary<NumberDictionaryShape, uint32_t>::Add( | 7954 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add( |
7719 uint32_t, Object*, PropertyDetails); | 7955 uint32_t, Object*, PropertyDetails); |
7720 | 7956 |
7721 template Object* Dictionary<NumberDictionaryShape, uint32_t>::EnsureCapacity( | 7957 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>:: |
7722 int, uint32_t); | 7958 EnsureCapacity(int, uint32_t); |
7723 | 7959 |
7724 template Object* Dictionary<StringDictionaryShape, String*>::EnsureCapacity( | 7960 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: |
7725 int, String*); | 7961 EnsureCapacity(int, String*); |
7726 | 7962 |
7727 template Object* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry( | 7963 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry( |
7728 uint32_t, Object*, PropertyDetails, uint32_t); | 7964 uint32_t, Object*, PropertyDetails, uint32_t); |
7729 | 7965 |
7730 template Object* Dictionary<StringDictionaryShape, String*>::AddEntry( | 7966 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( |
7731 String*, Object*, PropertyDetails, uint32_t); | 7967 String*, Object*, PropertyDetails, uint32_t); |
7732 | 7968 |
7733 template | 7969 template |
7734 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 7970 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements(); |
7735 | 7971 |
7736 template | 7972 template |
7737 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 7973 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
7738 | 7974 |
7739 template | 7975 template |
7740 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 7976 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
7741 | 7977 |
7742 | 7978 |
7743 // Collates undefined and unexisting elements below limit from position | 7979 // Collates undefined and unexisting elements below limit from position |
7744 // zero of the elements. The object stays in Dictionary mode. | 7980 // zero of the elements. The object stays in Dictionary mode. |
7745 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 7981 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
7746 ASSERT(HasDictionaryElements()); | 7982 ASSERT(HasDictionaryElements()); |
7747 // Must stay in dictionary mode, either because of requires_slow_elements, | 7983 // Must stay in dictionary mode, either because of requires_slow_elements, |
7748 // or because we are not going to sort (and therefore compact) all of the | 7984 // or because we are not going to sort (and therefore compact) all of the |
7749 // elements. | 7985 // elements. |
7750 NumberDictionary* dict = element_dictionary(); | 7986 NumberDictionary* dict = element_dictionary(); |
7751 HeapNumber* result_double = NULL; | 7987 HeapNumber* result_double = NULL; |
7752 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 7988 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
7753 // Allocate space for result before we start mutating the object. | 7989 // Allocate space for result before we start mutating the object. |
7754 Object* new_double = Heap::AllocateHeapNumber(0.0); | 7990 Object* new_double; |
7755 if (new_double->IsFailure()) return new_double; | 7991 { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0); |
| 7992 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
| 7993 } |
7756 result_double = HeapNumber::cast(new_double); | 7994 result_double = HeapNumber::cast(new_double); |
7757 } | 7995 } |
7758 | 7996 |
7759 Object* obj = NumberDictionary::Allocate(dict->NumberOfElements()); | 7997 Object* obj; |
7760 if (obj->IsFailure()) return obj; | 7998 { MaybeObject* maybe_obj = |
| 7999 NumberDictionary::Allocate(dict->NumberOfElements()); |
| 8000 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8001 } |
7761 NumberDictionary* new_dict = NumberDictionary::cast(obj); | 8002 NumberDictionary* new_dict = NumberDictionary::cast(obj); |
7762 | 8003 |
7763 AssertNoAllocation no_alloc; | 8004 AssertNoAllocation no_alloc; |
7764 | 8005 |
7765 uint32_t pos = 0; | 8006 uint32_t pos = 0; |
7766 uint32_t undefs = 0; | 8007 uint32_t undefs = 0; |
7767 int capacity = dict->Capacity(); | 8008 int capacity = dict->Capacity(); |
7768 for (int i = 0; i < capacity; i++) { | 8009 for (int i = 0; i < capacity; i++) { |
7769 Object* k = dict->KeyAt(i); | 8010 Object* k = dict->KeyAt(i); |
7770 if (dict->IsKey(k)) { | 8011 if (dict->IsKey(k)) { |
7771 ASSERT(k->IsNumber()); | 8012 ASSERT(k->IsNumber()); |
7772 ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0); | 8013 ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
7773 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); | 8014 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
7774 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); | 8015 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
7775 Object* value = dict->ValueAt(i); | 8016 Object* value = dict->ValueAt(i); |
7776 PropertyDetails details = dict->DetailsAt(i); | 8017 PropertyDetails details = dict->DetailsAt(i); |
7777 if (details.type() == CALLBACKS) { | 8018 if (details.type() == CALLBACKS) { |
7778 // Bail out and do the sorting of undefineds and array holes in JS. | 8019 // Bail out and do the sorting of undefineds and array holes in JS. |
7779 return Smi::FromInt(-1); | 8020 return Smi::FromInt(-1); |
7780 } | 8021 } |
7781 uint32_t key = NumberToUint32(k); | 8022 uint32_t key = NumberToUint32(k); |
| 8023 // In the following we assert that adding the entry to the new dictionary |
| 8024 // does not cause GC. This is the case because we made sure to allocate |
| 8025 // the dictionary big enough above, so it need not grow. |
7782 if (key < limit) { | 8026 if (key < limit) { |
7783 if (value->IsUndefined()) { | 8027 if (value->IsUndefined()) { |
7784 undefs++; | 8028 undefs++; |
7785 } else { | 8029 } else { |
7786 new_dict->AddNumberEntry(pos, value, details); | 8030 new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked(); |
7787 pos++; | 8031 pos++; |
7788 } | 8032 } |
7789 } else { | 8033 } else { |
7790 new_dict->AddNumberEntry(key, value, details); | 8034 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); |
7791 } | 8035 } |
7792 } | 8036 } |
7793 } | 8037 } |
7794 | 8038 |
7795 uint32_t result = pos; | 8039 uint32_t result = pos; |
7796 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); | 8040 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); |
7797 while (undefs > 0) { | 8041 while (undefs > 0) { |
7798 new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details); | 8042 new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details)-> |
| 8043 ToObjectUnchecked(); |
7799 pos++; | 8044 pos++; |
7800 undefs--; | 8045 undefs--; |
7801 } | 8046 } |
7802 | 8047 |
7803 set_elements(new_dict); | 8048 set_elements(new_dict); |
7804 | 8049 |
7805 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 8050 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
7806 return Smi::FromInt(static_cast<int>(result)); | 8051 return Smi::FromInt(static_cast<int>(result)); |
7807 } | 8052 } |
7808 | 8053 |
7809 ASSERT_NE(NULL, result_double); | 8054 ASSERT_NE(NULL, result_double); |
7810 result_double->set_value(static_cast<double>(result)); | 8055 result_double->set_value(static_cast<double>(result)); |
7811 return result_double; | 8056 return result_double; |
7812 } | 8057 } |
7813 | 8058 |
7814 | 8059 |
7815 // Collects all defined (non-hole) and non-undefined (array) elements at | 8060 // Collects all defined (non-hole) and non-undefined (array) elements at |
7816 // the start of the elements array. | 8061 // the start of the elements array. |
7817 // If the object is in dictionary mode, it is converted to fast elements | 8062 // If the object is in dictionary mode, it is converted to fast elements |
7818 // mode. | 8063 // mode. |
7819 Object* JSObject::PrepareElementsForSort(uint32_t limit) { | 8064 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
7820 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 8065 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
7821 | 8066 |
7822 if (HasDictionaryElements()) { | 8067 if (HasDictionaryElements()) { |
7823 // Convert to fast elements containing only the existing properties. | 8068 // Convert to fast elements containing only the existing properties. |
7824 // Ordering is irrelevant, since we are going to sort anyway. | 8069 // Ordering is irrelevant, since we are going to sort anyway. |
7825 NumberDictionary* dict = element_dictionary(); | 8070 NumberDictionary* dict = element_dictionary(); |
7826 if (IsJSArray() || dict->requires_slow_elements() || | 8071 if (IsJSArray() || dict->requires_slow_elements() || |
7827 dict->max_number_key() >= limit) { | 8072 dict->max_number_key() >= limit) { |
7828 return PrepareSlowElementsForSort(limit); | 8073 return PrepareSlowElementsForSort(limit); |
7829 } | 8074 } |
7830 // Convert to fast elements. | 8075 // Convert to fast elements. |
7831 | 8076 |
7832 Object* obj = map()->GetFastElementsMap(); | 8077 Object* obj; |
7833 if (obj->IsFailure()) return obj; | 8078 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
| 8079 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8080 } |
7834 Map* new_map = Map::cast(obj); | 8081 Map* new_map = Map::cast(obj); |
7835 | 8082 |
7836 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; | 8083 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; |
7837 Object* new_array = | 8084 Object* new_array; |
7838 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); | 8085 { MaybeObject* maybe_new_array = |
7839 if (new_array->IsFailure()) return new_array; | 8086 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); |
| 8087 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; |
| 8088 } |
7840 FixedArray* fast_elements = FixedArray::cast(new_array); | 8089 FixedArray* fast_elements = FixedArray::cast(new_array); |
7841 dict->CopyValuesTo(fast_elements); | 8090 dict->CopyValuesTo(fast_elements); |
7842 | 8091 |
7843 set_map(new_map); | 8092 set_map(new_map); |
7844 set_elements(fast_elements); | 8093 set_elements(fast_elements); |
7845 } else { | 8094 } else { |
7846 Object* obj = EnsureWritableFastElements(); | 8095 Object* obj; |
7847 if (obj->IsFailure()) return obj; | 8096 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 8097 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8098 } |
7848 } | 8099 } |
7849 ASSERT(HasFastElements()); | 8100 ASSERT(HasFastElements()); |
7850 | 8101 |
7851 // Collect holes at the end, undefined before that and the rest at the | 8102 // Collect holes at the end, undefined before that and the rest at the |
7852 // start, and return the number of non-hole, non-undefined values. | 8103 // start, and return the number of non-hole, non-undefined values. |
7853 | 8104 |
7854 FixedArray* elements = FixedArray::cast(this->elements()); | 8105 FixedArray* elements = FixedArray::cast(this->elements()); |
7855 uint32_t elements_length = static_cast<uint32_t>(elements->length()); | 8106 uint32_t elements_length = static_cast<uint32_t>(elements->length()); |
7856 if (limit > elements_length) { | 8107 if (limit > elements_length) { |
7857 limit = elements_length ; | 8108 limit = elements_length ; |
7858 } | 8109 } |
7859 if (limit == 0) { | 8110 if (limit == 0) { |
7860 return Smi::FromInt(0); | 8111 return Smi::FromInt(0); |
7861 } | 8112 } |
7862 | 8113 |
7863 HeapNumber* result_double = NULL; | 8114 HeapNumber* result_double = NULL; |
7864 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 8115 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
7865 // Pessimistically allocate space for return value before | 8116 // Pessimistically allocate space for return value before |
7866 // we start mutating the array. | 8117 // we start mutating the array. |
7867 Object* new_double = Heap::AllocateHeapNumber(0.0); | 8118 Object* new_double; |
7868 if (new_double->IsFailure()) return new_double; | 8119 { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0); |
| 8120 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
| 8121 } |
7869 result_double = HeapNumber::cast(new_double); | 8122 result_double = HeapNumber::cast(new_double); |
7870 } | 8123 } |
7871 | 8124 |
7872 AssertNoAllocation no_alloc; | 8125 AssertNoAllocation no_alloc; |
7873 | 8126 |
7874 // Split elements into defined, undefined and the_hole, in that order. | 8127 // Split elements into defined, undefined and the_hole, in that order. |
7875 // Only count locations for undefined and the hole, and fill them afterwards. | 8128 // Only count locations for undefined and the hole, and fill them afterwards. |
7876 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); | 8129 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); |
7877 unsigned int undefs = limit; | 8130 unsigned int undefs = limit; |
7878 unsigned int holes = limit; | 8131 unsigned int holes = limit; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7950 // converted to a number type further up in the call chain. | 8203 // converted to a number type further up in the call chain. |
7951 ASSERT(value->IsUndefined()); | 8204 ASSERT(value->IsUndefined()); |
7952 } | 8205 } |
7953 set(index, clamped_value); | 8206 set(index, clamped_value); |
7954 } | 8207 } |
7955 return Smi::FromInt(clamped_value); | 8208 return Smi::FromInt(clamped_value); |
7956 } | 8209 } |
7957 | 8210 |
7958 | 8211 |
7959 template<typename ExternalArrayClass, typename ValueType> | 8212 template<typename ExternalArrayClass, typename ValueType> |
7960 static Object* ExternalArrayIntSetter(ExternalArrayClass* receiver, | 8213 static MaybeObject* ExternalArrayIntSetter(ExternalArrayClass* receiver, |
7961 uint32_t index, | 8214 uint32_t index, |
7962 Object* value) { | 8215 Object* value) { |
7963 ValueType cast_value = 0; | 8216 ValueType cast_value = 0; |
7964 if (index < static_cast<uint32_t>(receiver->length())) { | 8217 if (index < static_cast<uint32_t>(receiver->length())) { |
7965 if (value->IsSmi()) { | 8218 if (value->IsSmi()) { |
7966 int int_value = Smi::cast(value)->value(); | 8219 int int_value = Smi::cast(value)->value(); |
7967 cast_value = static_cast<ValueType>(int_value); | 8220 cast_value = static_cast<ValueType>(int_value); |
7968 } else if (value->IsHeapNumber()) { | 8221 } else if (value->IsHeapNumber()) { |
7969 double double_value = HeapNumber::cast(value)->value(); | 8222 double double_value = HeapNumber::cast(value)->value(); |
7970 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); | 8223 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); |
7971 } else { | 8224 } else { |
7972 // Clamp undefined to zero (default). All other types have been | 8225 // Clamp undefined to zero (default). All other types have been |
7973 // converted to a number type further up in the call chain. | 8226 // converted to a number type further up in the call chain. |
7974 ASSERT(value->IsUndefined()); | 8227 ASSERT(value->IsUndefined()); |
7975 } | 8228 } |
7976 receiver->set(index, cast_value); | 8229 receiver->set(index, cast_value); |
7977 } | 8230 } |
7978 return Heap::NumberFromInt32(cast_value); | 8231 return Heap::NumberFromInt32(cast_value); |
7979 } | 8232 } |
7980 | 8233 |
7981 | 8234 |
7982 Object* ExternalByteArray::SetValue(uint32_t index, Object* value) { | 8235 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { |
7983 return ExternalArrayIntSetter<ExternalByteArray, int8_t> | 8236 return ExternalArrayIntSetter<ExternalByteArray, int8_t> |
7984 (this, index, value); | 8237 (this, index, value); |
7985 } | 8238 } |
7986 | 8239 |
7987 | 8240 |
7988 Object* ExternalUnsignedByteArray::SetValue(uint32_t index, Object* value) { | 8241 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, |
| 8242 Object* value) { |
7989 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> | 8243 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> |
7990 (this, index, value); | 8244 (this, index, value); |
7991 } | 8245 } |
7992 | 8246 |
7993 | 8247 |
7994 Object* ExternalShortArray::SetValue(uint32_t index, Object* value) { | 8248 MaybeObject* ExternalShortArray::SetValue(uint32_t index, |
| 8249 Object* value) { |
7995 return ExternalArrayIntSetter<ExternalShortArray, int16_t> | 8250 return ExternalArrayIntSetter<ExternalShortArray, int16_t> |
7996 (this, index, value); | 8251 (this, index, value); |
7997 } | 8252 } |
7998 | 8253 |
7999 | 8254 |
8000 Object* ExternalUnsignedShortArray::SetValue(uint32_t index, Object* value) { | 8255 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, |
| 8256 Object* value) { |
8001 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> | 8257 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> |
8002 (this, index, value); | 8258 (this, index, value); |
8003 } | 8259 } |
8004 | 8260 |
8005 | 8261 |
8006 Object* ExternalIntArray::SetValue(uint32_t index, Object* value) { | 8262 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { |
8007 return ExternalArrayIntSetter<ExternalIntArray, int32_t> | 8263 return ExternalArrayIntSetter<ExternalIntArray, int32_t> |
8008 (this, index, value); | 8264 (this, index, value); |
8009 } | 8265 } |
8010 | 8266 |
8011 | 8267 |
8012 Object* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { | 8268 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { |
8013 uint32_t cast_value = 0; | 8269 uint32_t cast_value = 0; |
8014 if (index < static_cast<uint32_t>(length())) { | 8270 if (index < static_cast<uint32_t>(length())) { |
8015 if (value->IsSmi()) { | 8271 if (value->IsSmi()) { |
8016 int int_value = Smi::cast(value)->value(); | 8272 int int_value = Smi::cast(value)->value(); |
8017 cast_value = static_cast<uint32_t>(int_value); | 8273 cast_value = static_cast<uint32_t>(int_value); |
8018 } else if (value->IsHeapNumber()) { | 8274 } else if (value->IsHeapNumber()) { |
8019 double double_value = HeapNumber::cast(value)->value(); | 8275 double double_value = HeapNumber::cast(value)->value(); |
8020 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 8276 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
8021 } else { | 8277 } else { |
8022 // Clamp undefined to zero (default). All other types have been | 8278 // Clamp undefined to zero (default). All other types have been |
8023 // converted to a number type further up in the call chain. | 8279 // converted to a number type further up in the call chain. |
8024 ASSERT(value->IsUndefined()); | 8280 ASSERT(value->IsUndefined()); |
8025 } | 8281 } |
8026 set(index, cast_value); | 8282 set(index, cast_value); |
8027 } | 8283 } |
8028 return Heap::NumberFromUint32(cast_value); | 8284 return Heap::NumberFromUint32(cast_value); |
8029 } | 8285 } |
8030 | 8286 |
8031 | 8287 |
8032 Object* ExternalFloatArray::SetValue(uint32_t index, Object* value) { | 8288 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { |
8033 float cast_value = 0; | 8289 float cast_value = 0; |
8034 if (index < static_cast<uint32_t>(length())) { | 8290 if (index < static_cast<uint32_t>(length())) { |
8035 if (value->IsSmi()) { | 8291 if (value->IsSmi()) { |
8036 int int_value = Smi::cast(value)->value(); | 8292 int int_value = Smi::cast(value)->value(); |
8037 cast_value = static_cast<float>(int_value); | 8293 cast_value = static_cast<float>(int_value); |
8038 } else if (value->IsHeapNumber()) { | 8294 } else if (value->IsHeapNumber()) { |
8039 double double_value = HeapNumber::cast(value)->value(); | 8295 double double_value = HeapNumber::cast(value)->value(); |
8040 cast_value = static_cast<float>(double_value); | 8296 cast_value = static_cast<float>(double_value); |
8041 } else { | 8297 } else { |
8042 // Clamp undefined to zero (default). All other types have been | 8298 // Clamp undefined to zero (default). All other types have been |
8043 // converted to a number type further up in the call chain. | 8299 // converted to a number type further up in the call chain. |
8044 ASSERT(value->IsUndefined()); | 8300 ASSERT(value->IsUndefined()); |
8045 } | 8301 } |
8046 set(index, cast_value); | 8302 set(index, cast_value); |
8047 } | 8303 } |
8048 return Heap::AllocateHeapNumber(cast_value); | 8304 return Heap::AllocateHeapNumber(cast_value); |
8049 } | 8305 } |
8050 | 8306 |
8051 | 8307 |
8052 Object* GlobalObject::GetPropertyCell(LookupResult* result) { | 8308 Object* GlobalObject::GetPropertyCell(LookupResult* result) { |
8053 ASSERT(!HasFastProperties()); | 8309 ASSERT(!HasFastProperties()); |
8054 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 8310 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
8055 ASSERT(value->IsJSGlobalPropertyCell()); | 8311 ASSERT(value->IsJSGlobalPropertyCell()); |
8056 return value; | 8312 return value; |
8057 } | 8313 } |
8058 | 8314 |
8059 | 8315 |
8060 Object* GlobalObject::EnsurePropertyCell(String* name) { | 8316 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { |
8061 ASSERT(!HasFastProperties()); | 8317 ASSERT(!HasFastProperties()); |
8062 int entry = property_dictionary()->FindEntry(name); | 8318 int entry = property_dictionary()->FindEntry(name); |
8063 if (entry == StringDictionary::kNotFound) { | 8319 if (entry == StringDictionary::kNotFound) { |
8064 Object* cell = Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value()); | 8320 Object* cell; |
8065 if (cell->IsFailure()) return cell; | 8321 { MaybeObject* maybe_cell = |
| 8322 Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value()); |
| 8323 if (!maybe_cell->ToObject(&cell)) return maybe_cell; |
| 8324 } |
8066 PropertyDetails details(NONE, NORMAL); | 8325 PropertyDetails details(NONE, NORMAL); |
8067 details = details.AsDeleted(); | 8326 details = details.AsDeleted(); |
8068 Object* dictionary = property_dictionary()->Add(name, cell, details); | 8327 Object* dictionary; |
8069 if (dictionary->IsFailure()) return dictionary; | 8328 { MaybeObject* maybe_dictionary = |
| 8329 property_dictionary()->Add(name, cell, details); |
| 8330 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary; |
| 8331 } |
8070 set_properties(StringDictionary::cast(dictionary)); | 8332 set_properties(StringDictionary::cast(dictionary)); |
8071 return cell; | 8333 return cell; |
8072 } else { | 8334 } else { |
8073 Object* value = property_dictionary()->ValueAt(entry); | 8335 Object* value = property_dictionary()->ValueAt(entry); |
8074 ASSERT(value->IsJSGlobalPropertyCell()); | 8336 ASSERT(value->IsJSGlobalPropertyCell()); |
8075 return value; | 8337 return value; |
8076 } | 8338 } |
8077 } | 8339 } |
8078 | 8340 |
8079 | 8341 |
8080 Object* SymbolTable::LookupString(String* string, Object** s) { | 8342 MaybeObject* SymbolTable::LookupString(String* string, Object** s) { |
8081 SymbolKey key(string); | 8343 SymbolKey key(string); |
8082 return LookupKey(&key, s); | 8344 return LookupKey(&key, s); |
8083 } | 8345 } |
8084 | 8346 |
8085 | 8347 |
8086 // This class is used for looking up two character strings in the symbol table. | 8348 // This class is used for looking up two character strings in the symbol table. |
8087 // If we don't have a hit we don't want to waste much time so we unroll the | 8349 // If we don't have a hit we don't want to waste much time so we unroll the |
8088 // string hash calculation loop here for speed. Doesn't work if the two | 8350 // string hash calculation loop here for speed. Doesn't work if the two |
8089 // characters form a decimal integer, since such strings have a different hash | 8351 // characters form a decimal integer, since such strings have a different hash |
8090 // algorithm. | 8352 // algorithm. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8167 return false; | 8429 return false; |
8168 } else { | 8430 } else { |
8169 String* result = String::cast(KeyAt(entry)); | 8431 String* result = String::cast(KeyAt(entry)); |
8170 ASSERT(StringShape(result).IsSymbol()); | 8432 ASSERT(StringShape(result).IsSymbol()); |
8171 *symbol = result; | 8433 *symbol = result; |
8172 return true; | 8434 return true; |
8173 } | 8435 } |
8174 } | 8436 } |
8175 | 8437 |
8176 | 8438 |
8177 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 8439 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { |
8178 Utf8SymbolKey key(str); | 8440 Utf8SymbolKey key(str); |
8179 return LookupKey(&key, s); | 8441 return LookupKey(&key, s); |
8180 } | 8442 } |
8181 | 8443 |
8182 | 8444 |
8183 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 8445 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
8184 int entry = FindEntry(key); | 8446 int entry = FindEntry(key); |
8185 | 8447 |
8186 // Symbol already in table. | 8448 // Symbol already in table. |
8187 if (entry != kNotFound) { | 8449 if (entry != kNotFound) { |
8188 *s = KeyAt(entry); | 8450 *s = KeyAt(entry); |
8189 return this; | 8451 return this; |
8190 } | 8452 } |
8191 | 8453 |
8192 // Adding new symbol. Grow table if needed. | 8454 // Adding new symbol. Grow table if needed. |
8193 Object* obj = EnsureCapacity(1, key); | 8455 Object* obj; |
8194 if (obj->IsFailure()) return obj; | 8456 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 8457 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8458 } |
8195 | 8459 |
8196 // Create symbol object. | 8460 // Create symbol object. |
8197 Object* symbol = key->AsObject(); | 8461 Object* symbol; |
8198 if (symbol->IsFailure()) return symbol; | 8462 { MaybeObject* maybe_symbol = key->AsObject(); |
| 8463 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; |
| 8464 } |
8199 | 8465 |
8200 // If the symbol table grew as part of EnsureCapacity, obj is not | 8466 // If the symbol table grew as part of EnsureCapacity, obj is not |
8201 // the current symbol table and therefore we cannot use | 8467 // the current symbol table and therefore we cannot use |
8202 // SymbolTable::cast here. | 8468 // SymbolTable::cast here. |
8203 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); | 8469 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); |
8204 | 8470 |
8205 // Add the new symbol and return it along with the symbol table. | 8471 // Add the new symbol and return it along with the symbol table. |
8206 entry = table->FindInsertionEntry(key->Hash()); | 8472 entry = table->FindInsertionEntry(key->Hash()); |
8207 table->set(EntryToIndex(entry), symbol); | 8473 table->set(EntryToIndex(entry), symbol); |
8208 table->ElementAdded(); | 8474 table->ElementAdded(); |
(...skipping 20 matching lines...) Expand all Loading... |
8229 | 8495 |
8230 Object* CompilationCacheTable::LookupRegExp(String* src, | 8496 Object* CompilationCacheTable::LookupRegExp(String* src, |
8231 JSRegExp::Flags flags) { | 8497 JSRegExp::Flags flags) { |
8232 RegExpKey key(src, flags); | 8498 RegExpKey key(src, flags); |
8233 int entry = FindEntry(&key); | 8499 int entry = FindEntry(&key); |
8234 if (entry == kNotFound) return Heap::undefined_value(); | 8500 if (entry == kNotFound) return Heap::undefined_value(); |
8235 return get(EntryToIndex(entry) + 1); | 8501 return get(EntryToIndex(entry) + 1); |
8236 } | 8502 } |
8237 | 8503 |
8238 | 8504 |
8239 Object* CompilationCacheTable::Put(String* src, Object* value) { | 8505 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { |
8240 StringKey key(src); | 8506 StringKey key(src); |
8241 Object* obj = EnsureCapacity(1, &key); | 8507 Object* obj; |
8242 if (obj->IsFailure()) return obj; | 8508 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 8509 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8510 } |
8243 | 8511 |
8244 CompilationCacheTable* cache = | 8512 CompilationCacheTable* cache = |
8245 reinterpret_cast<CompilationCacheTable*>(obj); | 8513 reinterpret_cast<CompilationCacheTable*>(obj); |
8246 int entry = cache->FindInsertionEntry(key.Hash()); | 8514 int entry = cache->FindInsertionEntry(key.Hash()); |
8247 cache->set(EntryToIndex(entry), src); | 8515 cache->set(EntryToIndex(entry), src); |
8248 cache->set(EntryToIndex(entry) + 1, value); | 8516 cache->set(EntryToIndex(entry) + 1, value); |
8249 cache->ElementAdded(); | 8517 cache->ElementAdded(); |
8250 return cache; | 8518 return cache; |
8251 } | 8519 } |
8252 | 8520 |
8253 | 8521 |
8254 Object* CompilationCacheTable::PutEval(String* src, | 8522 MaybeObject* CompilationCacheTable::PutEval(String* src, |
8255 Context* context, | 8523 Context* context, |
8256 Object* value) { | 8524 Object* value) { |
8257 StringSharedKey key(src, context->closure()->shared()); | 8525 StringSharedKey key(src, context->closure()->shared()); |
8258 Object* obj = EnsureCapacity(1, &key); | 8526 Object* obj; |
8259 if (obj->IsFailure()) return obj; | 8527 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 8528 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8529 } |
8260 | 8530 |
8261 CompilationCacheTable* cache = | 8531 CompilationCacheTable* cache = |
8262 reinterpret_cast<CompilationCacheTable*>(obj); | 8532 reinterpret_cast<CompilationCacheTable*>(obj); |
8263 int entry = cache->FindInsertionEntry(key.Hash()); | 8533 int entry = cache->FindInsertionEntry(key.Hash()); |
8264 | 8534 |
8265 Object* k = key.AsObject(); | 8535 Object* k; |
8266 if (k->IsFailure()) return k; | 8536 { MaybeObject* maybe_k = key.AsObject(); |
| 8537 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 8538 } |
8267 | 8539 |
8268 cache->set(EntryToIndex(entry), k); | 8540 cache->set(EntryToIndex(entry), k); |
8269 cache->set(EntryToIndex(entry) + 1, value); | 8541 cache->set(EntryToIndex(entry) + 1, value); |
8270 cache->ElementAdded(); | 8542 cache->ElementAdded(); |
8271 return cache; | 8543 return cache; |
8272 } | 8544 } |
8273 | 8545 |
8274 | 8546 |
8275 Object* CompilationCacheTable::PutRegExp(String* src, | 8547 MaybeObject* CompilationCacheTable::PutRegExp(String* src, |
8276 JSRegExp::Flags flags, | 8548 JSRegExp::Flags flags, |
8277 FixedArray* value) { | 8549 FixedArray* value) { |
8278 RegExpKey key(src, flags); | 8550 RegExpKey key(src, flags); |
8279 Object* obj = EnsureCapacity(1, &key); | 8551 Object* obj; |
8280 if (obj->IsFailure()) return obj; | 8552 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 8553 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8554 } |
8281 | 8555 |
8282 CompilationCacheTable* cache = | 8556 CompilationCacheTable* cache = |
8283 reinterpret_cast<CompilationCacheTable*>(obj); | 8557 reinterpret_cast<CompilationCacheTable*>(obj); |
8284 int entry = cache->FindInsertionEntry(key.Hash()); | 8558 int entry = cache->FindInsertionEntry(key.Hash()); |
8285 // We store the value in the key slot, and compare the search key | 8559 // We store the value in the key slot, and compare the search key |
8286 // to the stored value with a custon IsMatch function during lookups. | 8560 // to the stored value with a custon IsMatch function during lookups. |
8287 cache->set(EntryToIndex(entry), value); | 8561 cache->set(EntryToIndex(entry), value); |
8288 cache->set(EntryToIndex(entry) + 1, value); | 8562 cache->set(EntryToIndex(entry) + 1, value); |
8289 cache->ElementAdded(); | 8563 cache->ElementAdded(); |
8290 return cache; | 8564 return cache; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8326 | 8600 |
8327 | 8601 |
8328 Object* MapCache::Lookup(FixedArray* array) { | 8602 Object* MapCache::Lookup(FixedArray* array) { |
8329 SymbolsKey key(array); | 8603 SymbolsKey key(array); |
8330 int entry = FindEntry(&key); | 8604 int entry = FindEntry(&key); |
8331 if (entry == kNotFound) return Heap::undefined_value(); | 8605 if (entry == kNotFound) return Heap::undefined_value(); |
8332 return get(EntryToIndex(entry) + 1); | 8606 return get(EntryToIndex(entry) + 1); |
8333 } | 8607 } |
8334 | 8608 |
8335 | 8609 |
8336 Object* MapCache::Put(FixedArray* array, Map* value) { | 8610 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { |
8337 SymbolsKey key(array); | 8611 SymbolsKey key(array); |
8338 Object* obj = EnsureCapacity(1, &key); | 8612 Object* obj; |
8339 if (obj->IsFailure()) return obj; | 8613 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 8614 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8615 } |
8340 | 8616 |
8341 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 8617 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
8342 int entry = cache->FindInsertionEntry(key.Hash()); | 8618 int entry = cache->FindInsertionEntry(key.Hash()); |
8343 cache->set(EntryToIndex(entry), array); | 8619 cache->set(EntryToIndex(entry), array); |
8344 cache->set(EntryToIndex(entry) + 1, value); | 8620 cache->set(EntryToIndex(entry) + 1, value); |
8345 cache->ElementAdded(); | 8621 cache->ElementAdded(); |
8346 return cache; | 8622 return cache; |
8347 } | 8623 } |
8348 | 8624 |
8349 | 8625 |
8350 template<typename Shape, typename Key> | 8626 template<typename Shape, typename Key> |
8351 Object* Dictionary<Shape, Key>::Allocate(int at_least_space_for) { | 8627 MaybeObject* Dictionary<Shape, Key>::Allocate(int at_least_space_for) { |
8352 Object* obj = HashTable<Shape, Key>::Allocate(at_least_space_for); | 8628 Object* obj; |
| 8629 { MaybeObject* maybe_obj = |
| 8630 HashTable<Shape, Key>::Allocate(at_least_space_for); |
| 8631 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8632 } |
8353 // Initialize the next enumeration index. | 8633 // Initialize the next enumeration index. |
8354 if (!obj->IsFailure()) { | 8634 Dictionary<Shape, Key>::cast(obj)-> |
8355 Dictionary<Shape, Key>::cast(obj)-> | 8635 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
8356 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | |
8357 } | |
8358 return obj; | 8636 return obj; |
8359 } | 8637 } |
8360 | 8638 |
8361 | 8639 |
8362 template<typename Shape, typename Key> | 8640 template<typename Shape, typename Key> |
8363 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 8641 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
8364 int length = HashTable<Shape, Key>::NumberOfElements(); | 8642 int length = HashTable<Shape, Key>::NumberOfElements(); |
8365 | 8643 |
8366 // Allocate and initialize iteration order array. | 8644 // Allocate and initialize iteration order array. |
8367 Object* obj = Heap::AllocateFixedArray(length); | 8645 Object* obj; |
8368 if (obj->IsFailure()) return obj; | 8646 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length); |
| 8647 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8648 } |
8369 FixedArray* iteration_order = FixedArray::cast(obj); | 8649 FixedArray* iteration_order = FixedArray::cast(obj); |
8370 for (int i = 0; i < length; i++) { | 8650 for (int i = 0; i < length; i++) { |
8371 iteration_order->set(i, Smi::FromInt(i)); | 8651 iteration_order->set(i, Smi::FromInt(i)); |
8372 } | 8652 } |
8373 | 8653 |
8374 // Allocate array with enumeration order. | 8654 // Allocate array with enumeration order. |
8375 obj = Heap::AllocateFixedArray(length); | 8655 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length); |
8376 if (obj->IsFailure()) return obj; | 8656 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8657 } |
8377 FixedArray* enumeration_order = FixedArray::cast(obj); | 8658 FixedArray* enumeration_order = FixedArray::cast(obj); |
8378 | 8659 |
8379 // Fill the enumeration order array with property details. | 8660 // Fill the enumeration order array with property details. |
8380 int capacity = HashTable<Shape, Key>::Capacity(); | 8661 int capacity = HashTable<Shape, Key>::Capacity(); |
8381 int pos = 0; | 8662 int pos = 0; |
8382 for (int i = 0; i < capacity; i++) { | 8663 for (int i = 0; i < capacity; i++) { |
8383 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 8664 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
8384 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); | 8665 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); |
8385 } | 8666 } |
8386 } | 8667 } |
(...skipping 20 matching lines...) Expand all Loading... |
8407 DetailsAtPut(i, new_details); | 8688 DetailsAtPut(i, new_details); |
8408 } | 8689 } |
8409 } | 8690 } |
8410 | 8691 |
8411 // Set the next enumeration index. | 8692 // Set the next enumeration index. |
8412 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 8693 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
8413 return this; | 8694 return this; |
8414 } | 8695 } |
8415 | 8696 |
8416 template<typename Shape, typename Key> | 8697 template<typename Shape, typename Key> |
8417 Object* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { | 8698 MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { |
8418 // Check whether there are enough enumeration indices to add n elements. | 8699 // Check whether there are enough enumeration indices to add n elements. |
8419 if (Shape::kIsEnumerable && | 8700 if (Shape::kIsEnumerable && |
8420 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 8701 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
8421 // If not, we generate new indices for the properties. | 8702 // If not, we generate new indices for the properties. |
8422 Object* result = GenerateNewEnumerationIndices(); | 8703 Object* result; |
8423 if (result->IsFailure()) return result; | 8704 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 8705 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 8706 } |
8424 } | 8707 } |
8425 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 8708 return HashTable<Shape, Key>::EnsureCapacity(n, key); |
8426 } | 8709 } |
8427 | 8710 |
8428 | 8711 |
8429 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { | 8712 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { |
8430 // Do nothing if the interval [from, to) is empty. | 8713 // Do nothing if the interval [from, to) is empty. |
8431 if (from >= to) return; | 8714 if (from >= to) return; |
8432 | 8715 |
8433 int removed_entries = 0; | 8716 int removed_entries = 0; |
(...skipping 23 matching lines...) Expand all Loading... |
8457 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { | 8740 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { |
8458 return Heap::false_value(); | 8741 return Heap::false_value(); |
8459 } | 8742 } |
8460 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); | 8743 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); |
8461 HashTable<Shape, Key>::ElementRemoved(); | 8744 HashTable<Shape, Key>::ElementRemoved(); |
8462 return Heap::true_value(); | 8745 return Heap::true_value(); |
8463 } | 8746 } |
8464 | 8747 |
8465 | 8748 |
8466 template<typename Shape, typename Key> | 8749 template<typename Shape, typename Key> |
8467 Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | 8750 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { |
8468 int entry = this->FindEntry(key); | 8751 int entry = this->FindEntry(key); |
8469 | 8752 |
8470 // If the entry is present set the value; | 8753 // If the entry is present set the value; |
8471 if (entry != Dictionary<Shape, Key>::kNotFound) { | 8754 if (entry != Dictionary<Shape, Key>::kNotFound) { |
8472 ValueAtPut(entry, value); | 8755 ValueAtPut(entry, value); |
8473 return this; | 8756 return this; |
8474 } | 8757 } |
8475 | 8758 |
8476 // Check whether the dictionary should be extended. | 8759 // Check whether the dictionary should be extended. |
8477 Object* obj = EnsureCapacity(1, key); | 8760 Object* obj; |
8478 if (obj->IsFailure()) return obj; | 8761 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 8762 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8763 } |
8479 | 8764 |
8480 Object* k = Shape::AsObject(key); | 8765 Object* k; |
8481 if (k->IsFailure()) return k; | 8766 { MaybeObject* maybe_k = Shape::AsObject(key); |
| 8767 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 8768 } |
8482 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 8769 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
8483 return Dictionary<Shape, Key>::cast(obj)-> | 8770 return Dictionary<Shape, Key>::cast(obj)-> |
8484 AddEntry(key, value, details, Shape::Hash(key)); | 8771 AddEntry(key, value, details, Shape::Hash(key)); |
8485 } | 8772 } |
8486 | 8773 |
8487 | 8774 |
8488 template<typename Shape, typename Key> | 8775 template<typename Shape, typename Key> |
8489 Object* Dictionary<Shape, Key>::Add(Key key, | 8776 MaybeObject* Dictionary<Shape, Key>::Add(Key key, |
8490 Object* value, | 8777 Object* value, |
8491 PropertyDetails details) { | 8778 PropertyDetails details) { |
8492 // Valdate key is absent. | 8779 // Valdate key is absent. |
8493 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 8780 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); |
8494 // Check whether the dictionary should be extended. | 8781 // Check whether the dictionary should be extended. |
8495 Object* obj = EnsureCapacity(1, key); | 8782 Object* obj; |
8496 if (obj->IsFailure()) return obj; | 8783 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 8784 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8785 } |
8497 return Dictionary<Shape, Key>::cast(obj)-> | 8786 return Dictionary<Shape, Key>::cast(obj)-> |
8498 AddEntry(key, value, details, Shape::Hash(key)); | 8787 AddEntry(key, value, details, Shape::Hash(key)); |
8499 } | 8788 } |
8500 | 8789 |
8501 | 8790 |
8502 // Add a key, value pair to the dictionary. | 8791 // Add a key, value pair to the dictionary. |
8503 template<typename Shape, typename Key> | 8792 template<typename Shape, typename Key> |
8504 Object* Dictionary<Shape, Key>::AddEntry(Key key, | 8793 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, |
8505 Object* value, | 8794 Object* value, |
8506 PropertyDetails details, | 8795 PropertyDetails details, |
8507 uint32_t hash) { | 8796 uint32_t hash) { |
8508 // Compute the key object. | 8797 // Compute the key object. |
8509 Object* k = Shape::AsObject(key); | 8798 Object* k; |
8510 if (k->IsFailure()) return k; | 8799 { MaybeObject* maybe_k = Shape::AsObject(key); |
| 8800 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 8801 } |
8511 | 8802 |
8512 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); | 8803 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); |
8513 // Insert element at empty or deleted entry | 8804 // Insert element at empty or deleted entry |
8514 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { | 8805 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { |
8515 // Assign an enumeration index to the property and update | 8806 // Assign an enumeration index to the property and update |
8516 // SetNextEnumerationIndex. | 8807 // SetNextEnumerationIndex. |
8517 int index = NextEnumerationIndex(); | 8808 int index = NextEnumerationIndex(); |
8518 details = PropertyDetails(details.attributes(), details.type(), index); | 8809 details = PropertyDetails(details.attributes(), details.type(), index); |
8519 SetNextEnumerationIndex(index + 1); | 8810 SetNextEnumerationIndex(index + 1); |
8520 } | 8811 } |
(...skipping 17 matching lines...) Expand all Loading... |
8538 } | 8829 } |
8539 // Update max key value. | 8830 // Update max key value. |
8540 Object* max_index_object = get(kMaxNumberKeyIndex); | 8831 Object* max_index_object = get(kMaxNumberKeyIndex); |
8541 if (!max_index_object->IsSmi() || max_number_key() < key) { | 8832 if (!max_index_object->IsSmi() || max_number_key() < key) { |
8542 FixedArray::set(kMaxNumberKeyIndex, | 8833 FixedArray::set(kMaxNumberKeyIndex, |
8543 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 8834 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
8544 } | 8835 } |
8545 } | 8836 } |
8546 | 8837 |
8547 | 8838 |
8548 Object* NumberDictionary::AddNumberEntry(uint32_t key, | 8839 MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key, |
8549 Object* value, | 8840 Object* value, |
8550 PropertyDetails details) { | 8841 PropertyDetails details) { |
8551 UpdateMaxNumberKey(key); | 8842 UpdateMaxNumberKey(key); |
8552 SLOW_ASSERT(this->FindEntry(key) == kNotFound); | 8843 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
8553 return Add(key, value, details); | 8844 return Add(key, value, details); |
8554 } | 8845 } |
8555 | 8846 |
8556 | 8847 |
8557 Object* NumberDictionary::AtNumberPut(uint32_t key, Object* value) { | 8848 MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) { |
8558 UpdateMaxNumberKey(key); | 8849 UpdateMaxNumberKey(key); |
8559 return AtPut(key, value); | 8850 return AtPut(key, value); |
8560 } | 8851 } |
8561 | 8852 |
8562 | 8853 |
8563 Object* NumberDictionary::Set(uint32_t key, | 8854 MaybeObject* NumberDictionary::Set(uint32_t key, |
8564 Object* value, | 8855 Object* value, |
8565 PropertyDetails details) { | 8856 PropertyDetails details) { |
8566 int entry = FindEntry(key); | 8857 int entry = FindEntry(key); |
8567 if (entry == kNotFound) return AddNumberEntry(key, value, details); | 8858 if (entry == kNotFound) return AddNumberEntry(key, value, details); |
8568 // Preserve enumeration index. | 8859 // Preserve enumeration index. |
8569 details = PropertyDetails(details.attributes(), | 8860 details = PropertyDetails(details.attributes(), |
8570 details.type(), | 8861 details.type(), |
8571 DetailsAt(entry).index()); | 8862 DetailsAt(entry).index()); |
8572 Object* object_key = NumberDictionaryShape::AsObject(key); | 8863 MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key); |
8573 if (object_key->IsFailure()) return object_key; | 8864 Object* object_key; |
| 8865 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
8574 SetEntry(entry, object_key, value, details); | 8866 SetEntry(entry, object_key, value, details); |
8575 return this; | 8867 return this; |
8576 } | 8868 } |
8577 | 8869 |
8578 | 8870 |
8579 | 8871 |
8580 template<typename Shape, typename Key> | 8872 template<typename Shape, typename Key> |
8581 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 8873 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
8582 PropertyAttributes filter) { | 8874 PropertyAttributes filter) { |
8583 int capacity = HashTable<Shape, Key>::Capacity(); | 8875 int capacity = HashTable<Shape, Key>::Capacity(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8671 if (e->IsJSGlobalPropertyCell()) { | 8963 if (e->IsJSGlobalPropertyCell()) { |
8672 e = JSGlobalPropertyCell::cast(e)->value(); | 8964 e = JSGlobalPropertyCell::cast(e)->value(); |
8673 } | 8965 } |
8674 if (e == value) return k; | 8966 if (e == value) return k; |
8675 } | 8967 } |
8676 } | 8968 } |
8677 return Heap::undefined_value(); | 8969 return Heap::undefined_value(); |
8678 } | 8970 } |
8679 | 8971 |
8680 | 8972 |
8681 Object* StringDictionary::TransformPropertiesToFastFor( | 8973 MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
8682 JSObject* obj, int unused_property_fields) { | 8974 JSObject* obj, int unused_property_fields) { |
8683 // Make sure we preserve dictionary representation if there are too many | 8975 // Make sure we preserve dictionary representation if there are too many |
8684 // descriptors. | 8976 // descriptors. |
8685 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 8977 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
8686 | 8978 |
8687 // Figure out if it is necessary to generate new enumeration indices. | 8979 // Figure out if it is necessary to generate new enumeration indices. |
8688 int max_enumeration_index = | 8980 int max_enumeration_index = |
8689 NextEnumerationIndex() + | 8981 NextEnumerationIndex() + |
8690 (DescriptorArray::kMaxNumberOfDescriptors - | 8982 (DescriptorArray::kMaxNumberOfDescriptors - |
8691 NumberOfElements()); | 8983 NumberOfElements()); |
8692 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { | 8984 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { |
8693 Object* result = GenerateNewEnumerationIndices(); | 8985 Object* result; |
8694 if (result->IsFailure()) return result; | 8986 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 8987 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 8988 } |
8695 } | 8989 } |
8696 | 8990 |
8697 int instance_descriptor_length = 0; | 8991 int instance_descriptor_length = 0; |
8698 int number_of_fields = 0; | 8992 int number_of_fields = 0; |
8699 | 8993 |
8700 // Compute the length of the instance descriptor. | 8994 // Compute the length of the instance descriptor. |
8701 int capacity = Capacity(); | 8995 int capacity = Capacity(); |
8702 for (int i = 0; i < capacity; i++) { | 8996 for (int i = 0; i < capacity; i++) { |
8703 Object* k = KeyAt(i); | 8997 Object* k = KeyAt(i); |
8704 if (IsKey(k)) { | 8998 if (IsKey(k)) { |
8705 Object* value = ValueAt(i); | 8999 Object* value = ValueAt(i); |
8706 PropertyType type = DetailsAt(i).type(); | 9000 PropertyType type = DetailsAt(i).type(); |
8707 ASSERT(type != FIELD); | 9001 ASSERT(type != FIELD); |
8708 instance_descriptor_length++; | 9002 instance_descriptor_length++; |
8709 if (type == NORMAL && | 9003 if (type == NORMAL && |
8710 (!value->IsJSFunction() || Heap::InNewSpace(value))) { | 9004 (!value->IsJSFunction() || Heap::InNewSpace(value))) { |
8711 number_of_fields += 1; | 9005 number_of_fields += 1; |
8712 } | 9006 } |
8713 } | 9007 } |
8714 } | 9008 } |
8715 | 9009 |
8716 // Allocate the instance descriptor. | 9010 // Allocate the instance descriptor. |
8717 Object* descriptors_unchecked = | 9011 Object* descriptors_unchecked; |
8718 DescriptorArray::Allocate(instance_descriptor_length); | 9012 { MaybeObject* maybe_descriptors_unchecked = |
8719 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; | 9013 DescriptorArray::Allocate(instance_descriptor_length); |
| 9014 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { |
| 9015 return maybe_descriptors_unchecked; |
| 9016 } |
| 9017 } |
8720 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); | 9018 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); |
8721 | 9019 |
8722 int inobject_props = obj->map()->inobject_properties(); | 9020 int inobject_props = obj->map()->inobject_properties(); |
8723 int number_of_allocated_fields = | 9021 int number_of_allocated_fields = |
8724 number_of_fields + unused_property_fields - inobject_props; | 9022 number_of_fields + unused_property_fields - inobject_props; |
8725 if (number_of_allocated_fields < 0) { | 9023 if (number_of_allocated_fields < 0) { |
8726 // There is enough inobject space for all fields (including unused). | 9024 // There is enough inobject space for all fields (including unused). |
8727 number_of_allocated_fields = 0; | 9025 number_of_allocated_fields = 0; |
8728 unused_property_fields = inobject_props - number_of_fields; | 9026 unused_property_fields = inobject_props - number_of_fields; |
8729 } | 9027 } |
8730 | 9028 |
8731 // Allocate the fixed array for the fields. | 9029 // Allocate the fixed array for the fields. |
8732 Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields); | 9030 Object* fields; |
8733 if (fields->IsFailure()) return fields; | 9031 { MaybeObject* maybe_fields = |
| 9032 Heap::AllocateFixedArray(number_of_allocated_fields); |
| 9033 if (!maybe_fields->ToObject(&fields)) return maybe_fields; |
| 9034 } |
8734 | 9035 |
8735 // Fill in the instance descriptor and the fields. | 9036 // Fill in the instance descriptor and the fields. |
8736 int next_descriptor = 0; | 9037 int next_descriptor = 0; |
8737 int current_offset = 0; | 9038 int current_offset = 0; |
8738 for (int i = 0; i < capacity; i++) { | 9039 for (int i = 0; i < capacity; i++) { |
8739 Object* k = KeyAt(i); | 9040 Object* k = KeyAt(i); |
8740 if (IsKey(k)) { | 9041 if (IsKey(k)) { |
8741 Object* value = ValueAt(i); | 9042 Object* value = ValueAt(i); |
8742 // Ensure the key is a symbol before writing into the instance descriptor. | 9043 // Ensure the key is a symbol before writing into the instance descriptor. |
8743 Object* key = Heap::LookupSymbol(String::cast(k)); | 9044 Object* key; |
8744 if (key->IsFailure()) return key; | 9045 { MaybeObject* maybe_key = Heap::LookupSymbol(String::cast(k)); |
| 9046 if (!maybe_key->ToObject(&key)) return maybe_key; |
| 9047 } |
8745 PropertyDetails details = DetailsAt(i); | 9048 PropertyDetails details = DetailsAt(i); |
8746 PropertyType type = details.type(); | 9049 PropertyType type = details.type(); |
8747 | 9050 |
8748 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { | 9051 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { |
8749 ConstantFunctionDescriptor d(String::cast(key), | 9052 ConstantFunctionDescriptor d(String::cast(key), |
8750 JSFunction::cast(value), | 9053 JSFunction::cast(value), |
8751 details.attributes(), | 9054 details.attributes(), |
8752 details.index()); | 9055 details.index()); |
8753 descriptors->Set(next_descriptor++, &d); | 9056 descriptors->Set(next_descriptor++, &d); |
8754 } else if (type == NORMAL) { | 9057 } else if (type == NORMAL) { |
(...skipping 18 matching lines...) Expand all Loading... |
8773 descriptors->Set(next_descriptor++, &d); | 9076 descriptors->Set(next_descriptor++, &d); |
8774 } else { | 9077 } else { |
8775 UNREACHABLE(); | 9078 UNREACHABLE(); |
8776 } | 9079 } |
8777 } | 9080 } |
8778 } | 9081 } |
8779 ASSERT(current_offset == number_of_fields); | 9082 ASSERT(current_offset == number_of_fields); |
8780 | 9083 |
8781 descriptors->Sort(); | 9084 descriptors->Sort(); |
8782 // Allocate new map. | 9085 // Allocate new map. |
8783 Object* new_map = obj->map()->CopyDropDescriptors(); | 9086 Object* new_map; |
8784 if (new_map->IsFailure()) return new_map; | 9087 { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); |
| 9088 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 9089 } |
8785 | 9090 |
8786 // Transform the object. | 9091 // Transform the object. |
8787 obj->set_map(Map::cast(new_map)); | 9092 obj->set_map(Map::cast(new_map)); |
8788 obj->map()->set_instance_descriptors(descriptors); | 9093 obj->map()->set_instance_descriptors(descriptors); |
8789 obj->map()->set_unused_property_fields(unused_property_fields); | 9094 obj->map()->set_unused_property_fields(unused_property_fields); |
8790 | 9095 |
8791 obj->set_properties(FixedArray::cast(fields)); | 9096 obj->set_properties(FixedArray::cast(fields)); |
8792 ASSERT(obj->IsJSObject()); | 9097 ASSERT(obj->IsJSObject()); |
8793 | 9098 |
8794 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); | 9099 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9040 if (break_point_objects()->IsUndefined()) return 0; | 9345 if (break_point_objects()->IsUndefined()) return 0; |
9041 // Single beak point. | 9346 // Single beak point. |
9042 if (!break_point_objects()->IsFixedArray()) return 1; | 9347 if (!break_point_objects()->IsFixedArray()) return 1; |
9043 // Multiple break points. | 9348 // Multiple break points. |
9044 return FixedArray::cast(break_point_objects())->length(); | 9349 return FixedArray::cast(break_point_objects())->length(); |
9045 } | 9350 } |
9046 #endif | 9351 #endif |
9047 | 9352 |
9048 | 9353 |
9049 } } // namespace v8::internal | 9354 } } // namespace v8::internal |
OLD | NEW |