Chromium Code Reviews| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 return Failure::InternalError(); | 106 return Failure::InternalError(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 | 109 |
| 110 Object* Object::ToBoolean() { | 110 Object* Object::ToBoolean() { |
| 111 if (IsTrue()) return this; | 111 if (IsTrue()) return this; |
| 112 if (IsFalse()) return this; | 112 if (IsFalse()) return this; |
| 113 if (IsSmi()) { | 113 if (IsSmi()) { |
| 114 return Isolate::Current()->heap()->ToBoolean(Smi::cast(this)->value() != 0); | 114 return Isolate::Current()->heap()->ToBoolean(Smi::cast(this)->value() != 0); |
| 115 } | 115 } |
| 116 if (IsUndefined() || IsNull()) { | 116 HeapObject* heap_this = HeapObject::cast(this); |
|
Vyacheslav Egorov (Chromium)
2011/03/30 15:57:33
heap_this is confusing name.
| |
| 117 return HeapObject::cast(this)->GetHeap()->false_value(); | 117 if (heap_this->IsUndefined() || heap_this->IsNull()) { |
| 118 return heap_this->GetHeap()->false_value(); | |
| 118 } | 119 } |
| 119 // Undetectable object is false | 120 // Undetectable object is false |
| 120 if (IsUndetectableObject()) { | 121 if (heap_this->IsUndetectableObject()) { |
| 121 return HeapObject::cast(this)->GetHeap()->false_value(); | 122 return heap_this->GetHeap()->false_value(); |
| 122 } | 123 } |
| 123 if (IsString()) { | 124 if (heap_this->IsString()) { |
| 124 return HeapObject::cast(this)->GetHeap()->ToBoolean( | 125 return heap_this->GetHeap()->ToBoolean( |
| 125 String::cast(this)->length() != 0); | 126 String::cast(this)->length() != 0); |
| 126 } | 127 } |
| 127 if (IsHeapNumber()) { | 128 if (heap_this->IsHeapNumber()) { |
| 128 return HeapNumber::cast(this)->HeapNumberToBoolean(); | 129 return HeapNumber::cast(this)->HeapNumberToBoolean(); |
| 129 } | 130 } |
| 130 return Isolate::Current()->heap()->true_value(); | 131 return heap_this->GetHeap()->true_value(); |
| 131 } | 132 } |
| 132 | 133 |
| 133 | 134 |
| 134 void Object::Lookup(String* name, LookupResult* result) { | 135 void Object::Lookup(String* name, LookupResult* result) { |
| 135 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); | |
| 136 Object* holder = NULL; | 136 Object* holder = NULL; |
| 137 if (IsString()) { | 137 if (IsSmi()) { |
| 138 Heap* heap = HeapObject::cast(this)->GetHeap(); | |
| 139 Context* global_context = heap->isolate()->context()->global_context(); | |
| 140 holder = global_context->string_function()->instance_prototype(); | |
| 141 } else if (IsNumber()) { | |
| 142 Heap* heap = Isolate::Current()->heap(); | 138 Heap* heap = Isolate::Current()->heap(); |
| 143 Context* global_context = heap->isolate()->context()->global_context(); | 139 Context* global_context = heap->isolate()->context()->global_context(); |
| 144 holder = global_context->number_function()->instance_prototype(); | 140 holder = global_context->number_function()->instance_prototype(); |
| 145 } else if (IsBoolean()) { | 141 } else { |
| 146 Heap* heap = HeapObject::cast(this)->GetHeap(); | 142 HeapObject* heap_this = HeapObject::cast(this); |
| 147 Context* global_context = heap->isolate()->context()->global_context(); | 143 if (heap_this->IsJSObject()) { |
| 148 holder = global_context->boolean_function()->instance_prototype(); | 144 return JSObject::cast(this)->Lookup(name, result); |
| 145 } | |
| 146 Heap* heap = heap_this->GetHeap(); | |
| 147 if (heap_this->IsString()) { | |
| 148 Context* global_context = heap->isolate()->context()->global_context(); | |
| 149 holder = global_context->string_function()->instance_prototype(); | |
| 150 } else if (heap_this->IsHeapNumber()) { | |
| 151 Context* global_context = heap->isolate()->context()->global_context(); | |
| 152 holder = global_context->number_function()->instance_prototype(); | |
| 153 } else if (heap_this->IsBoolean()) { | |
| 154 Context* global_context = heap->isolate()->context()->global_context(); | |
| 155 holder = global_context->boolean_function()->instance_prototype(); | |
| 156 } | |
| 149 } | 157 } |
| 150 ASSERT(holder != NULL); // Cannot handle null or undefined. | 158 ASSERT(holder != NULL); // Cannot handle null or undefined. |
| 151 JSObject::cast(holder)->Lookup(name, result); | 159 JSObject::cast(holder)->Lookup(name, result); |
| 152 } | 160 } |
| 153 | 161 |
| 154 | 162 |
| 155 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 163 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
| 156 String* name, | 164 String* name, |
| 157 PropertyAttributes* attributes) { | 165 PropertyAttributes* attributes) { |
| 158 LookupResult result; | 166 LookupResult result; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 return *result; | 248 return *result; |
| 241 } | 249 } |
| 242 | 250 |
| 243 | 251 |
| 244 // Only deal with CALLBACKS and INTERCEPTOR | 252 // Only deal with CALLBACKS and INTERCEPTOR |
| 245 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( | 253 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( |
| 246 Object* receiver, | 254 Object* receiver, |
| 247 LookupResult* result, | 255 LookupResult* result, |
| 248 String* name, | 256 String* name, |
| 249 PropertyAttributes* attributes) { | 257 PropertyAttributes* attributes) { |
| 250 Heap* heap = name->GetHeap(); | |
| 251 if (result->IsProperty()) { | 258 if (result->IsProperty()) { |
| 252 switch (result->type()) { | 259 switch (result->type()) { |
| 253 case CALLBACKS: { | 260 case CALLBACKS: { |
| 254 // Only allow API accessors. | 261 // Only allow API accessors. |
| 255 Object* obj = result->GetCallbackObject(); | 262 Object* obj = result->GetCallbackObject(); |
| 256 if (obj->IsAccessorInfo()) { | 263 if (obj->IsAccessorInfo()) { |
| 257 AccessorInfo* info = AccessorInfo::cast(obj); | 264 AccessorInfo* info = AccessorInfo::cast(obj); |
| 258 if (info->all_can_read()) { | 265 if (info->all_can_read()) { |
| 259 *attributes = result->GetAttributes(); | 266 *attributes = result->GetAttributes(); |
| 260 return GetPropertyWithCallback(receiver, | 267 return GetPropertyWithCallback(receiver, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 } | 299 } |
| 293 break; | 300 break; |
| 294 } | 301 } |
| 295 default: | 302 default: |
| 296 UNREACHABLE(); | 303 UNREACHABLE(); |
| 297 } | 304 } |
| 298 } | 305 } |
| 299 | 306 |
| 300 // No accessible property found. | 307 // No accessible property found. |
| 301 *attributes = ABSENT; | 308 *attributes = ABSENT; |
| 309 Heap* heap = name->GetHeap(); | |
| 302 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 310 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 303 return heap->undefined_value(); | 311 return heap->undefined_value(); |
| 304 } | 312 } |
| 305 | 313 |
| 306 | 314 |
| 307 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 315 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
| 308 Object* receiver, | 316 Object* receiver, |
| 309 LookupResult* result, | 317 LookupResult* result, |
| 310 String* name, | 318 String* name, |
| 311 bool continue_search) { | 319 bool continue_search) { |
| 312 Heap* heap = name->GetHeap(); | |
| 313 if (result->IsProperty()) { | 320 if (result->IsProperty()) { |
| 314 switch (result->type()) { | 321 switch (result->type()) { |
| 315 case CALLBACKS: { | 322 case CALLBACKS: { |
| 316 // Only allow API accessors. | 323 // Only allow API accessors. |
| 317 Object* obj = result->GetCallbackObject(); | 324 Object* obj = result->GetCallbackObject(); |
| 318 if (obj->IsAccessorInfo()) { | 325 if (obj->IsAccessorInfo()) { |
| 319 AccessorInfo* info = AccessorInfo::cast(obj); | 326 AccessorInfo* info = AccessorInfo::cast(obj); |
| 320 if (info->all_can_read()) { | 327 if (info->all_can_read()) { |
| 321 return result->GetAttributes(); | 328 return result->GetAttributes(); |
| 322 } | 329 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 continue_search); | 363 continue_search); |
| 357 } | 364 } |
| 358 break; | 365 break; |
| 359 } | 366 } |
| 360 | 367 |
| 361 default: | 368 default: |
| 362 UNREACHABLE(); | 369 UNREACHABLE(); |
| 363 } | 370 } |
| 364 } | 371 } |
| 365 | 372 |
| 366 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 373 GetHeap()->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 367 return ABSENT; | 374 return ABSENT; |
| 368 } | 375 } |
| 369 | 376 |
| 370 | 377 |
| 371 Object* JSObject::GetNormalizedProperty(LookupResult* result) { | 378 Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
| 372 ASSERT(!HasFastProperties()); | 379 ASSERT(!HasFastProperties()); |
| 373 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 380 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 374 if (IsGlobalObject()) { | 381 if (IsGlobalObject()) { |
| 375 value = JSGlobalPropertyCell::cast(value)->value(); | 382 value = JSGlobalPropertyCell::cast(value)->value(); |
| 376 } | 383 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 390 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 397 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 391 } | 398 } |
| 392 return value; | 399 return value; |
| 393 } | 400 } |
| 394 | 401 |
| 395 | 402 |
| 396 MaybeObject* JSObject::SetNormalizedProperty(String* name, | 403 MaybeObject* JSObject::SetNormalizedProperty(String* name, |
| 397 Object* value, | 404 Object* value, |
| 398 PropertyDetails details) { | 405 PropertyDetails details) { |
| 399 ASSERT(!HasFastProperties()); | 406 ASSERT(!HasFastProperties()); |
| 400 Heap* heap = name->GetHeap(); | |
| 401 int entry = property_dictionary()->FindEntry(name); | 407 int entry = property_dictionary()->FindEntry(name); |
| 402 if (entry == StringDictionary::kNotFound) { | 408 if (entry == StringDictionary::kNotFound) { |
| 403 Object* store_value = value; | 409 Object* store_value = value; |
| 404 if (IsGlobalObject()) { | 410 if (IsGlobalObject()) { |
| 411 Heap* heap = name->GetHeap(); | |
| 405 MaybeObject* maybe_store_value = | 412 MaybeObject* maybe_store_value = |
| 406 heap->AllocateJSGlobalPropertyCell(value); | 413 heap->AllocateJSGlobalPropertyCell(value); |
| 407 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 414 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 408 } | 415 } |
| 409 Object* dict; | 416 Object* dict; |
| 410 { MaybeObject* maybe_dict = | 417 { MaybeObject* maybe_dict = |
| 411 property_dictionary()->Add(name, store_value, details); | 418 property_dictionary()->Add(name, store_value, details); |
| 412 if (!maybe_dict->ToObject(&dict)) return maybe_dict; | 419 if (!maybe_dict->ToObject(&dict)) return maybe_dict; |
| 413 } | 420 } |
| 414 set_properties(StringDictionary::cast(dict)); | 421 set_properties(StringDictionary::cast(dict)); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 426 property_dictionary()->DetailsAtPut(entry, details); | 433 property_dictionary()->DetailsAtPut(entry, details); |
| 427 } else { | 434 } else { |
| 428 property_dictionary()->SetEntry(entry, name, value, details); | 435 property_dictionary()->SetEntry(entry, name, value, details); |
| 429 } | 436 } |
| 430 return value; | 437 return value; |
| 431 } | 438 } |
| 432 | 439 |
| 433 | 440 |
| 434 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 441 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
| 435 ASSERT(!HasFastProperties()); | 442 ASSERT(!HasFastProperties()); |
| 436 Heap* heap = GetHeap(); | |
| 437 StringDictionary* dictionary = property_dictionary(); | 443 StringDictionary* dictionary = property_dictionary(); |
| 438 int entry = dictionary->FindEntry(name); | 444 int entry = dictionary->FindEntry(name); |
| 439 if (entry != StringDictionary::kNotFound) { | 445 if (entry != StringDictionary::kNotFound) { |
| 440 // If we have a global object set the cell to the hole. | 446 // If we have a global object set the cell to the hole. |
| 441 if (IsGlobalObject()) { | 447 if (IsGlobalObject()) { |
| 442 PropertyDetails details = dictionary->DetailsAt(entry); | 448 PropertyDetails details = dictionary->DetailsAt(entry); |
| 443 if (details.IsDontDelete()) { | 449 if (details.IsDontDelete()) { |
| 444 if (mode != FORCE_DELETION) return heap->false_value(); | 450 if (mode != FORCE_DELETION) return GetHeap()->false_value(); |
| 445 // When forced to delete global properties, we have to make a | 451 // When forced to delete global properties, we have to make a |
| 446 // map change to invalidate any ICs that think they can load | 452 // map change to invalidate any ICs that think they can load |
| 447 // from the DontDelete cell without checking if it contains | 453 // from the DontDelete cell without checking if it contains |
| 448 // the hole value. | 454 // the hole value. |
| 449 Object* new_map; | 455 Object* new_map; |
| 450 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 456 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 451 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 457 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 452 } | 458 } |
| 453 set_map(Map::cast(new_map)); | 459 set_map(Map::cast(new_map)); |
| 454 } | 460 } |
| 455 JSGlobalPropertyCell* cell = | 461 JSGlobalPropertyCell* cell = |
| 456 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 462 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
| 457 cell->set_value(heap->the_hole_value()); | 463 cell->set_value(cell->heap()->the_hole_value()); |
| 458 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 464 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 459 } else { | 465 } else { |
| 460 return dictionary->DeleteProperty(entry, mode); | 466 return dictionary->DeleteProperty(entry, mode); |
| 461 } | 467 } |
| 462 } | 468 } |
| 463 return heap->true_value(); | 469 return GetHeap()->true_value(); |
| 464 } | 470 } |
| 465 | 471 |
| 466 | 472 |
| 467 bool JSObject::IsDirty() { | 473 bool JSObject::IsDirty() { |
| 468 Object* cons_obj = map()->constructor(); | 474 Object* cons_obj = map()->constructor(); |
| 469 if (!cons_obj->IsJSFunction()) | 475 if (!cons_obj->IsJSFunction()) |
| 470 return true; | 476 return true; |
| 471 JSFunction* fun = JSFunction::cast(cons_obj); | 477 JSFunction* fun = JSFunction::cast(cons_obj); |
| 472 if (!fun->shared()->IsApiFunction()) | 478 if (!fun->shared()->IsApiFunction()) |
| 473 return true; | 479 return true; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 549 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
| 544 } | 550 } |
| 545 default: | 551 default: |
| 546 UNREACHABLE(); | 552 UNREACHABLE(); |
| 547 return NULL; | 553 return NULL; |
| 548 } | 554 } |
| 549 } | 555 } |
| 550 | 556 |
| 551 | 557 |
| 552 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 558 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
| 553 if (IsJSObject()) { | 559 Object* holder = NULL; |
| 554 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); | 560 if (IsSmi()) { |
| 555 } | 561 Context* global_context = Isolate::Current()->context()->global_context(); |
| 562 holder = global_context->number_function()->instance_prototype(); | |
| 563 } else { | |
| 564 HeapObject* heap_this = HeapObject::cast(this); | |
| 556 | 565 |
| 557 Object* holder = NULL; | 566 if (heap_this->IsJSObject()) { |
| 558 Context* global_context = Isolate::Current()->context()->global_context(); | 567 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); |
| 559 if (IsString()) { | 568 } |
| 560 holder = global_context->string_function()->instance_prototype(); | 569 Heap* heap = heap_this->GetHeap(); |
| 561 } else if (IsNumber()) { | 570 Isolate* isolate = heap->isolate(); |
| 562 holder = global_context->number_function()->instance_prototype(); | 571 |
| 563 } else if (IsBoolean()) { | 572 Context* global_context = isolate->context()->global_context(); |
| 564 holder = global_context->boolean_function()->instance_prototype(); | 573 if (heap_this->IsString()) { |
| 565 } else { | 574 holder = global_context->string_function()->instance_prototype(); |
| 566 // Undefined and null have no indexed properties. | 575 } else if (heap_this->IsHeapNumber()) { |
| 567 ASSERT(IsUndefined() || IsNull()); | 576 holder = global_context->number_function()->instance_prototype(); |
| 568 return HEAP->undefined_value(); | 577 } else if (heap_this->IsBoolean()) { |
| 578 holder = global_context->boolean_function()->instance_prototype(); | |
| 579 } else { | |
| 580 // Undefined and null have no indexed properties. | |
| 581 ASSERT(heap_this->IsUndefined() || heap_this->IsNull()); | |
| 582 return heap->undefined_value(); | |
| 583 } | |
| 569 } | 584 } |
| 570 | 585 |
| 571 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); | 586 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); |
| 572 } | 587 } |
| 573 | 588 |
| 574 | 589 |
| 575 Object* Object::GetPrototype() { | 590 Object* Object::GetPrototype() { |
| 591 if (IsSmi()) { | |
| 592 Heap* heap = Isolate::Current()->heap(); | |
| 593 Context* context = heap->isolate()->context()->global_context(); | |
| 594 return context->number_function()->instance_prototype(); | |
| 595 } | |
| 596 | |
| 597 HeapObject* heap_this = HeapObject::cast(this); | |
| 598 | |
| 576 // The object is either a number, a string, a boolean, or a real JS object. | 599 // The object is either a number, a string, a boolean, or a real JS object. |
| 577 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); | 600 if (heap_this->IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
| 578 Heap* heap = Isolate::Current()->heap(); | 601 Heap* heap = heap_this->GetHeap(); |
| 579 Context* context = heap->isolate()->context()->global_context(); | 602 Context* context = heap->isolate()->context()->global_context(); |
| 580 | 603 |
| 581 if (IsNumber()) return context->number_function()->instance_prototype(); | 604 if (heap_this->IsHeapNumber()) { |
| 582 if (IsString()) return context->string_function()->instance_prototype(); | 605 return context->number_function()->instance_prototype(); |
| 583 if (IsBoolean()) { | 606 } |
| 607 if (heap_this->IsString()) { | |
| 608 return context->string_function()->instance_prototype(); | |
| 609 } | |
| 610 if (heap_this->IsBoolean()) { | |
| 584 return context->boolean_function()->instance_prototype(); | 611 return context->boolean_function()->instance_prototype(); |
| 585 } else { | 612 } else { |
| 586 return heap->null_value(); | 613 return heap->null_value(); |
| 587 } | 614 } |
| 588 } | 615 } |
| 589 | 616 |
| 590 | 617 |
| 591 void Object::ShortPrint(FILE* out) { | 618 void Object::ShortPrint(FILE* out) { |
| 592 HeapStringAllocator allocator; | 619 HeapStringAllocator allocator; |
| 593 StringStream accumulator(&allocator); | 620 StringStream accumulator(&allocator); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 } | 928 } |
| 902 } | 929 } |
| 903 if (!printed) { | 930 if (!printed) { |
| 904 accumulator->Add("<JS Function>"); | 931 accumulator->Add("<JS Function>"); |
| 905 } | 932 } |
| 906 break; | 933 break; |
| 907 } | 934 } |
| 908 // All other JSObjects are rather similar to each other (JSObject, | 935 // All other JSObjects are rather similar to each other (JSObject, |
| 909 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). | 936 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). |
| 910 default: { | 937 default: { |
| 911 Heap* heap = GetHeap(); | 938 Map* map_of_this = map(); |
| 912 Object* constructor = map()->constructor(); | 939 Heap* heap = map_of_this->heap(); |
| 940 Object* constructor = map_of_this->constructor(); | |
| 913 bool printed = false; | 941 bool printed = false; |
| 914 if (constructor->IsHeapObject() && | 942 if (constructor->IsHeapObject() && |
| 915 !heap->Contains(HeapObject::cast(constructor))) { | 943 !heap->Contains(HeapObject::cast(constructor))) { |
| 916 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); | 944 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); |
| 917 } else { | 945 } else { |
| 918 bool global_object = IsJSGlobalProxy(); | 946 bool global_object = IsJSGlobalProxy(); |
| 919 if (constructor->IsJSFunction()) { | 947 if (constructor->IsJSFunction()) { |
| 920 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { | 948 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { |
| 921 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); | 949 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); |
| 922 } else { | 950 } else { |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1343 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1371 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1344 set_map(new_map); | 1372 set_map(new_map); |
| 1345 return FastPropertyAtPut(index, value); | 1373 return FastPropertyAtPut(index, value); |
| 1346 } | 1374 } |
| 1347 | 1375 |
| 1348 | 1376 |
| 1349 MaybeObject* JSObject::AddConstantFunctionProperty( | 1377 MaybeObject* JSObject::AddConstantFunctionProperty( |
| 1350 String* name, | 1378 String* name, |
| 1351 JSFunction* function, | 1379 JSFunction* function, |
| 1352 PropertyAttributes attributes) { | 1380 PropertyAttributes attributes) { |
| 1353 Heap* heap = GetHeap(); | 1381 ASSERT(!GetHeap()->InNewSpace(function)); |
| 1354 ASSERT(!heap->InNewSpace(function)); | |
| 1355 | 1382 |
| 1356 // Allocate new instance descriptors with (name, function) added | 1383 // Allocate new instance descriptors with (name, function) added |
| 1357 ConstantFunctionDescriptor d(name, function, attributes); | 1384 ConstantFunctionDescriptor d(name, function, attributes); |
| 1358 Object* new_descriptors; | 1385 Object* new_descriptors; |
| 1359 { MaybeObject* maybe_new_descriptors = | 1386 { MaybeObject* maybe_new_descriptors = |
| 1360 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); | 1387 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); |
| 1361 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1388 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
| 1362 return maybe_new_descriptors; | 1389 return maybe_new_descriptors; |
| 1363 } | 1390 } |
| 1364 } | 1391 } |
| 1365 | 1392 |
| 1366 // Allocate a new map for the object. | 1393 // Allocate a new map for the object. |
| 1367 Object* new_map; | 1394 Object* new_map; |
| 1368 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 1395 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 1369 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 1396 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 1370 } | 1397 } |
| 1371 | 1398 |
| 1372 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); | 1399 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); |
| 1373 Map::cast(new_map)->set_instance_descriptors(descriptors); | 1400 Map::cast(new_map)->set_instance_descriptors(descriptors); |
| 1374 Map* old_map = map(); | 1401 Map* old_map = map(); |
| 1375 set_map(Map::cast(new_map)); | 1402 set_map(Map::cast(new_map)); |
| 1376 | 1403 |
| 1377 // If the old map is the global object map (from new Object()), | 1404 // If the old map is the global object map (from new Object()), |
| 1378 // then transitions are not added to it, so we are done. | 1405 // then transitions are not added to it, so we are done. |
| 1406 Heap* heap = old_map->heap(); | |
| 1379 if (old_map == heap->isolate()->context()->global_context()-> | 1407 if (old_map == heap->isolate()->context()->global_context()-> |
| 1380 object_function()->map()) { | 1408 object_function()->map()) { |
| 1381 return function; | 1409 return function; |
| 1382 } | 1410 } |
| 1383 | 1411 |
| 1384 // Do not add CONSTANT_TRANSITIONS to global objects | 1412 // Do not add CONSTANT_TRANSITIONS to global objects |
| 1385 if (IsGlobalObject()) { | 1413 if (IsGlobalObject()) { |
| 1386 return function; | 1414 return function; |
| 1387 } | 1415 } |
| 1388 | 1416 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1405 | 1433 |
| 1406 return function; | 1434 return function; |
| 1407 } | 1435 } |
| 1408 | 1436 |
| 1409 | 1437 |
| 1410 // Add property in slow mode | 1438 // Add property in slow mode |
| 1411 MaybeObject* JSObject::AddSlowProperty(String* name, | 1439 MaybeObject* JSObject::AddSlowProperty(String* name, |
| 1412 Object* value, | 1440 Object* value, |
| 1413 PropertyAttributes attributes) { | 1441 PropertyAttributes attributes) { |
| 1414 ASSERT(!HasFastProperties()); | 1442 ASSERT(!HasFastProperties()); |
| 1415 Heap* heap = GetHeap(); | |
| 1416 StringDictionary* dict = property_dictionary(); | 1443 StringDictionary* dict = property_dictionary(); |
| 1417 Object* store_value = value; | 1444 Object* store_value = value; |
| 1418 if (IsGlobalObject()) { | 1445 if (IsGlobalObject()) { |
| 1419 // In case name is an orphaned property reuse the cell. | 1446 // In case name is an orphaned property reuse the cell. |
| 1420 int entry = dict->FindEntry(name); | 1447 int entry = dict->FindEntry(name); |
| 1421 if (entry != StringDictionary::kNotFound) { | 1448 if (entry != StringDictionary::kNotFound) { |
| 1422 store_value = dict->ValueAt(entry); | 1449 store_value = dict->ValueAt(entry); |
| 1423 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1450 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1424 // Assign an enumeration index to the property and update | 1451 // Assign an enumeration index to the property and update |
| 1425 // SetNextEnumerationIndex. | 1452 // SetNextEnumerationIndex. |
| 1426 int index = dict->NextEnumerationIndex(); | 1453 int index = dict->NextEnumerationIndex(); |
| 1427 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); | 1454 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
| 1428 dict->SetNextEnumerationIndex(index + 1); | 1455 dict->SetNextEnumerationIndex(index + 1); |
| 1429 dict->SetEntry(entry, name, store_value, details); | 1456 dict->SetEntry(entry, name, store_value, details); |
| 1430 return value; | 1457 return value; |
| 1431 } | 1458 } |
| 1459 Heap* heap = GetHeap(); | |
| 1432 { MaybeObject* maybe_store_value = | 1460 { MaybeObject* maybe_store_value = |
| 1433 heap->AllocateJSGlobalPropertyCell(value); | 1461 heap->AllocateJSGlobalPropertyCell(value); |
| 1434 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 1462 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 1435 } | 1463 } |
| 1436 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1464 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1437 } | 1465 } |
| 1438 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1466 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1439 Object* result; | 1467 Object* result; |
| 1440 { MaybeObject* maybe_result = dict->Add(name, store_value, details); | 1468 { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
| 1441 if (!maybe_result->ToObject(&result)) return maybe_result; | 1469 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1442 } | 1470 } |
| 1443 if (dict != result) set_properties(StringDictionary::cast(result)); | 1471 if (dict != result) set_properties(StringDictionary::cast(result)); |
| 1444 return value; | 1472 return value; |
| 1445 } | 1473 } |
| 1446 | 1474 |
| 1447 | 1475 |
| 1448 MaybeObject* JSObject::AddProperty(String* name, | 1476 MaybeObject* JSObject::AddProperty(String* name, |
| 1449 Object* value, | 1477 Object* value, |
| 1450 PropertyAttributes attributes, | 1478 PropertyAttributes attributes, |
| 1451 StrictModeFlag strict_mode) { | 1479 StrictModeFlag strict_mode) { |
| 1452 ASSERT(!IsJSGlobalProxy()); | 1480 ASSERT(!IsJSGlobalProxy()); |
| 1453 Heap* heap = GetHeap(); | 1481 Map* map_of_this = map(); |
| 1454 if (!map()->is_extensible()) { | 1482 Heap* heap = map_of_this->heap(); |
| 1483 if (!map_of_this->is_extensible()) { | |
| 1455 if (strict_mode == kNonStrictMode) { | 1484 if (strict_mode == kNonStrictMode) { |
| 1456 return heap->undefined_value(); | 1485 return heap->undefined_value(); |
| 1457 } else { | 1486 } else { |
| 1458 Handle<Object> args[1] = {Handle<String>(name)}; | 1487 Handle<Object> args[1] = {Handle<String>(name)}; |
| 1459 return heap->isolate()->Throw( | 1488 return heap->isolate()->Throw( |
| 1460 *FACTORY->NewTypeError("object_not_extensible", | 1489 *FACTORY->NewTypeError("object_not_extensible", |
| 1461 HandleVector(args, 1))); | 1490 HandleVector(args, 1))); |
| 1462 } | 1491 } |
| 1463 } | 1492 } |
| 1464 if (HasFastProperties()) { | 1493 if (HasFastProperties()) { |
| 1465 // Ensure the descriptor array does not get too big. | 1494 // Ensure the descriptor array does not get too big. |
| 1466 if (map()->instance_descriptors()->number_of_descriptors() < | 1495 if (map_of_this->instance_descriptors()->number_of_descriptors() < |
| 1467 DescriptorArray::kMaxNumberOfDescriptors) { | 1496 DescriptorArray::kMaxNumberOfDescriptors) { |
| 1468 if (value->IsJSFunction() && !heap->InNewSpace(value)) { | 1497 if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
| 1469 return AddConstantFunctionProperty(name, | 1498 return AddConstantFunctionProperty(name, |
| 1470 JSFunction::cast(value), | 1499 JSFunction::cast(value), |
| 1471 attributes); | 1500 attributes); |
| 1472 } else { | 1501 } else { |
| 1473 return AddFastProperty(name, value, attributes); | 1502 return AddFastProperty(name, value, attributes); |
| 1474 } | 1503 } |
| 1475 } else { | 1504 } else { |
| 1476 // Normalize the object to prevent very large instance descriptors. | 1505 // Normalize the object to prevent very large instance descriptors. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1530 { MaybeObject* maybe_result = | 1559 { MaybeObject* maybe_result = |
| 1531 ConvertDescriptorToField(name, new_value, attributes); | 1560 ConvertDescriptorToField(name, new_value, attributes); |
| 1532 if (!maybe_result->ToObject(&result)) return maybe_result; | 1561 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1533 } | 1562 } |
| 1534 // If we get to this point we have succeeded - do not return failure | 1563 // If we get to this point we have succeeded - do not return failure |
| 1535 // after this point. Later stuff is optional. | 1564 // after this point. Later stuff is optional. |
| 1536 if (!HasFastProperties()) { | 1565 if (!HasFastProperties()) { |
| 1537 return result; | 1566 return result; |
| 1538 } | 1567 } |
| 1539 // Do not add transitions to the map of "new Object()". | 1568 // Do not add transitions to the map of "new Object()". |
| 1540 if (map() == GetHeap()->isolate()->context()->global_context()-> | 1569 if (map() == old_map->heap()->isolate()->context()->global_context()-> |
| 1541 object_function()->map()) { | 1570 object_function()->map()) { |
| 1542 return result; | 1571 return result; |
| 1543 } | 1572 } |
| 1544 | 1573 |
| 1545 MapTransitionDescriptor transition(name, | 1574 MapTransitionDescriptor transition(name, |
| 1546 map(), | 1575 map(), |
| 1547 attributes); | 1576 attributes); |
| 1548 Object* new_descriptors; | 1577 Object* new_descriptors; |
| 1549 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> | 1578 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> |
| 1550 CopyInsert(&transition, KEEP_TRANSITIONS); | 1579 CopyInsert(&transition, KEEP_TRANSITIONS); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 if (number != DescriptorArray::kNotFound) { | 1858 if (number != DescriptorArray::kNotFound) { |
| 1830 result->DescriptorResult(holder, descriptors->GetDetails(number), number); | 1859 result->DescriptorResult(holder, descriptors->GetDetails(number), number); |
| 1831 } else { | 1860 } else { |
| 1832 result->NotFound(); | 1861 result->NotFound(); |
| 1833 } | 1862 } |
| 1834 } | 1863 } |
| 1835 | 1864 |
| 1836 | 1865 |
| 1837 MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, | 1866 MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, |
| 1838 bool safe_to_add_transition) { | 1867 bool safe_to_add_transition) { |
| 1868 Heap* current_heap = heap(); | |
| 1839 DescriptorArray* descriptors = instance_descriptors(); | 1869 DescriptorArray* descriptors = instance_descriptors(); |
| 1840 String* external_array_sentinel_name = GetIsolate()->heap()->empty_symbol(); | 1870 String* external_array_sentinel_name = current_heap->empty_symbol(); |
| 1841 | 1871 |
| 1842 if (safe_to_add_transition) { | 1872 if (safe_to_add_transition) { |
| 1843 // It's only safe to manipulate the descriptor array if it would be | 1873 // It's only safe to manipulate the descriptor array if it would be |
| 1844 // safe to add a transition. | 1874 // safe to add a transition. |
| 1845 | 1875 |
| 1846 ASSERT(!is_shared()); // no transitions can be added to shared maps. | 1876 ASSERT(!is_shared()); // no transitions can be added to shared maps. |
| 1847 // Check if the external array transition already exists. | 1877 // Check if the external array transition already exists. |
| 1848 DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache(); | 1878 DescriptorLookupCache* cache = |
| 1879 current_heap->isolate()->descriptor_lookup_cache(); | |
| 1849 int index = cache->Lookup(descriptors, external_array_sentinel_name); | 1880 int index = cache->Lookup(descriptors, external_array_sentinel_name); |
| 1850 if (index == DescriptorLookupCache::kAbsent) { | 1881 if (index == DescriptorLookupCache::kAbsent) { |
| 1851 index = descriptors->Search(external_array_sentinel_name); | 1882 index = descriptors->Search(external_array_sentinel_name); |
| 1852 cache->Update(descriptors, | 1883 cache->Update(descriptors, |
| 1853 external_array_sentinel_name, | 1884 external_array_sentinel_name, |
| 1854 index); | 1885 index); |
| 1855 } | 1886 } |
| 1856 | 1887 |
| 1857 // If the transition already exists, check the type. If there is a match, | 1888 // If the transition already exists, check the type. If there is a match, |
| 1858 // return it. | 1889 // return it. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1972 } | 2003 } |
| 1973 result->NotFound(); | 2004 result->NotFound(); |
| 1974 } | 2005 } |
| 1975 | 2006 |
| 1976 | 2007 |
| 1977 // We only need to deal with CALLBACKS and INTERCEPTORS | 2008 // We only need to deal with CALLBACKS and INTERCEPTORS |
| 1978 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 2009 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, |
| 1979 String* name, | 2010 String* name, |
| 1980 Object* value, | 2011 Object* value, |
| 1981 bool check_prototype) { | 2012 bool check_prototype) { |
| 1982 Heap* heap = GetHeap(); | |
| 1983 if (check_prototype && !result->IsProperty()) { | 2013 if (check_prototype && !result->IsProperty()) { |
| 1984 LookupCallbackSetterInPrototypes(name, result); | 2014 LookupCallbackSetterInPrototypes(name, result); |
| 1985 } | 2015 } |
| 1986 | 2016 |
| 1987 if (result->IsProperty()) { | 2017 if (result->IsProperty()) { |
| 1988 if (!result->IsReadOnly()) { | 2018 if (!result->IsReadOnly()) { |
| 1989 switch (result->type()) { | 2019 switch (result->type()) { |
| 1990 case CALLBACKS: { | 2020 case CALLBACKS: { |
| 1991 Object* obj = result->GetCallbackObject(); | 2021 Object* obj = result->GetCallbackObject(); |
| 1992 if (obj->IsAccessorInfo()) { | 2022 if (obj->IsAccessorInfo()) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2013 } | 2043 } |
| 2014 default: { | 2044 default: { |
| 2015 break; | 2045 break; |
| 2016 } | 2046 } |
| 2017 } | 2047 } |
| 2018 } | 2048 } |
| 2019 } | 2049 } |
| 2020 | 2050 |
| 2021 HandleScope scope; | 2051 HandleScope scope; |
| 2022 Handle<Object> value_handle(value); | 2052 Handle<Object> value_handle(value); |
| 2053 Heap* heap = GetHeap(); | |
| 2023 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2054 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2024 return *value_handle; | 2055 return *value_handle; |
| 2025 } | 2056 } |
| 2026 | 2057 |
| 2027 | 2058 |
| 2028 MaybeObject* JSObject::SetProperty(LookupResult* result, | 2059 MaybeObject* JSObject::SetProperty(LookupResult* result, |
| 2029 String* name, | 2060 String* name, |
| 2030 Object* value, | 2061 Object* value, |
| 2031 PropertyAttributes attributes, | 2062 PropertyAttributes attributes, |
| 2032 StrictModeFlag strict_mode) { | 2063 StrictModeFlag strict_mode) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2150 // Set a real local property, even if it is READ_ONLY. If the property is not | 2181 // Set a real local property, even if it is READ_ONLY. If the property is not |
| 2151 // present, add it with attributes NONE. This code is an exact clone of | 2182 // present, add it with attributes NONE. This code is an exact clone of |
| 2152 // SetProperty, with the check for IsReadOnly and the check for a | 2183 // SetProperty, with the check for IsReadOnly and the check for a |
| 2153 // callback setter removed. The two lines looking up the LookupResult | 2184 // callback setter removed. The two lines looking up the LookupResult |
| 2154 // result are also added. If one of the functions is changed, the other | 2185 // result are also added. If one of the functions is changed, the other |
| 2155 // should be. | 2186 // should be. |
| 2156 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 2187 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 2157 String* name, | 2188 String* name, |
| 2158 Object* value, | 2189 Object* value, |
| 2159 PropertyAttributes attributes) { | 2190 PropertyAttributes attributes) { |
| 2160 Heap* heap = GetHeap(); | |
| 2161 | 2191 |
| 2162 // Make sure that the top context does not change when doing callbacks or | 2192 // Make sure that the top context does not change when doing callbacks or |
| 2163 // interceptor calls. | 2193 // interceptor calls. |
| 2164 AssertNoContextChange ncc; | 2194 AssertNoContextChange ncc; |
| 2165 LookupResult result; | 2195 LookupResult result; |
| 2166 LocalLookup(name, &result); | 2196 LocalLookup(name, &result); |
| 2167 // Check access rights if needed. | 2197 // Check access rights if needed. |
| 2168 if (IsAccessCheckNeeded() | 2198 if (IsAccessCheckNeeded()) { |
| 2169 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2199 Heap* heap = GetHeap(); |
| 2170 return SetPropertyWithFailedAccessCheck(&result, name, value, false); | 2200 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2201 return SetPropertyWithFailedAccessCheck(&result, name, value, false); | |
| 2202 } | |
| 2171 } | 2203 } |
| 2172 | 2204 |
| 2173 if (IsJSGlobalProxy()) { | 2205 if (IsJSGlobalProxy()) { |
| 2174 Object* proto = GetPrototype(); | 2206 Object* proto = GetPrototype(); |
| 2175 if (proto->IsNull()) return value; | 2207 if (proto->IsNull()) return value; |
| 2176 ASSERT(proto->IsJSGlobalObject()); | 2208 ASSERT(proto->IsJSGlobalObject()); |
| 2177 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 2209 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
| 2178 name, | 2210 name, |
| 2179 value, | 2211 value, |
| 2180 attributes); | 2212 attributes); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2311 LookupResult result; | 2343 LookupResult result; |
| 2312 Lookup(key, &result); | 2344 Lookup(key, &result); |
| 2313 return GetPropertyAttribute(receiver, &result, key, true); | 2345 return GetPropertyAttribute(receiver, &result, key, true); |
| 2314 } | 2346 } |
| 2315 | 2347 |
| 2316 | 2348 |
| 2317 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, | 2349 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, |
| 2318 LookupResult* result, | 2350 LookupResult* result, |
| 2319 String* name, | 2351 String* name, |
| 2320 bool continue_search) { | 2352 bool continue_search) { |
| 2321 Heap* heap = GetHeap(); | |
| 2322 // Check access rights if needed. | 2353 // Check access rights if needed. |
| 2323 if (IsAccessCheckNeeded() && | 2354 if (IsAccessCheckNeeded()) { |
| 2324 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2355 Heap* heap = GetHeap(); |
| 2325 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2356 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 2326 result, | 2357 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 2327 name, | 2358 result, |
| 2328 continue_search); | 2359 name, |
| 2360 continue_search); | |
| 2361 } | |
| 2329 } | 2362 } |
| 2330 if (result->IsProperty()) { | 2363 if (result->IsProperty()) { |
| 2331 switch (result->type()) { | 2364 switch (result->type()) { |
| 2332 case NORMAL: // fall through | 2365 case NORMAL: // fall through |
| 2333 case FIELD: | 2366 case FIELD: |
| 2334 case CONSTANT_FUNCTION: | 2367 case CONSTANT_FUNCTION: |
| 2335 case CALLBACKS: | 2368 case CALLBACKS: |
| 2336 return result->GetAttributes(); | 2369 return result->GetAttributes(); |
| 2337 case INTERCEPTOR: | 2370 case INTERCEPTOR: |
| 2338 return result->holder()-> | 2371 return result->holder()-> |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2458 | 2491 |
| 2459 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 2492 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
| 2460 int expected_additional_properties) { | 2493 int expected_additional_properties) { |
| 2461 if (!HasFastProperties()) return this; | 2494 if (!HasFastProperties()) return this; |
| 2462 | 2495 |
| 2463 // The global object is always normalized. | 2496 // The global object is always normalized. |
| 2464 ASSERT(!IsGlobalObject()); | 2497 ASSERT(!IsGlobalObject()); |
| 2465 // JSGlobalProxy must never be normalized | 2498 // JSGlobalProxy must never be normalized |
| 2466 ASSERT(!IsJSGlobalProxy()); | 2499 ASSERT(!IsJSGlobalProxy()); |
| 2467 | 2500 |
| 2468 Heap* heap = GetHeap(); | 2501 Map* map_of_this = map(); |
| 2469 | 2502 |
| 2470 // Allocate new content. | 2503 // Allocate new content. |
| 2471 int property_count = map()->NumberOfDescribedProperties(); | 2504 int property_count = map_of_this->NumberOfDescribedProperties(); |
| 2472 if (expected_additional_properties > 0) { | 2505 if (expected_additional_properties > 0) { |
| 2473 property_count += expected_additional_properties; | 2506 property_count += expected_additional_properties; |
| 2474 } else { | 2507 } else { |
| 2475 property_count += 2; // Make space for two more properties. | 2508 property_count += 2; // Make space for two more properties. |
| 2476 } | 2509 } |
| 2477 Object* obj; | 2510 Object* obj; |
| 2478 { MaybeObject* maybe_obj = | 2511 { MaybeObject* maybe_obj = |
| 2479 StringDictionary::Allocate(property_count); | 2512 StringDictionary::Allocate(property_count); |
| 2480 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2513 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2481 } | 2514 } |
| 2482 StringDictionary* dictionary = StringDictionary::cast(obj); | 2515 StringDictionary* dictionary = StringDictionary::cast(obj); |
| 2483 | 2516 |
| 2484 DescriptorArray* descs = map()->instance_descriptors(); | 2517 DescriptorArray* descs = map_of_this->instance_descriptors(); |
| 2485 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 2518 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 2486 PropertyDetails details = descs->GetDetails(i); | 2519 PropertyDetails details = descs->GetDetails(i); |
| 2487 switch (details.type()) { | 2520 switch (details.type()) { |
| 2488 case CONSTANT_FUNCTION: { | 2521 case CONSTANT_FUNCTION: { |
| 2489 PropertyDetails d = | 2522 PropertyDetails d = |
| 2490 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2523 PropertyDetails(details.attributes(), NORMAL, details.index()); |
| 2491 Object* value = descs->GetConstantFunction(i); | 2524 Object* value = descs->GetConstantFunction(i); |
| 2492 Object* result; | 2525 Object* result; |
| 2493 { MaybeObject* maybe_result = | 2526 { MaybeObject* maybe_result = |
| 2494 dictionary->Add(descs->GetKey(i), value, d); | 2527 dictionary->Add(descs->GetKey(i), value, d); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2524 case MAP_TRANSITION: | 2557 case MAP_TRANSITION: |
| 2525 case CONSTANT_TRANSITION: | 2558 case CONSTANT_TRANSITION: |
| 2526 case NULL_DESCRIPTOR: | 2559 case NULL_DESCRIPTOR: |
| 2527 case INTERCEPTOR: | 2560 case INTERCEPTOR: |
| 2528 break; | 2561 break; |
| 2529 default: | 2562 default: |
| 2530 UNREACHABLE(); | 2563 UNREACHABLE(); |
| 2531 } | 2564 } |
| 2532 } | 2565 } |
| 2533 | 2566 |
| 2567 Heap* current_heap = map_of_this->heap(); | |
| 2568 | |
| 2534 // Copy the next enumeration index from instance descriptor. | 2569 // Copy the next enumeration index from instance descriptor. |
| 2535 int index = map()->instance_descriptors()->NextEnumerationIndex(); | 2570 int index = map_of_this->instance_descriptors()->NextEnumerationIndex(); |
| 2536 dictionary->SetNextEnumerationIndex(index); | 2571 dictionary->SetNextEnumerationIndex(index); |
| 2537 | 2572 |
| 2538 { MaybeObject* maybe_obj = heap->isolate()->context()->global_context()-> | 2573 { MaybeObject* maybe_obj = |
| 2574 current_heap->isolate()->context()->global_context()-> | |
| 2539 normalized_map_cache()->Get(this, mode); | 2575 normalized_map_cache()->Get(this, mode); |
| 2540 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2576 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2541 } | 2577 } |
| 2542 Map* new_map = Map::cast(obj); | 2578 Map* new_map = Map::cast(obj); |
| 2543 | 2579 |
| 2544 // We have now successfully allocated all the necessary objects. | 2580 // We have now successfully allocated all the necessary objects. |
| 2545 // Changes can now be made with the guarantee that all of them take effect. | 2581 // Changes can now be made with the guarantee that all of them take effect. |
| 2546 | 2582 |
| 2547 // Resize the object in the heap if necessary. | 2583 // Resize the object in the heap if necessary. |
| 2548 int new_instance_size = new_map->instance_size(); | 2584 int new_instance_size = new_map->instance_size(); |
| 2549 int instance_size_delta = map()->instance_size() - new_instance_size; | 2585 int instance_size_delta = map_of_this->instance_size() - new_instance_size; |
| 2550 ASSERT(instance_size_delta >= 0); | 2586 ASSERT(instance_size_delta >= 0); |
| 2551 heap->CreateFillerObjectAt(this->address() + new_instance_size, | 2587 current_heap->CreateFillerObjectAt(this->address() + new_instance_size, |
| 2552 instance_size_delta); | 2588 instance_size_delta); |
| 2553 | 2589 |
| 2554 set_map(new_map); | 2590 set_map(new_map); |
| 2555 map()->set_instance_descriptors(heap->empty_descriptor_array()); | 2591 new_map->set_instance_descriptors(current_heap->empty_descriptor_array()); |
| 2556 | 2592 |
| 2557 set_properties(dictionary); | 2593 set_properties(dictionary); |
| 2558 | 2594 |
| 2559 heap->isolate()->counters()->props_to_dictionary()->Increment(); | 2595 current_heap->isolate()->counters()->props_to_dictionary()->Increment(); |
| 2560 | 2596 |
| 2561 #ifdef DEBUG | 2597 #ifdef DEBUG |
| 2562 if (FLAG_trace_normalization) { | 2598 if (FLAG_trace_normalization) { |
| 2563 PrintF("Object properties have been normalized:\n"); | 2599 PrintF("Object properties have been normalized:\n"); |
| 2564 Print(); | 2600 Print(); |
| 2565 } | 2601 } |
| 2566 #endif | 2602 #endif |
| 2567 return this; | 2603 return this; |
| 2568 } | 2604 } |
| 2569 | 2605 |
| 2570 | 2606 |
| 2571 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { | 2607 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 2572 if (HasFastProperties()) return this; | 2608 if (HasFastProperties()) return this; |
| 2573 ASSERT(!IsGlobalObject()); | 2609 ASSERT(!IsGlobalObject()); |
| 2574 return property_dictionary()-> | 2610 return property_dictionary()-> |
| 2575 TransformPropertiesToFastFor(this, unused_property_fields); | 2611 TransformPropertiesToFastFor(this, unused_property_fields); |
| 2576 } | 2612 } |
| 2577 | 2613 |
| 2578 | 2614 |
| 2579 MaybeObject* JSObject::NormalizeElements() { | 2615 MaybeObject* JSObject::NormalizeElements() { |
| 2580 ASSERT(!HasExternalArrayElements()); | 2616 ASSERT(!HasExternalArrayElements()); |
| 2581 if (HasDictionaryElements()) return this; | 2617 if (HasDictionaryElements()) return this; |
| 2582 ASSERT(map()->has_fast_elements()); | 2618 Map* old_map = map(); |
| 2619 ASSERT(old_map->has_fast_elements()); | |
| 2583 | 2620 |
| 2584 Object* obj; | 2621 Object* obj; |
| 2585 { MaybeObject* maybe_obj = map()->GetSlowElementsMap(); | 2622 { MaybeObject* maybe_obj = old_map->GetSlowElementsMap(); |
| 2586 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2623 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2587 } | 2624 } |
| 2588 Map* new_map = Map::cast(obj); | 2625 Map* new_map = Map::cast(obj); |
| 2589 | 2626 |
| 2590 // Get number of entries. | 2627 // Get number of entries. |
| 2591 FixedArray* array = FixedArray::cast(elements()); | 2628 FixedArray* array = FixedArray::cast(elements()); |
| 2592 | 2629 |
| 2593 // Compute the effective length. | 2630 // Compute the effective length. |
| 2594 int length = IsJSArray() ? | 2631 int length = IsJSArray() ? |
| 2595 Smi::cast(JSArray::cast(this)->length())->value() : | 2632 Smi::cast(JSArray::cast(this)->length())->value() : |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 2610 } | 2647 } |
| 2611 dictionary = NumberDictionary::cast(result); | 2648 dictionary = NumberDictionary::cast(result); |
| 2612 } | 2649 } |
| 2613 } | 2650 } |
| 2614 // Switch to using the dictionary as the backing storage for | 2651 // Switch to using the dictionary as the backing storage for |
| 2615 // elements. Set the new map first to satify the elements type | 2652 // elements. Set the new map first to satify the elements type |
| 2616 // assert in set_elements(). | 2653 // assert in set_elements(). |
| 2617 set_map(new_map); | 2654 set_map(new_map); |
| 2618 set_elements(dictionary); | 2655 set_elements(dictionary); |
| 2619 | 2656 |
| 2620 new_map->GetHeap()->isolate()->counters()->elements_to_dictionary()-> | 2657 new_map->heap()->isolate()->counters()->elements_to_dictionary()-> |
| 2621 Increment(); | 2658 Increment(); |
| 2622 | 2659 |
| 2623 #ifdef DEBUG | 2660 #ifdef DEBUG |
| 2624 if (FLAG_trace_normalization) { | 2661 if (FLAG_trace_normalization) { |
| 2625 PrintF("Object elements have been normalized:\n"); | 2662 PrintF("Object elements have been normalized:\n"); |
| 2626 Print(); | 2663 Print(); |
| 2627 } | 2664 } |
| 2628 #endif | 2665 #endif |
| 2629 | 2666 |
| 2630 return this; | 2667 return this; |
| 2631 } | 2668 } |
| 2632 | 2669 |
| 2633 | 2670 |
| 2634 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 2671 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, |
| 2635 DeleteMode mode) { | 2672 DeleteMode mode) { |
| 2636 // Check local property, ignore interceptor. | 2673 // Check local property, ignore interceptor. |
| 2637 Heap* heap = GetHeap(); | |
| 2638 LookupResult result; | 2674 LookupResult result; |
| 2639 LocalLookupRealNamedProperty(name, &result); | 2675 LocalLookupRealNamedProperty(name, &result); |
| 2640 if (!result.IsProperty()) return heap->true_value(); | 2676 if (!result.IsProperty()) return GetHeap()->true_value(); |
| 2641 | 2677 |
| 2642 // Normalize object if needed. | 2678 // Normalize object if needed. |
| 2643 Object* obj; | 2679 Object* obj; |
| 2644 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2680 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2645 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2681 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2646 } | 2682 } |
| 2647 | 2683 |
| 2648 return DeleteNormalizedProperty(name, mode); | 2684 return DeleteNormalizedProperty(name, mode); |
| 2649 } | 2685 } |
| 2650 | 2686 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 2676 } | 2712 } |
| 2677 MaybeObject* raw_result = | 2713 MaybeObject* raw_result = |
| 2678 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 2714 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); |
| 2679 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2715 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2680 return raw_result; | 2716 return raw_result; |
| 2681 } | 2717 } |
| 2682 | 2718 |
| 2683 | 2719 |
| 2684 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2720 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, |
| 2685 DeleteMode mode) { | 2721 DeleteMode mode) { |
| 2686 Heap* heap = GetHeap(); | |
| 2687 ASSERT(!HasExternalArrayElements()); | 2722 ASSERT(!HasExternalArrayElements()); |
| 2688 switch (GetElementsKind()) { | 2723 switch (GetElementsKind()) { |
| 2689 case FAST_ELEMENTS: { | 2724 case FAST_ELEMENTS: { |
| 2690 Object* obj; | 2725 Object* obj; |
| 2691 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 2726 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 2692 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2727 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2693 } | 2728 } |
| 2694 uint32_t length = IsJSArray() ? | 2729 uint32_t length = IsJSArray() ? |
| 2695 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2730 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2696 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2731 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2697 if (index < length) { | 2732 if (index < length) { |
| 2698 FixedArray::cast(elements())->set_the_hole(index); | 2733 FixedArray::cast(elements())->set_the_hole(index); |
| 2699 } | 2734 } |
| 2700 break; | 2735 break; |
| 2701 } | 2736 } |
| 2702 case DICTIONARY_ELEMENTS: { | 2737 case DICTIONARY_ELEMENTS: { |
| 2703 NumberDictionary* dictionary = element_dictionary(); | 2738 NumberDictionary* dictionary = element_dictionary(); |
| 2704 int entry = dictionary->FindEntry(index); | 2739 int entry = dictionary->FindEntry(index); |
| 2705 if (entry != NumberDictionary::kNotFound) { | 2740 if (entry != NumberDictionary::kNotFound) { |
| 2706 return dictionary->DeleteProperty(entry, mode); | 2741 return dictionary->DeleteProperty(entry, mode); |
| 2707 } | 2742 } |
| 2708 break; | 2743 break; |
| 2709 } | 2744 } |
| 2710 default: | 2745 default: |
| 2711 UNREACHABLE(); | 2746 UNREACHABLE(); |
| 2712 break; | 2747 break; |
| 2713 } | 2748 } |
| 2714 return heap->true_value(); | 2749 return GetHeap()->true_value(); |
| 2715 } | 2750 } |
| 2716 | 2751 |
| 2717 | 2752 |
| 2718 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2753 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
| 2719 Isolate* isolate = GetIsolate(); | 2754 Isolate* isolate = GetIsolate(); |
| 2720 Heap* heap = isolate->heap(); | 2755 Heap* heap = isolate->heap(); |
| 2721 // Make sure that the top context does not change when doing | 2756 // Make sure that the top context does not change when doing |
| 2722 // callbacks or interceptor calls. | 2757 // callbacks or interceptor calls. |
| 2723 AssertNoContextChange ncc; | 2758 AssertNoContextChange ncc; |
| 2724 HandleScope scope(isolate); | 2759 HandleScope scope(isolate); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2877 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2912 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2878 } | 2913 } |
| 2879 // Make sure the properties are normalized before removing the entry. | 2914 // Make sure the properties are normalized before removing the entry. |
| 2880 return DeleteNormalizedProperty(name, mode); | 2915 return DeleteNormalizedProperty(name, mode); |
| 2881 } | 2916 } |
| 2882 } | 2917 } |
| 2883 | 2918 |
| 2884 | 2919 |
| 2885 // Check whether this object references another object. | 2920 // Check whether this object references another object. |
| 2886 bool JSObject::ReferencesObject(Object* obj) { | 2921 bool JSObject::ReferencesObject(Object* obj) { |
| 2887 Heap* heap = GetHeap(); | 2922 Map* map_of_this = map(); |
| 2923 Heap* heap = map_of_this->heap(); | |
| 2888 AssertNoAllocation no_alloc; | 2924 AssertNoAllocation no_alloc; |
| 2889 | 2925 |
| 2890 // Is the object the constructor for this object? | 2926 // Is the object the constructor for this object? |
| 2891 if (map()->constructor() == obj) { | 2927 if (map_of_this->constructor() == obj) { |
| 2892 return true; | 2928 return true; |
| 2893 } | 2929 } |
| 2894 | 2930 |
| 2895 // Is the object the prototype for this object? | 2931 // Is the object the prototype for this object? |
| 2896 if (map()->prototype() == obj) { | 2932 if (map_of_this->prototype() == obj) { |
| 2897 return true; | 2933 return true; |
| 2898 } | 2934 } |
| 2899 | 2935 |
| 2900 // Check if the object is among the named properties. | 2936 // Check if the object is among the named properties. |
| 2901 Object* key = SlowReverseLookup(obj); | 2937 Object* key = SlowReverseLookup(obj); |
| 2902 if (!key->IsUndefined()) { | 2938 if (!key->IsUndefined()) { |
| 2903 return true; | 2939 return true; |
| 2904 } | 2940 } |
| 2905 | 2941 |
| 2906 // Check if the object is among the indexed properties. | 2942 // Check if the object is among the indexed properties. |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3496 } | 3532 } |
| 3497 } | 3533 } |
| 3498 } | 3534 } |
| 3499 } | 3535 } |
| 3500 } | 3536 } |
| 3501 return heap->undefined_value(); | 3537 return heap->undefined_value(); |
| 3502 } | 3538 } |
| 3503 | 3539 |
| 3504 | 3540 |
| 3505 Object* JSObject::SlowReverseLookup(Object* value) { | 3541 Object* JSObject::SlowReverseLookup(Object* value) { |
| 3506 Heap* heap = GetHeap(); | |
| 3507 if (HasFastProperties()) { | 3542 if (HasFastProperties()) { |
| 3508 DescriptorArray* descs = map()->instance_descriptors(); | 3543 DescriptorArray* descs = map()->instance_descriptors(); |
| 3509 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 3544 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 3510 if (descs->GetType(i) == FIELD) { | 3545 if (descs->GetType(i) == FIELD) { |
| 3511 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { | 3546 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { |
| 3512 return descs->GetKey(i); | 3547 return descs->GetKey(i); |
| 3513 } | 3548 } |
| 3514 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { | 3549 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { |
| 3515 if (descs->GetConstantFunction(i) == value) { | 3550 if (descs->GetConstantFunction(i) == value) { |
| 3516 return descs->GetKey(i); | 3551 return descs->GetKey(i); |
| 3517 } | 3552 } |
| 3518 } | 3553 } |
| 3519 } | 3554 } |
| 3520 return heap->undefined_value(); | 3555 return GetHeap()->undefined_value(); |
| 3521 } else { | 3556 } else { |
| 3522 return property_dictionary()->SlowReverseLookup(value); | 3557 return property_dictionary()->SlowReverseLookup(value); |
| 3523 } | 3558 } |
| 3524 } | 3559 } |
| 3525 | 3560 |
| 3526 | 3561 |
| 3527 MaybeObject* Map::CopyDropDescriptors() { | 3562 MaybeObject* Map::CopyDropDescriptors() { |
| 3528 Heap* heap = GetHeap(); | 3563 Heap* heap = GetHeap(); |
| 3529 Object* result; | 3564 Object* result; |
| 3530 { MaybeObject* maybe_result = | 3565 { MaybeObject* maybe_result = |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3614 } | 3649 } |
| 3615 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); | 3650 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); |
| 3616 return new_map; | 3651 return new_map; |
| 3617 } | 3652 } |
| 3618 | 3653 |
| 3619 | 3654 |
| 3620 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { | 3655 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { |
| 3621 // Allocate the code cache if not present. | 3656 // Allocate the code cache if not present. |
| 3622 if (code_cache()->IsFixedArray()) { | 3657 if (code_cache()->IsFixedArray()) { |
| 3623 Object* result; | 3658 Object* result; |
| 3624 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); | 3659 { MaybeObject* maybe_result = code->heap()->AllocateCodeCache(); |
| 3625 if (!maybe_result->ToObject(&result)) return maybe_result; | 3660 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3626 } | 3661 } |
| 3627 set_code_cache(result); | 3662 set_code_cache(result); |
| 3628 } | 3663 } |
| 3629 | 3664 |
| 3630 // Update the code cache. | 3665 // Update the code cache. |
| 3631 return CodeCache::cast(code_cache())->Update(name, code); | 3666 return CodeCache::cast(code_cache())->Update(name, code); |
| 3632 } | 3667 } |
| 3633 | 3668 |
| 3634 | 3669 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3800 Object* CodeCache::Lookup(String* name, Code::Flags flags) { | 3835 Object* CodeCache::Lookup(String* name, Code::Flags flags) { |
| 3801 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { | 3836 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { |
| 3802 return LookupNormalTypeCache(name, flags); | 3837 return LookupNormalTypeCache(name, flags); |
| 3803 } else { | 3838 } else { |
| 3804 return LookupDefaultCache(name, flags); | 3839 return LookupDefaultCache(name, flags); |
| 3805 } | 3840 } |
| 3806 } | 3841 } |
| 3807 | 3842 |
| 3808 | 3843 |
| 3809 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { | 3844 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { |
| 3810 Heap* heap = GetHeap(); | |
| 3811 FixedArray* cache = default_cache(); | 3845 FixedArray* cache = default_cache(); |
| 3812 int length = cache->length(); | 3846 int length = cache->length(); |
| 3813 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 3847 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
| 3814 Object* key = cache->get(i + kCodeCacheEntryNameOffset); | 3848 Object* key = cache->get(i + kCodeCacheEntryNameOffset); |
| 3815 // Skip deleted elements. | 3849 // Skip deleted elements. |
| 3816 if (key->IsNull()) continue; | 3850 if (key->IsNull()) continue; |
| 3817 if (key->IsUndefined()) return key; | 3851 if (key->IsUndefined()) return key; |
| 3818 if (name->Equals(String::cast(key))) { | 3852 if (name->Equals(String::cast(key))) { |
| 3819 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); | 3853 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); |
| 3820 if (code->flags() == flags) { | 3854 if (code->flags() == flags) { |
| 3821 return code; | 3855 return code; |
| 3822 } | 3856 } |
| 3823 } | 3857 } |
| 3824 } | 3858 } |
| 3825 return heap->undefined_value(); | 3859 return GetHeap()->undefined_value(); |
| 3826 } | 3860 } |
| 3827 | 3861 |
| 3828 | 3862 |
| 3829 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { | 3863 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { |
| 3830 if (!normal_type_cache()->IsUndefined()) { | 3864 if (!normal_type_cache()->IsUndefined()) { |
| 3831 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3865 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 3832 return cache->Lookup(name, flags); | 3866 return cache->Lookup(name, flags); |
| 3833 } else { | 3867 } else { |
| 3834 return GetHeap()->undefined_value(); | 3868 return GetHeap()->undefined_value(); |
| 3835 } | 3869 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3906 uint32_t HashForObject(Object* obj) { | 3940 uint32_t HashForObject(Object* obj) { |
| 3907 FixedArray* pair = FixedArray::cast(obj); | 3941 FixedArray* pair = FixedArray::cast(obj); |
| 3908 String* name = String::cast(pair->get(0)); | 3942 String* name = String::cast(pair->get(0)); |
| 3909 Code* code = Code::cast(pair->get(1)); | 3943 Code* code = Code::cast(pair->get(1)); |
| 3910 return NameFlagsHashHelper(name, code->flags()); | 3944 return NameFlagsHashHelper(name, code->flags()); |
| 3911 } | 3945 } |
| 3912 | 3946 |
| 3913 MUST_USE_RESULT MaybeObject* AsObject() { | 3947 MUST_USE_RESULT MaybeObject* AsObject() { |
| 3914 ASSERT(code_ != NULL); | 3948 ASSERT(code_ != NULL); |
| 3915 Object* obj; | 3949 Object* obj; |
| 3916 { MaybeObject* maybe_obj = code_->GetHeap()->AllocateFixedArray(2); | 3950 { MaybeObject* maybe_obj = code_->heap()->AllocateFixedArray(2); |
| 3917 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3951 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3918 } | 3952 } |
| 3919 FixedArray* pair = FixedArray::cast(obj); | 3953 FixedArray* pair = FixedArray::cast(obj); |
| 3920 pair->set(0, name_); | 3954 pair->set(0, name_); |
| 3921 pair->set(1, code_); | 3955 pair->set(1, code_); |
| 3922 return pair; | 3956 return pair; |
| 3923 } | 3957 } |
| 3924 | 3958 |
| 3925 private: | 3959 private: |
| 3926 String* name_; | 3960 String* name_; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3984 if (element->IsString() && | 4018 if (element->IsString() && |
| 3985 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 4019 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
| 3986 return true; | 4020 return true; |
| 3987 } | 4021 } |
| 3988 } | 4022 } |
| 3989 return false; | 4023 return false; |
| 3990 } | 4024 } |
| 3991 | 4025 |
| 3992 | 4026 |
| 3993 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 4027 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 3994 Heap* heap = GetHeap(); | |
| 3995 ASSERT(!array->HasExternalArrayElements()); | 4028 ASSERT(!array->HasExternalArrayElements()); |
| 3996 switch (array->GetElementsKind()) { | 4029 switch (array->GetElementsKind()) { |
| 3997 case JSObject::FAST_ELEMENTS: | 4030 case JSObject::FAST_ELEMENTS: |
| 3998 return UnionOfKeys(FixedArray::cast(array->elements())); | 4031 return UnionOfKeys(FixedArray::cast(array->elements())); |
| 3999 case JSObject::DICTIONARY_ELEMENTS: { | 4032 case JSObject::DICTIONARY_ELEMENTS: { |
| 4000 NumberDictionary* dict = array->element_dictionary(); | 4033 NumberDictionary* dict = array->element_dictionary(); |
| 4001 int size = dict->NumberOfElements(); | 4034 int size = dict->NumberOfElements(); |
| 4002 | 4035 |
| 4003 // Allocate a temporary fixed array. | 4036 // Allocate a temporary fixed array. |
| 4004 Object* object; | 4037 Object* object; |
| 4005 { MaybeObject* maybe_object = heap->AllocateFixedArray(size); | 4038 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size); |
| 4006 if (!maybe_object->ToObject(&object)) return maybe_object; | 4039 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 4007 } | 4040 } |
| 4008 FixedArray* key_array = FixedArray::cast(object); | 4041 FixedArray* key_array = FixedArray::cast(object); |
| 4009 | 4042 |
| 4010 int capacity = dict->Capacity(); | 4043 int capacity = dict->Capacity(); |
| 4011 int pos = 0; | 4044 int pos = 0; |
| 4012 // Copy the elements from the JSArray to the temporary fixed array. | 4045 // Copy the elements from the JSArray to the temporary fixed array. |
| 4013 for (int i = 0; i < capacity; i++) { | 4046 for (int i = 0; i < capacity; i++) { |
| 4014 if (dict->IsKey(dict->KeyAt(i))) { | 4047 if (dict->IsKey(dict->KeyAt(i))) { |
| 4015 key_array->set(pos++, dict->ValueAt(i)); | 4048 key_array->set(pos++, dict->ValueAt(i)); |
| 4016 } | 4049 } |
| 4017 } | 4050 } |
| 4018 // Compute the union of this and the temporary fixed array. | 4051 // Compute the union of this and the temporary fixed array. |
| 4019 return UnionOfKeys(key_array); | 4052 return UnionOfKeys(key_array); |
| 4020 } | 4053 } |
| 4021 default: | 4054 default: |
| 4022 UNREACHABLE(); | 4055 UNREACHABLE(); |
| 4023 } | 4056 } |
| 4024 UNREACHABLE(); | 4057 UNREACHABLE(); |
| 4025 return heap->null_value(); // Failure case needs to "return" a value. | 4058 return GetHeap()->null_value(); // Failure case needs to "return" a value. |
| 4026 } | 4059 } |
| 4027 | 4060 |
| 4028 | 4061 |
| 4029 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { | 4062 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| 4030 Heap* heap = GetHeap(); | |
| 4031 int len0 = length(); | 4063 int len0 = length(); |
| 4032 #ifdef DEBUG | 4064 #ifdef DEBUG |
| 4033 if (FLAG_enable_slow_asserts) { | 4065 if (FLAG_enable_slow_asserts) { |
| 4034 for (int i = 0; i < len0; i++) { | 4066 for (int i = 0; i < len0; i++) { |
| 4035 ASSERT(get(i)->IsString() || get(i)->IsNumber()); | 4067 ASSERT(get(i)->IsString() || get(i)->IsNumber()); |
| 4036 } | 4068 } |
| 4037 } | 4069 } |
| 4038 #endif | 4070 #endif |
| 4039 int len1 = other->length(); | 4071 int len1 = other->length(); |
| 4040 // Optimize if 'other' is empty. | 4072 // Optimize if 'other' is empty. |
| 4041 // We cannot optimize if 'this' is empty, as other may have holes | 4073 // We cannot optimize if 'this' is empty, as other may have holes |
| 4042 // or non keys. | 4074 // or non keys. |
| 4043 if (len1 == 0) return this; | 4075 if (len1 == 0) return this; |
| 4044 | 4076 |
| 4045 // Compute how many elements are not in this. | 4077 // Compute how many elements are not in this. |
| 4046 int extra = 0; | 4078 int extra = 0; |
| 4047 for (int y = 0; y < len1; y++) { | 4079 for (int y = 0; y < len1; y++) { |
| 4048 Object* value = other->get(y); | 4080 Object* value = other->get(y); |
| 4049 if (!value->IsTheHole() && !HasKey(this, value)) extra++; | 4081 if (!value->IsTheHole() && !HasKey(this, value)) extra++; |
| 4050 } | 4082 } |
| 4051 | 4083 |
| 4052 if (extra == 0) return this; | 4084 if (extra == 0) return this; |
| 4053 | 4085 |
| 4054 // Allocate the result | 4086 // Allocate the result |
| 4055 Object* obj; | 4087 Object* obj; |
| 4056 { MaybeObject* maybe_obj = heap->AllocateFixedArray(len0 + extra); | 4088 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); |
| 4057 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4089 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4058 } | 4090 } |
| 4059 // Fill in the content | 4091 // Fill in the content |
| 4060 AssertNoAllocation no_gc; | 4092 AssertNoAllocation no_gc; |
| 4061 FixedArray* result = FixedArray::cast(obj); | 4093 FixedArray* result = FixedArray::cast(obj); |
| 4062 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4094 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 4063 for (int i = 0; i < len0; i++) { | 4095 for (int i = 0; i < len0; i++) { |
| 4064 Object* e = get(i); | 4096 Object* e = get(i); |
| 4065 ASSERT(e->IsString() || e->IsNumber()); | 4097 ASSERT(e->IsString() || e->IsNumber()); |
| 4066 result->set(i, e, mode); | 4098 result->set(i, e, mode); |
| (...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5366 return CompareStringContentsPartial(isolate, | 5398 return CompareStringContentsPartial(isolate, |
| 5367 isolate->objects_string_compare_buffer_a(), rhs); | 5399 isolate->objects_string_compare_buffer_a(), rhs); |
| 5368 } | 5400 } |
| 5369 } | 5401 } |
| 5370 | 5402 |
| 5371 | 5403 |
| 5372 bool String::MarkAsUndetectable() { | 5404 bool String::MarkAsUndetectable() { |
| 5373 if (StringShape(this).IsSymbol()) return false; | 5405 if (StringShape(this).IsSymbol()) return false; |
| 5374 | 5406 |
| 5375 Map* map = this->map(); | 5407 Map* map = this->map(); |
| 5376 Heap* heap = map->GetHeap(); | 5408 Heap* heap = map->heap(); |
| 5377 if (map == heap->string_map()) { | 5409 if (map == heap->string_map()) { |
| 5378 this->set_map(heap->undetectable_string_map()); | 5410 this->set_map(heap->undetectable_string_map()); |
| 5379 return true; | 5411 return true; |
| 5380 } else if (map == heap->ascii_string_map()) { | 5412 } else if (map == heap->ascii_string_map()) { |
| 5381 this->set_map(heap->undetectable_ascii_string_map()); | 5413 this->set_map(heap->undetectable_ascii_string_map()); |
| 5382 return true; | 5414 return true; |
| 5383 } | 5415 } |
| 5384 // Rest cannot be marked as undetectable | 5416 // Rest cannot be marked as undetectable |
| 5385 return false; | 5417 return false; |
| 5386 } | 5418 } |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5695 | 5727 |
| 5696 MaybeObject* JSFunction::SetPrototype(Object* value) { | 5728 MaybeObject* JSFunction::SetPrototype(Object* value) { |
| 5697 ASSERT(should_have_prototype()); | 5729 ASSERT(should_have_prototype()); |
| 5698 Object* construct_prototype = value; | 5730 Object* construct_prototype = value; |
| 5699 | 5731 |
| 5700 // If the value is not a JSObject, store the value in the map's | 5732 // If the value is not a JSObject, store the value in the map's |
| 5701 // constructor field so it can be accessed. Also, set the prototype | 5733 // constructor field so it can be accessed. Also, set the prototype |
| 5702 // used for constructing objects to the original object prototype. | 5734 // used for constructing objects to the original object prototype. |
| 5703 // See ECMA-262 13.2.2. | 5735 // See ECMA-262 13.2.2. |
| 5704 if (!value->IsJSObject()) { | 5736 if (!value->IsJSObject()) { |
| 5705 Heap* heap = GetHeap(); | |
| 5706 // Copy the map so this does not affect unrelated functions. | 5737 // Copy the map so this does not affect unrelated functions. |
| 5707 // Remove map transitions because they point to maps with a | 5738 // Remove map transitions because they point to maps with a |
| 5708 // different prototype. | 5739 // different prototype. |
| 5709 Object* new_map; | 5740 Object* new_object; |
| 5710 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); | 5741 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); |
| 5711 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 5742 if (!maybe_new_map->ToObject(&new_object)) return maybe_new_map; |
| 5712 } | 5743 } |
| 5713 set_map(Map::cast(new_map)); | 5744 Map* new_map = Map::cast(new_object); |
| 5714 map()->set_constructor(value); | 5745 Heap* heap = new_map->heap(); |
| 5715 map()->set_non_instance_prototype(true); | 5746 set_map(new_map); |
| 5747 new_map->set_constructor(value); | |
| 5748 new_map->set_non_instance_prototype(true); | |
| 5716 construct_prototype = | 5749 construct_prototype = |
| 5717 heap->isolate()->context()->global_context()-> | 5750 heap->isolate()->context()->global_context()-> |
| 5718 initial_object_prototype(); | 5751 initial_object_prototype(); |
| 5719 } else { | 5752 } else { |
| 5720 map()->set_non_instance_prototype(false); | 5753 map()->set_non_instance_prototype(false); |
| 5721 } | 5754 } |
| 5722 | 5755 |
| 5723 return SetInstancePrototype(construct_prototype); | 5756 return SetInstancePrototype(construct_prototype); |
| 5724 } | 5757 } |
| 5725 | 5758 |
| 5726 | 5759 |
| 5727 Object* JSFunction::RemovePrototype() { | 5760 Object* JSFunction::RemovePrototype() { |
| 5728 Context* global_context = context()->global_context(); | 5761 Context* global_context = context()->global_context(); |
| 5729 Map* no_prototype_map = shared()->strict_mode() | 5762 Map* no_prototype_map = shared()->strict_mode() |
| 5730 ? global_context->strict_mode_function_without_prototype_map() | 5763 ? global_context->strict_mode_function_without_prototype_map() |
| 5731 : global_context->function_without_prototype_map(); | 5764 : global_context->function_without_prototype_map(); |
| 5732 | 5765 |
| 5733 if (map() == no_prototype_map) { | 5766 if (map() == no_prototype_map) { |
| 5734 // Be idempotent. | 5767 // Be idempotent. |
| 5735 return this; | 5768 return this; |
| 5736 } | 5769 } |
| 5737 | 5770 |
| 5738 ASSERT(!shared()->strict_mode() || | 5771 ASSERT(!shared()->strict_mode() || |
| 5739 map() == global_context->strict_mode_function_map()); | 5772 map() == global_context->strict_mode_function_map()); |
| 5740 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); | 5773 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); |
| 5741 | 5774 |
| 5742 set_map(no_prototype_map); | 5775 set_map(no_prototype_map); |
| 5743 set_prototype_or_initial_map(GetHeap()->the_hole_value()); | 5776 set_prototype_or_initial_map(no_prototype_map->heap()->the_hole_value()); |
| 5744 return this; | 5777 return this; |
| 5745 } | 5778 } |
| 5746 | 5779 |
| 5747 | 5780 |
| 5748 Object* JSFunction::SetInstanceClassName(String* name) { | 5781 Object* JSFunction::SetInstanceClassName(String* name) { |
| 5749 shared()->set_instance_class_name(name); | 5782 shared()->set_instance_class_name(name); |
| 5750 return this; | 5783 return this; |
| 5751 } | 5784 } |
| 5752 | 5785 |
| 5753 | 5786 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5815 return instance_size; | 5848 return instance_size; |
| 5816 } | 5849 } |
| 5817 | 5850 |
| 5818 | 5851 |
| 5819 int SharedFunctionInfo::CalculateInObjectProperties() { | 5852 int SharedFunctionInfo::CalculateInObjectProperties() { |
| 5820 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; | 5853 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
| 5821 } | 5854 } |
| 5822 | 5855 |
| 5823 | 5856 |
| 5824 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { | 5857 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { |
| 5825 Heap* heap = GetHeap(); | |
| 5826 | |
| 5827 // Check the basic conditions for generating inline constructor code. | 5858 // Check the basic conditions for generating inline constructor code. |
| 5828 if (!FLAG_inline_new | 5859 if (!FLAG_inline_new |
| 5829 || !has_only_simple_this_property_assignments() | 5860 || !has_only_simple_this_property_assignments() |
| 5830 || this_property_assignments_count() == 0) { | 5861 || this_property_assignments_count() == 0) { |
| 5831 return false; | 5862 return false; |
| 5832 } | 5863 } |
| 5833 | 5864 |
| 5834 // If the prototype is null inline constructors cause no problems. | 5865 // If the prototype is null inline constructors cause no problems. |
| 5835 if (!prototype->IsJSObject()) { | 5866 if (!prototype->IsJSObject()) { |
| 5836 ASSERT(prototype->IsNull()); | 5867 ASSERT(prototype->IsNull()); |
| 5837 return true; | 5868 return true; |
| 5838 } | 5869 } |
| 5839 | 5870 |
| 5871 Heap* heap = GetHeap(); | |
| 5872 | |
| 5840 // Traverse the proposed prototype chain looking for setters for properties of | 5873 // Traverse the proposed prototype chain looking for setters for properties of |
| 5841 // the same names as are set by the inline constructor. | 5874 // the same names as are set by the inline constructor. |
| 5842 for (Object* obj = prototype; | 5875 for (Object* obj = prototype; |
| 5843 obj != heap->null_value(); | 5876 obj != heap->null_value(); |
| 5844 obj = obj->GetPrototype()) { | 5877 obj = obj->GetPrototype()) { |
| 5845 JSObject* js_object = JSObject::cast(obj); | 5878 JSObject* js_object = JSObject::cast(obj); |
| 5846 for (int i = 0; i < this_property_assignments_count(); i++) { | 5879 for (int i = 0; i < this_property_assignments_count(); i++) { |
| 5847 LookupResult result; | 5880 LookupResult result; |
| 5848 String* name = GetThisPropertyAssignmentName(i); | 5881 String* name = GetThisPropertyAssignmentName(i); |
| 5849 js_object->LocalLookupRealNamedProperty(name, &result); | 5882 js_object->LocalLookupRealNamedProperty(name, &result); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6149 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 6182 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
| 6150 rinfo->IsPatchedDebugBreakSlotSequence())); | 6183 rinfo->IsPatchedDebugBreakSlotSequence())); |
| 6151 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 6184 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
| 6152 Object* old_target = target; | 6185 Object* old_target = target; |
| 6153 VisitPointer(&target); | 6186 VisitPointer(&target); |
| 6154 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 6187 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
| 6155 } | 6188 } |
| 6156 | 6189 |
| 6157 | 6190 |
| 6158 void Code::InvalidateRelocation() { | 6191 void Code::InvalidateRelocation() { |
| 6159 set_relocation_info(GetHeap()->empty_byte_array()); | 6192 set_relocation_info(heap()->empty_byte_array()); |
| 6160 } | 6193 } |
| 6161 | 6194 |
| 6162 | 6195 |
| 6163 void Code::Relocate(intptr_t delta) { | 6196 void Code::Relocate(intptr_t delta) { |
| 6164 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 6197 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
| 6165 it.rinfo()->apply(delta); | 6198 it.rinfo()->apply(delta); |
| 6166 } | 6199 } |
| 6167 CPU::FlushICache(instruction_start(), instruction_size()); | 6200 CPU::FlushICache(instruction_start(), instruction_size()); |
| 6168 } | 6201 } |
| 6169 | 6202 |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6727 | 6760 |
| 6728 static Failure* ArrayLengthRangeError(Heap* heap) { | 6761 static Failure* ArrayLengthRangeError(Heap* heap) { |
| 6729 HandleScope scope; | 6762 HandleScope scope; |
| 6730 return heap->isolate()->Throw( | 6763 return heap->isolate()->Throw( |
| 6731 *FACTORY->NewRangeError("invalid_array_length", | 6764 *FACTORY->NewRangeError("invalid_array_length", |
| 6732 HandleVector<Object>(NULL, 0))); | 6765 HandleVector<Object>(NULL, 0))); |
| 6733 } | 6766 } |
| 6734 | 6767 |
| 6735 | 6768 |
| 6736 MaybeObject* JSObject::SetElementsLength(Object* len) { | 6769 MaybeObject* JSObject::SetElementsLength(Object* len) { |
| 6737 Heap* heap = GetHeap(); | |
| 6738 // We should never end in here with a pixel or external array. | 6770 // We should never end in here with a pixel or external array. |
| 6739 ASSERT(AllowsSetElementsLength()); | 6771 ASSERT(AllowsSetElementsLength()); |
| 6740 | 6772 |
| 6741 MaybeObject* maybe_smi_length = len->ToSmi(); | 6773 MaybeObject* maybe_smi_length = len->ToSmi(); |
| 6742 Object* smi_length = Smi::FromInt(0); | 6774 Object* smi_length = Smi::FromInt(0); |
| 6743 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { | 6775 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
| 6744 const int value = Smi::cast(smi_length)->value(); | 6776 const int value = Smi::cast(smi_length)->value(); |
| 6745 if (value < 0) return ArrayLengthRangeError(heap); | 6777 if (value < 0) return ArrayLengthRangeError(GetHeap()); |
| 6746 switch (GetElementsKind()) { | 6778 switch (GetElementsKind()) { |
| 6747 case FAST_ELEMENTS: { | 6779 case FAST_ELEMENTS: { |
| 6748 int old_capacity = FixedArray::cast(elements())->length(); | 6780 int old_capacity = FixedArray::cast(elements())->length(); |
| 6749 if (value <= old_capacity) { | 6781 if (value <= old_capacity) { |
| 6750 if (IsJSArray()) { | 6782 if (IsJSArray()) { |
| 6751 Object* obj; | 6783 Object* obj; |
| 6752 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 6784 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 6753 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6785 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6754 } | 6786 } |
| 6755 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 6787 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6801 break; | 6833 break; |
| 6802 } | 6834 } |
| 6803 } | 6835 } |
| 6804 | 6836 |
| 6805 // General slow case. | 6837 // General slow case. |
| 6806 if (len->IsNumber()) { | 6838 if (len->IsNumber()) { |
| 6807 uint32_t length; | 6839 uint32_t length; |
| 6808 if (len->ToArrayIndex(&length)) { | 6840 if (len->ToArrayIndex(&length)) { |
| 6809 return SetSlowElements(len); | 6841 return SetSlowElements(len); |
| 6810 } else { | 6842 } else { |
| 6811 return ArrayLengthRangeError(heap); | 6843 return ArrayLengthRangeError(GetHeap()); |
| 6812 } | 6844 } |
| 6813 } | 6845 } |
| 6814 | 6846 |
| 6815 // len is not a number so make the array size one and | 6847 // len is not a number so make the array size one and |
| 6816 // set only element to len. | 6848 // set only element to len. |
| 6817 Object* obj; | 6849 Object* obj; |
| 6818 { MaybeObject* maybe_obj = heap->AllocateFixedArray(1); | 6850 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); |
| 6819 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6851 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6820 } | 6852 } |
| 6821 FixedArray::cast(obj)->set(0, len); | 6853 FixedArray::cast(obj)->set(0, len); |
| 6822 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 6854 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); |
| 6823 set_elements(FixedArray::cast(obj)); | 6855 set_elements(FixedArray::cast(obj)); |
| 6824 return this; | 6856 return this; |
| 6825 } | 6857 } |
| 6826 | 6858 |
| 6827 | 6859 |
| 6828 MaybeObject* JSObject::SetPrototype(Object* value, | 6860 MaybeObject* JSObject::SetPrototype(Object* value, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6963 VMState state(isolate, EXTERNAL); | 6995 VMState state(isolate, EXTERNAL); |
| 6964 result = getter(index, info); | 6996 result = getter(index, info); |
| 6965 } | 6997 } |
| 6966 if (!result.IsEmpty()) return true; | 6998 if (!result.IsEmpty()) return true; |
| 6967 } | 6999 } |
| 6968 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); | 7000 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); |
| 6969 } | 7001 } |
| 6970 | 7002 |
| 6971 | 7003 |
| 6972 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { | 7004 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { |
| 6973 Heap* heap = GetHeap(); | |
| 6974 | 7005 |
| 6975 // Check access rights if needed. | 7006 // Check access rights if needed. |
| 6976 if (IsAccessCheckNeeded() && | 7007 if (IsAccessCheckNeeded()) { |
| 6977 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7008 Heap* heap = GetHeap(); |
| 6978 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7009 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 6979 return UNDEFINED_ELEMENT; | 7010 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 7011 return UNDEFINED_ELEMENT; | |
| 7012 } | |
| 6980 } | 7013 } |
| 6981 | 7014 |
| 6982 if (IsJSGlobalProxy()) { | 7015 if (IsJSGlobalProxy()) { |
| 6983 Object* proto = GetPrototype(); | 7016 Object* proto = GetPrototype(); |
| 6984 if (proto->IsNull()) return UNDEFINED_ELEMENT; | 7017 if (proto->IsNull()) return UNDEFINED_ELEMENT; |
| 6985 ASSERT(proto->IsJSGlobalObject()); | 7018 ASSERT(proto->IsJSGlobalObject()); |
| 6986 return JSObject::cast(proto)->HasLocalElement(index); | 7019 return JSObject::cast(proto)->HasLocalElement(index); |
| 6987 } | 7020 } |
| 6988 | 7021 |
| 6989 // Check for lookup interceptor | 7022 // Check for lookup interceptor |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7035 default: | 7068 default: |
| 7036 UNREACHABLE(); | 7069 UNREACHABLE(); |
| 7037 break; | 7070 break; |
| 7038 } | 7071 } |
| 7039 | 7072 |
| 7040 return UNDEFINED_ELEMENT; | 7073 return UNDEFINED_ELEMENT; |
| 7041 } | 7074 } |
| 7042 | 7075 |
| 7043 | 7076 |
| 7044 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 7077 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 7045 Heap* heap = GetHeap(); | |
| 7046 | |
| 7047 // Check access rights if needed. | 7078 // Check access rights if needed. |
| 7048 if (IsAccessCheckNeeded() && | 7079 if (IsAccessCheckNeeded()) { |
| 7049 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7080 Heap* heap = GetHeap(); |
| 7050 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7081 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 7051 return false; | 7082 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 7083 return false; | |
| 7084 } | |
| 7052 } | 7085 } |
| 7053 | 7086 |
| 7054 // Check for lookup interceptor | 7087 // Check for lookup interceptor |
| 7055 if (HasIndexedInterceptor()) { | 7088 if (HasIndexedInterceptor()) { |
| 7056 return HasElementWithInterceptor(receiver, index); | 7089 return HasElementWithInterceptor(receiver, index); |
| 7057 } | 7090 } |
| 7058 | 7091 |
| 7059 switch (GetElementsKind()) { | 7092 switch (GetElementsKind()) { |
| 7060 case FAST_ELEMENTS: { | 7093 case FAST_ELEMENTS: { |
| 7061 uint32_t length = IsJSArray() ? | 7094 uint32_t length = IsJSArray() ? |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7313 } | 7346 } |
| 7314 ASSERT(HasDictionaryElements()); | 7347 ASSERT(HasDictionaryElements()); |
| 7315 return SetElement(index, value, strict_mode, check_prototype); | 7348 return SetElement(index, value, strict_mode, check_prototype); |
| 7316 } | 7349 } |
| 7317 | 7350 |
| 7318 | 7351 |
| 7319 MaybeObject* JSObject::SetElement(uint32_t index, | 7352 MaybeObject* JSObject::SetElement(uint32_t index, |
| 7320 Object* value, | 7353 Object* value, |
| 7321 StrictModeFlag strict_mode, | 7354 StrictModeFlag strict_mode, |
| 7322 bool check_prototype) { | 7355 bool check_prototype) { |
| 7323 Heap* heap = GetHeap(); | |
| 7324 // Check access rights if needed. | 7356 // Check access rights if needed. |
| 7325 if (IsAccessCheckNeeded() && | 7357 if (IsAccessCheckNeeded()) { |
| 7326 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7358 Heap* heap = GetHeap(); |
| 7327 HandleScope scope; | 7359 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 7328 Handle<Object> value_handle(value); | 7360 HandleScope scope; |
| 7329 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7361 Handle<Object> value_handle(value); |
| 7330 return *value_handle; | 7362 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 7363 return *value_handle; | |
| 7364 } | |
| 7331 } | 7365 } |
| 7332 | 7366 |
| 7333 if (IsJSGlobalProxy()) { | 7367 if (IsJSGlobalProxy()) { |
| 7334 Object* proto = GetPrototype(); | 7368 Object* proto = GetPrototype(); |
| 7335 if (proto->IsNull()) return value; | 7369 if (proto->IsNull()) return value; |
| 7336 ASSERT(proto->IsJSGlobalObject()); | 7370 ASSERT(proto->IsJSGlobalObject()); |
| 7337 return JSObject::cast(proto)->SetElement(index, | 7371 return JSObject::cast(proto)->SetElement(index, |
| 7338 value, | 7372 value, |
| 7339 strict_mode, | 7373 strict_mode, |
| 7340 check_prototype); | 7374 check_prototype); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7515 if (!maybe_len->ToObject(&len)) return maybe_len; | 7549 if (!maybe_len->ToObject(&len)) return maybe_len; |
| 7516 } | 7550 } |
| 7517 set_length(len); | 7551 set_length(len); |
| 7518 } | 7552 } |
| 7519 return value; | 7553 return value; |
| 7520 } | 7554 } |
| 7521 | 7555 |
| 7522 | 7556 |
| 7523 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, | 7557 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, |
| 7524 uint32_t index) { | 7558 uint32_t index) { |
| 7525 Heap* heap = GetHeap(); | |
| 7526 // Get element works for both JSObject and JSArray since | 7559 // Get element works for both JSObject and JSArray since |
| 7527 // JSArray::length cannot change. | 7560 // JSArray::length cannot change. |
| 7528 switch (GetElementsKind()) { | 7561 switch (GetElementsKind()) { |
| 7529 case FAST_ELEMENTS: { | 7562 case FAST_ELEMENTS: { |
| 7530 FixedArray* elms = FixedArray::cast(elements()); | 7563 FixedArray* elms = FixedArray::cast(elements()); |
| 7531 if (index < static_cast<uint32_t>(elms->length())) { | 7564 if (index < static_cast<uint32_t>(elms->length())) { |
| 7532 Object* value = elms->get(index); | 7565 Object* value = elms->get(index); |
| 7533 if (!value->IsTheHole()) return value; | 7566 if (!value->IsTheHole()) return value; |
| 7534 } | 7567 } |
| 7535 break; | 7568 break; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 7564 } | 7597 } |
| 7565 break; | 7598 break; |
| 7566 } | 7599 } |
| 7567 default: | 7600 default: |
| 7568 UNREACHABLE(); | 7601 UNREACHABLE(); |
| 7569 break; | 7602 break; |
| 7570 } | 7603 } |
| 7571 | 7604 |
| 7572 // Continue searching via the prototype chain. | 7605 // Continue searching via the prototype chain. |
| 7573 Object* pt = GetPrototype(); | 7606 Object* pt = GetPrototype(); |
| 7574 if (pt->IsNull()) return heap->undefined_value(); | 7607 if (pt->IsNull()) return GetHeap()->undefined_value(); |
| 7575 return pt->GetElementWithReceiver(receiver, index); | 7608 return pt->GetElementWithReceiver(receiver, index); |
| 7576 } | 7609 } |
| 7577 | 7610 |
| 7578 | 7611 |
| 7579 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, | 7612 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
| 7580 uint32_t index) { | 7613 uint32_t index) { |
| 7581 Isolate* isolate = GetIsolate(); | 7614 Isolate* isolate = GetIsolate(); |
| 7582 // Make sure that the top context does not change when doing | 7615 // Make sure that the top context does not change when doing |
| 7583 // callbacks or interceptor calls. | 7616 // callbacks or interceptor calls. |
| 7584 AssertNoContextChange ncc; | 7617 AssertNoContextChange ncc; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 7606 | 7639 |
| 7607 MaybeObject* raw_result = | 7640 MaybeObject* raw_result = |
| 7608 holder_handle->GetElementPostInterceptor(*this_handle, index); | 7641 holder_handle->GetElementPostInterceptor(*this_handle, index); |
| 7609 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7642 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7610 return raw_result; | 7643 return raw_result; |
| 7611 } | 7644 } |
| 7612 | 7645 |
| 7613 | 7646 |
| 7614 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, | 7647 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, |
| 7615 uint32_t index) { | 7648 uint32_t index) { |
| 7616 Heap* heap = GetHeap(); | |
| 7617 // Check access rights if needed. | 7649 // Check access rights if needed. |
| 7618 if (IsAccessCheckNeeded() && | 7650 if (IsAccessCheckNeeded()) { |
| 7619 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 7651 Heap* heap = GetHeap(); |
| 7620 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 7652 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
| 7621 return heap->undefined_value(); | 7653 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 7654 return heap->undefined_value(); | |
| 7655 } | |
| 7622 } | 7656 } |
| 7623 | 7657 |
| 7624 if (HasIndexedInterceptor()) { | 7658 if (HasIndexedInterceptor()) { |
| 7625 return GetElementWithInterceptor(receiver, index); | 7659 return GetElementWithInterceptor(receiver, index); |
| 7626 } | 7660 } |
| 7627 | 7661 |
| 7628 // Get element works for both JSObject and JSArray since | 7662 // Get element works for both JSObject and JSArray since |
| 7629 // JSArray::length cannot change. | 7663 // JSArray::length cannot change. |
| 7630 switch (GetElementsKind()) { | 7664 switch (GetElementsKind()) { |
| 7631 case FAST_ELEMENTS: { | 7665 case FAST_ELEMENTS: { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 7662 index, | 7696 index, |
| 7663 this); | 7697 this); |
| 7664 } | 7698 } |
| 7665 return element; | 7699 return element; |
| 7666 } | 7700 } |
| 7667 break; | 7701 break; |
| 7668 } | 7702 } |
| 7669 } | 7703 } |
| 7670 | 7704 |
| 7671 Object* pt = GetPrototype(); | 7705 Object* pt = GetPrototype(); |
| 7706 Heap* heap = GetHeap(); | |
| 7672 if (pt == heap->null_value()) return heap->undefined_value(); | 7707 if (pt == heap->null_value()) return heap->undefined_value(); |
| 7673 return pt->GetElementWithReceiver(receiver, index); | 7708 return pt->GetElementWithReceiver(receiver, index); |
| 7674 } | 7709 } |
| 7675 | 7710 |
| 7676 | 7711 |
| 7677 MaybeObject* JSObject::GetExternalElement(uint32_t index) { | 7712 MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
| 7678 // Get element works for both JSObject and JSArray since | 7713 // Get element works for both JSObject and JSArray since |
| 7679 // JSArray::length cannot change. | 7714 // JSArray::length cannot change. |
| 7680 switch (GetElementsKind()) { | 7715 switch (GetElementsKind()) { |
| 7681 case EXTERNAL_PIXEL_ELEMENTS: { | 7716 case EXTERNAL_PIXEL_ELEMENTS: { |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7888 Object* result = | 7923 Object* result = |
| 7889 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 7924 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 7890 return InterceptorInfo::cast(result); | 7925 return InterceptorInfo::cast(result); |
| 7891 } | 7926 } |
| 7892 | 7927 |
| 7893 | 7928 |
| 7894 MaybeObject* JSObject::GetPropertyPostInterceptor( | 7929 MaybeObject* JSObject::GetPropertyPostInterceptor( |
| 7895 JSObject* receiver, | 7930 JSObject* receiver, |
| 7896 String* name, | 7931 String* name, |
| 7897 PropertyAttributes* attributes) { | 7932 PropertyAttributes* attributes) { |
| 7898 Heap* heap = GetHeap(); | |
| 7899 // Check local property in holder, ignore interceptor. | 7933 // Check local property in holder, ignore interceptor. |
| 7900 LookupResult result; | 7934 LookupResult result; |
| 7901 LocalLookupRealNamedProperty(name, &result); | 7935 LocalLookupRealNamedProperty(name, &result); |
| 7902 if (result.IsProperty()) { | 7936 if (result.IsProperty()) { |
| 7903 return GetProperty(receiver, &result, name, attributes); | 7937 return GetProperty(receiver, &result, name, attributes); |
| 7904 } | 7938 } |
| 7905 // Continue searching via the prototype chain. | 7939 // Continue searching via the prototype chain. |
| 7906 Object* pt = GetPrototype(); | 7940 Object* pt = GetPrototype(); |
| 7907 *attributes = ABSENT; | 7941 *attributes = ABSENT; |
| 7908 if (pt->IsNull()) return heap->undefined_value(); | 7942 if (pt->IsNull()) return GetHeap()->undefined_value(); |
| 7909 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 7943 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
| 7910 } | 7944 } |
| 7911 | 7945 |
| 7912 | 7946 |
| 7913 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( | 7947 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
| 7914 JSObject* receiver, | 7948 JSObject* receiver, |
| 7915 String* name, | 7949 String* name, |
| 7916 PropertyAttributes* attributes) { | 7950 PropertyAttributes* attributes) { |
| 7917 Heap* heap = GetHeap(); | |
| 7918 // Check local property in holder, ignore interceptor. | 7951 // Check local property in holder, ignore interceptor. |
| 7919 LookupResult result; | 7952 LookupResult result; |
| 7920 LocalLookupRealNamedProperty(name, &result); | 7953 LocalLookupRealNamedProperty(name, &result); |
| 7921 if (result.IsProperty()) { | 7954 if (result.IsProperty()) { |
| 7922 return GetProperty(receiver, &result, name, attributes); | 7955 return GetProperty(receiver, &result, name, attributes); |
| 7923 } | 7956 } |
| 7924 return heap->undefined_value(); | 7957 return GetHeap()->undefined_value(); |
| 7925 } | 7958 } |
| 7926 | 7959 |
| 7927 | 7960 |
| 7928 MaybeObject* JSObject::GetPropertyWithInterceptor( | 7961 MaybeObject* JSObject::GetPropertyWithInterceptor( |
| 7929 JSObject* receiver, | 7962 JSObject* receiver, |
| 7930 String* name, | 7963 String* name, |
| 7931 PropertyAttributes* attributes) { | 7964 PropertyAttributes* attributes) { |
| 7932 Isolate* isolate = GetIsolate(); | 7965 Isolate* isolate = GetIsolate(); |
| 7933 InterceptorInfo* interceptor = GetNamedInterceptor(); | 7966 InterceptorInfo* interceptor = GetNamedInterceptor(); |
| 7934 HandleScope scope(isolate); | 7967 HandleScope scope(isolate); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 7959 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( | 7992 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( |
| 7960 *receiver_handle, | 7993 *receiver_handle, |
| 7961 *name_handle, | 7994 *name_handle, |
| 7962 attributes); | 7995 attributes); |
| 7963 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7996 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7964 return result; | 7997 return result; |
| 7965 } | 7998 } |
| 7966 | 7999 |
| 7967 | 8000 |
| 7968 bool JSObject::HasRealNamedProperty(String* key) { | 8001 bool JSObject::HasRealNamedProperty(String* key) { |
| 7969 Heap* heap = GetHeap(); | |
| 7970 // Check access rights if needed. | 8002 // Check access rights if needed. |
| 7971 if (IsAccessCheckNeeded() && | 8003 if (IsAccessCheckNeeded()) { |
| 7972 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 8004 Heap* heap = GetHeap(); |
| 7973 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8005 if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 7974 return false; | 8006 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 8007 return false; | |
| 8008 } | |
| 7975 } | 8009 } |
| 7976 | 8010 |
| 7977 LookupResult result; | 8011 LookupResult result; |
| 7978 LocalLookupRealNamedProperty(key, &result); | 8012 LocalLookupRealNamedProperty(key, &result); |
| 7979 return result.IsProperty() && (result.type() != INTERCEPTOR); | 8013 return result.IsProperty() && (result.type() != INTERCEPTOR); |
| 7980 } | 8014 } |
| 7981 | 8015 |
| 7982 | 8016 |
| 7983 bool JSObject::HasRealElementProperty(uint32_t index) { | 8017 bool JSObject::HasRealElementProperty(uint32_t index) { |
| 7984 Heap* heap = GetHeap(); | |
| 7985 // Check access rights if needed. | 8018 // Check access rights if needed. |
| 7986 if (IsAccessCheckNeeded() && | 8019 if (IsAccessCheckNeeded()) { |
| 7987 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 8020 Heap* heap = GetHeap(); |
| 7988 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8021 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 7989 return false; | 8022 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 8023 return false; | |
| 8024 } | |
| 7990 } | 8025 } |
| 7991 | 8026 |
| 7992 // Handle [] on String objects. | 8027 // Handle [] on String objects. |
| 7993 if (this->IsStringObjectWithCharacterAt(index)) return true; | 8028 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 7994 | 8029 |
| 7995 switch (GetElementsKind()) { | 8030 switch (GetElementsKind()) { |
| 7996 case FAST_ELEMENTS: { | 8031 case FAST_ELEMENTS: { |
| 7997 uint32_t length = IsJSArray() ? | 8032 uint32_t length = IsJSArray() ? |
| 7998 static_cast<uint32_t>( | 8033 static_cast<uint32_t>( |
| 7999 Smi::cast(JSArray::cast(this)->length())->value()) : | 8034 Smi::cast(JSArray::cast(this)->length())->value()) : |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 8018 case DICTIONARY_ELEMENTS: { | 8053 case DICTIONARY_ELEMENTS: { |
| 8019 return element_dictionary()->FindEntry(index) | 8054 return element_dictionary()->FindEntry(index) |
| 8020 != NumberDictionary::kNotFound; | 8055 != NumberDictionary::kNotFound; |
| 8021 } | 8056 } |
| 8022 default: | 8057 default: |
| 8023 UNREACHABLE(); | 8058 UNREACHABLE(); |
| 8024 break; | 8059 break; |
| 8025 } | 8060 } |
| 8026 // All possibilities have been handled above already. | 8061 // All possibilities have been handled above already. |
| 8027 UNREACHABLE(); | 8062 UNREACHABLE(); |
| 8028 return heap->null_value(); | 8063 return GetHeap()->null_value(); |
| 8029 } | 8064 } |
| 8030 | 8065 |
| 8031 | 8066 |
| 8032 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 8067 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 8033 Heap* heap = GetHeap(); | |
| 8034 // Check access rights if needed. | 8068 // Check access rights if needed. |
| 8035 if (IsAccessCheckNeeded() && | 8069 if (IsAccessCheckNeeded()) { |
| 8036 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 8070 Heap* heap = GetHeap(); |
| 8037 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8071 if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 8038 return false; | 8072 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 8073 return false; | |
| 8074 } | |
| 8039 } | 8075 } |
| 8040 | 8076 |
| 8041 LookupResult result; | 8077 LookupResult result; |
| 8042 LocalLookupRealNamedProperty(key, &result); | 8078 LocalLookupRealNamedProperty(key, &result); |
| 8043 return result.IsProperty() && (result.type() == CALLBACKS); | 8079 return result.IsProperty() && (result.type() == CALLBACKS); |
| 8044 } | 8080 } |
| 8045 | 8081 |
| 8046 | 8082 |
| 8047 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 8083 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
| 8048 if (HasFastProperties()) { | 8084 if (HasFastProperties()) { |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8667 } | 8703 } |
| 8668 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); | 8704 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); |
| 8669 entry = NextProbe(entry, count++, capacity); | 8705 entry = NextProbe(entry, count++, capacity); |
| 8670 } | 8706 } |
| 8671 return kNotFound; | 8707 return kNotFound; |
| 8672 } | 8708 } |
| 8673 | 8709 |
| 8674 | 8710 |
| 8675 template<typename Shape, typename Key> | 8711 template<typename Shape, typename Key> |
| 8676 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 8712 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
| 8677 Heap* heap = GetHeap(); | |
| 8678 int capacity = Capacity(); | 8713 int capacity = Capacity(); |
| 8679 int nof = NumberOfElements() + n; | 8714 int nof = NumberOfElements() + n; |
| 8680 int nod = NumberOfDeletedElements(); | 8715 int nod = NumberOfDeletedElements(); |
| 8681 // Return if: | 8716 // Return if: |
| 8682 // 50% is still free after adding n elements and | 8717 // 50% is still free after adding n elements and |
| 8683 // at most 50% of the free elements are deleted elements. | 8718 // at most 50% of the free elements are deleted elements. |
| 8684 if (nod <= (capacity - nof) >> 1) { | 8719 if (nod <= (capacity - nof) >> 1) { |
| 8685 int needed_free = nof >> 1; | 8720 int needed_free = nof >> 1; |
| 8686 if (nof + needed_free <= capacity) return this; | 8721 if (nof + needed_free <= capacity) return this; |
| 8687 } | 8722 } |
| 8688 | 8723 |
| 8689 const int kMinCapacityForPretenure = 256; | 8724 const int kMinCapacityForPretenure = 256; |
| 8690 bool pretenure = | 8725 bool pretenure = |
| 8691 (capacity > kMinCapacityForPretenure) && !heap->InNewSpace(this); | 8726 (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this); |
| 8692 Object* obj; | 8727 Object* obj; |
| 8693 { MaybeObject* maybe_obj = | 8728 { MaybeObject* maybe_obj = |
| 8694 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); | 8729 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); |
| 8695 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8730 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8696 } | 8731 } |
| 8697 | 8732 |
| 8698 AssertNoAllocation no_gc; | 8733 AssertNoAllocation no_gc; |
| 8699 HashTable* table = HashTable::cast(obj); | 8734 HashTable* table = HashTable::cast(obj); |
| 8700 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); | 8735 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); |
| 8701 | 8736 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8813 template | 8848 template |
| 8814 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 8849 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
| 8815 | 8850 |
| 8816 template | 8851 template |
| 8817 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 8852 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
| 8818 | 8853 |
| 8819 | 8854 |
| 8820 // Collates undefined and unexisting elements below limit from position | 8855 // Collates undefined and unexisting elements below limit from position |
| 8821 // zero of the elements. The object stays in Dictionary mode. | 8856 // zero of the elements. The object stays in Dictionary mode. |
| 8822 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 8857 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 8823 Heap* heap = GetHeap(); | |
| 8824 ASSERT(HasDictionaryElements()); | 8858 ASSERT(HasDictionaryElements()); |
| 8825 // Must stay in dictionary mode, either because of requires_slow_elements, | 8859 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 8826 // or because we are not going to sort (and therefore compact) all of the | 8860 // or because we are not going to sort (and therefore compact) all of the |
| 8827 // elements. | 8861 // elements. |
| 8828 NumberDictionary* dict = element_dictionary(); | 8862 NumberDictionary* dict = element_dictionary(); |
| 8829 HeapNumber* result_double = NULL; | 8863 HeapNumber* result_double = NULL; |
| 8830 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 8864 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 8831 // Allocate space for result before we start mutating the object. | 8865 // Allocate space for result before we start mutating the object. |
| 8832 Object* new_double; | 8866 Object* new_double; |
| 8833 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); | 8867 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); |
| 8834 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 8868 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
| 8835 } | 8869 } |
| 8836 result_double = HeapNumber::cast(new_double); | 8870 result_double = HeapNumber::cast(new_double); |
| 8837 } | 8871 } |
| 8838 | 8872 |
| 8839 Object* obj; | 8873 Object* obj; |
| 8840 { MaybeObject* maybe_obj = | 8874 { MaybeObject* maybe_obj = |
| 8841 NumberDictionary::Allocate(dict->NumberOfElements()); | 8875 NumberDictionary::Allocate(dict->NumberOfElements()); |
| 8842 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8876 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8843 } | 8877 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8883 // allocation. Bailout. | 8917 // allocation. Bailout. |
| 8884 return Smi::FromInt(-1); | 8918 return Smi::FromInt(-1); |
| 8885 } | 8919 } |
| 8886 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); | 8920 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); |
| 8887 } | 8921 } |
| 8888 } | 8922 } |
| 8889 } | 8923 } |
| 8890 | 8924 |
| 8891 uint32_t result = pos; | 8925 uint32_t result = pos; |
| 8892 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); | 8926 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); |
| 8927 Heap* heap = GetHeap(); | |
| 8893 while (undefs > 0) { | 8928 while (undefs > 0) { |
| 8894 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 8929 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 8895 // Adding an entry with the key beyond smi-range requires | 8930 // Adding an entry with the key beyond smi-range requires |
| 8896 // allocation. Bailout. | 8931 // allocation. Bailout. |
| 8897 return Smi::FromInt(-1); | 8932 return Smi::FromInt(-1); |
| 8898 } | 8933 } |
| 8899 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> | 8934 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> |
| 8900 ToObjectUnchecked(); | 8935 ToObjectUnchecked(); |
| 8901 pos++; | 8936 pos++; |
| 8902 undefs--; | 8937 undefs--; |
| 8903 } | 8938 } |
| 8904 | 8939 |
| 8905 set_elements(new_dict); | 8940 set_elements(new_dict); |
| 8906 | 8941 |
| 8907 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 8942 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 8908 return Smi::FromInt(static_cast<int>(result)); | 8943 return Smi::FromInt(static_cast<int>(result)); |
| 8909 } | 8944 } |
| 8910 | 8945 |
| 8911 ASSERT_NE(NULL, result_double); | 8946 ASSERT_NE(NULL, result_double); |
| 8912 result_double->set_value(static_cast<double>(result)); | 8947 result_double->set_value(static_cast<double>(result)); |
| 8913 return result_double; | 8948 return result_double; |
| 8914 } | 8949 } |
| 8915 | 8950 |
| 8916 | 8951 |
| 8917 // Collects all defined (non-hole) and non-undefined (array) elements at | 8952 // Collects all defined (non-hole) and non-undefined (array) elements at |
| 8918 // the start of the elements array. | 8953 // the start of the elements array. |
| 8919 // If the object is in dictionary mode, it is converted to fast elements | 8954 // If the object is in dictionary mode, it is converted to fast elements |
| 8920 // mode. | 8955 // mode. |
| 8921 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { | 8956 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 8957 ASSERT(!HasExternalArrayElements()); | |
| 8958 | |
| 8922 Heap* heap = GetHeap(); | 8959 Heap* heap = GetHeap(); |
| 8923 ASSERT(!HasExternalArrayElements()); | |
| 8924 | 8960 |
| 8925 if (HasDictionaryElements()) { | 8961 if (HasDictionaryElements()) { |
| 8926 // Convert to fast elements containing only the existing properties. | 8962 // Convert to fast elements containing only the existing properties. |
| 8927 // Ordering is irrelevant, since we are going to sort anyway. | 8963 // Ordering is irrelevant, since we are going to sort anyway. |
| 8928 NumberDictionary* dict = element_dictionary(); | 8964 NumberDictionary* dict = element_dictionary(); |
| 8929 if (IsJSArray() || dict->requires_slow_elements() || | 8965 if (IsJSArray() || dict->requires_slow_elements() || |
| 8930 dict->max_number_key() >= limit) { | 8966 dict->max_number_key() >= limit) { |
| 8931 return PrepareSlowElementsForSort(limit); | 8967 return PrepareSlowElementsForSort(limit); |
| 8932 } | 8968 } |
| 8933 // Convert to fast elements. | 8969 // Convert to fast elements. |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9168 | 9204 |
| 9169 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { | 9205 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
| 9170 ASSERT(!HasFastProperties()); | 9206 ASSERT(!HasFastProperties()); |
| 9171 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 9207 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 9172 return JSGlobalPropertyCell::cast(value); | 9208 return JSGlobalPropertyCell::cast(value); |
| 9173 } | 9209 } |
| 9174 | 9210 |
| 9175 | 9211 |
| 9176 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { | 9212 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { |
| 9177 ASSERT(!HasFastProperties()); | 9213 ASSERT(!HasFastProperties()); |
| 9178 Heap* heap = GetHeap(); | |
| 9179 int entry = property_dictionary()->FindEntry(name); | 9214 int entry = property_dictionary()->FindEntry(name); |
| 9180 if (entry == StringDictionary::kNotFound) { | 9215 if (entry == StringDictionary::kNotFound) { |
| 9216 Heap* heap = GetHeap(); | |
| 9181 Object* cell; | 9217 Object* cell; |
| 9182 { MaybeObject* maybe_cell = | 9218 { MaybeObject* maybe_cell = |
| 9183 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); | 9219 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); |
| 9184 if (!maybe_cell->ToObject(&cell)) return maybe_cell; | 9220 if (!maybe_cell->ToObject(&cell)) return maybe_cell; |
| 9185 } | 9221 } |
| 9186 PropertyDetails details(NONE, NORMAL); | 9222 PropertyDetails details(NONE, NORMAL); |
| 9187 details = details.AsDeleted(); | 9223 details = details.AsDeleted(); |
| 9188 Object* dictionary; | 9224 Object* dictionary; |
| 9189 { MaybeObject* maybe_dictionary = | 9225 { MaybeObject* maybe_dictionary = |
| 9190 property_dictionary()->Add(name, cell, details); | 9226 property_dictionary()->Add(name, cell, details); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9345 // Add the new symbol and return it along with the symbol table. | 9381 // Add the new symbol and return it along with the symbol table. |
| 9346 entry = table->FindInsertionEntry(key->Hash()); | 9382 entry = table->FindInsertionEntry(key->Hash()); |
| 9347 table->set(EntryToIndex(entry), symbol); | 9383 table->set(EntryToIndex(entry), symbol); |
| 9348 table->ElementAdded(); | 9384 table->ElementAdded(); |
| 9349 *s = symbol; | 9385 *s = symbol; |
| 9350 return table; | 9386 return table; |
| 9351 } | 9387 } |
| 9352 | 9388 |
| 9353 | 9389 |
| 9354 Object* CompilationCacheTable::Lookup(String* src) { | 9390 Object* CompilationCacheTable::Lookup(String* src) { |
| 9355 Heap* heap = GetHeap(); | |
| 9356 StringKey key(src); | 9391 StringKey key(src); |
| 9357 int entry = FindEntry(&key); | 9392 int entry = FindEntry(&key); |
| 9358 if (entry == kNotFound) return heap->undefined_value(); | 9393 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 9359 return get(EntryToIndex(entry) + 1); | 9394 return get(EntryToIndex(entry) + 1); |
| 9360 } | 9395 } |
| 9361 | 9396 |
| 9362 | 9397 |
| 9363 Object* CompilationCacheTable::LookupEval(String* src, | 9398 Object* CompilationCacheTable::LookupEval(String* src, |
| 9364 Context* context, | 9399 Context* context, |
| 9365 StrictModeFlag strict_mode) { | 9400 StrictModeFlag strict_mode) { |
| 9366 StringSharedKey key(src, context->closure()->shared(), strict_mode); | 9401 StringSharedKey key(src, context->closure()->shared(), strict_mode); |
| 9367 int entry = FindEntry(&key); | 9402 int entry = FindEntry(&key); |
| 9368 if (entry == kNotFound) return GetHeap()->undefined_value(); | 9403 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 9369 return get(EntryToIndex(entry) + 1); | 9404 return get(EntryToIndex(entry) + 1); |
| 9370 } | 9405 } |
| 9371 | 9406 |
| 9372 | 9407 |
| 9373 Object* CompilationCacheTable::LookupRegExp(String* src, | 9408 Object* CompilationCacheTable::LookupRegExp(String* src, |
| 9374 JSRegExp::Flags flags) { | 9409 JSRegExp::Flags flags) { |
| 9375 Heap* heap = GetHeap(); | |
| 9376 RegExpKey key(src, flags); | 9410 RegExpKey key(src, flags); |
| 9377 int entry = FindEntry(&key); | 9411 int entry = FindEntry(&key); |
| 9378 if (entry == kNotFound) return heap->undefined_value(); | 9412 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 9379 return get(EntryToIndex(entry) + 1); | 9413 return get(EntryToIndex(entry) + 1); |
| 9380 } | 9414 } |
| 9381 | 9415 |
| 9382 | 9416 |
| 9383 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { | 9417 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { |
| 9384 StringKey key(src); | 9418 StringKey key(src); |
| 9385 Object* obj; | 9419 Object* obj; |
| 9386 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 9420 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 9387 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9421 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 9388 } | 9422 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9488 } | 9522 } |
| 9489 | 9523 |
| 9490 Object* AsObject() { return symbols_; } | 9524 Object* AsObject() { return symbols_; } |
| 9491 | 9525 |
| 9492 private: | 9526 private: |
| 9493 FixedArray* symbols_; | 9527 FixedArray* symbols_; |
| 9494 }; | 9528 }; |
| 9495 | 9529 |
| 9496 | 9530 |
| 9497 Object* MapCache::Lookup(FixedArray* array) { | 9531 Object* MapCache::Lookup(FixedArray* array) { |
| 9498 Heap* heap = GetHeap(); | |
| 9499 SymbolsKey key(array); | 9532 SymbolsKey key(array); |
| 9500 int entry = FindEntry(&key); | 9533 int entry = FindEntry(&key); |
| 9501 if (entry == kNotFound) return heap->undefined_value(); | 9534 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 9502 return get(EntryToIndex(entry) + 1); | 9535 return get(EntryToIndex(entry) + 1); |
| 9503 } | 9536 } |
| 9504 | 9537 |
| 9505 | 9538 |
| 9506 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { | 9539 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { |
| 9507 SymbolsKey key(array); | 9540 SymbolsKey key(array); |
| 9508 Object* obj; | 9541 Object* obj; |
| 9509 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 9542 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 9510 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9543 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 9511 } | 9544 } |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9847 storage->set(index++, k); | 9880 storage->set(index++, k); |
| 9848 } | 9881 } |
| 9849 } | 9882 } |
| 9850 ASSERT(storage->length() >= index); | 9883 ASSERT(storage->length() >= index); |
| 9851 } | 9884 } |
| 9852 | 9885 |
| 9853 | 9886 |
| 9854 // Backwards lookup (slow). | 9887 // Backwards lookup (slow). |
| 9855 template<typename Shape, typename Key> | 9888 template<typename Shape, typename Key> |
| 9856 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 9889 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
| 9857 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | |
| 9858 int capacity = HashTable<Shape, Key>::Capacity(); | 9890 int capacity = HashTable<Shape, Key>::Capacity(); |
| 9859 for (int i = 0; i < capacity; i++) { | 9891 for (int i = 0; i < capacity; i++) { |
| 9860 Object* k = HashTable<Shape, Key>::KeyAt(i); | 9892 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 9861 if (Dictionary<Shape, Key>::IsKey(k)) { | 9893 if (Dictionary<Shape, Key>::IsKey(k)) { |
| 9862 Object* e = ValueAt(i); | 9894 Object* e = ValueAt(i); |
| 9863 if (e->IsJSGlobalPropertyCell()) { | 9895 if (e->IsJSGlobalPropertyCell()) { |
| 9864 e = JSGlobalPropertyCell::cast(e)->value(); | 9896 e = JSGlobalPropertyCell::cast(e)->value(); |
| 9865 } | 9897 } |
| 9866 if (e == value) return k; | 9898 if (e == value) return k; |
| 9867 } | 9899 } |
| 9868 } | 9900 } |
| 9901 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | |
| 9869 return heap->undefined_value(); | 9902 return heap->undefined_value(); |
| 9870 } | 9903 } |
| 9871 | 9904 |
| 9872 | 9905 |
| 9873 MaybeObject* StringDictionary::TransformPropertiesToFastFor( | 9906 MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
| 9874 JSObject* obj, int unused_property_fields) { | 9907 JSObject* obj, int unused_property_fields) { |
| 9875 Heap* heap = GetHeap(); | |
| 9876 // Make sure we preserve dictionary representation if there are too many | 9908 // Make sure we preserve dictionary representation if there are too many |
| 9877 // descriptors. | 9909 // descriptors. |
| 9878 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 9910 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
| 9879 | 9911 |
| 9880 // Figure out if it is necessary to generate new enumeration indices. | 9912 // Figure out if it is necessary to generate new enumeration indices. |
| 9881 int max_enumeration_index = | 9913 int max_enumeration_index = |
| 9882 NextEnumerationIndex() + | 9914 NextEnumerationIndex() + |
| 9883 (DescriptorArray::kMaxNumberOfDescriptors - | 9915 (DescriptorArray::kMaxNumberOfDescriptors - |
| 9884 NumberOfElements()); | 9916 NumberOfElements()); |
| 9885 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { | 9917 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { |
| 9886 Object* result; | 9918 Object* result; |
| 9887 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 9919 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 9888 if (!maybe_result->ToObject(&result)) return maybe_result; | 9920 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9889 } | 9921 } |
| 9890 } | 9922 } |
| 9891 | 9923 |
| 9892 int instance_descriptor_length = 0; | 9924 int instance_descriptor_length = 0; |
| 9893 int number_of_fields = 0; | 9925 int number_of_fields = 0; |
| 9894 | 9926 |
| 9927 Heap* heap = GetHeap(); | |
| 9928 | |
| 9895 // Compute the length of the instance descriptor. | 9929 // Compute the length of the instance descriptor. |
| 9896 int capacity = Capacity(); | 9930 int capacity = Capacity(); |
| 9897 for (int i = 0; i < capacity; i++) { | 9931 for (int i = 0; i < capacity; i++) { |
| 9898 Object* k = KeyAt(i); | 9932 Object* k = KeyAt(i); |
| 9899 if (IsKey(k)) { | 9933 if (IsKey(k)) { |
| 9900 Object* value = ValueAt(i); | 9934 Object* value = ValueAt(i); |
| 9901 PropertyType type = DetailsAt(i).type(); | 9935 PropertyType type = DetailsAt(i).type(); |
| 9902 ASSERT(type != FIELD); | 9936 ASSERT(type != FIELD); |
| 9903 instance_descriptor_length++; | 9937 instance_descriptor_length++; |
| 9904 if (type == NORMAL && | 9938 if (type == NORMAL && |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10013 | 10047 |
| 10014 // If there is no break point info object or no break points in the break | 10048 // If there is no break point info object or no break points in the break |
| 10015 // point info object there is no break point at this code position. | 10049 // point info object there is no break point at this code position. |
| 10016 if (break_point_info->IsUndefined()) return false; | 10050 if (break_point_info->IsUndefined()) return false; |
| 10017 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 10051 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
| 10018 } | 10052 } |
| 10019 | 10053 |
| 10020 | 10054 |
| 10021 // Get the break point info object for this code position. | 10055 // Get the break point info object for this code position. |
| 10022 Object* DebugInfo::GetBreakPointInfo(int code_position) { | 10056 Object* DebugInfo::GetBreakPointInfo(int code_position) { |
| 10023 Heap* heap = GetHeap(); | |
| 10024 // Find the index of the break point info object for this code position. | 10057 // Find the index of the break point info object for this code position. |
| 10025 int index = GetBreakPointInfoIndex(code_position); | 10058 int index = GetBreakPointInfoIndex(code_position); |
| 10026 | 10059 |
| 10027 // Return the break point info object if any. | 10060 // Return the break point info object if any. |
| 10028 if (index == kNoBreakPointInfo) return heap->undefined_value(); | 10061 if (index == kNoBreakPointInfo) return GetHeap()->undefined_value(); |
| 10029 return BreakPointInfo::cast(break_points()->get(index)); | 10062 return BreakPointInfo::cast(break_points()->get(index)); |
| 10030 } | 10063 } |
| 10031 | 10064 |
| 10032 | 10065 |
| 10033 // Clear a break point at the specified code position. | 10066 // Clear a break point at the specified code position. |
| 10034 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, | 10067 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, |
| 10035 int code_position, | 10068 int code_position, |
| 10036 Handle<Object> break_point_object) { | 10069 Handle<Object> break_point_object) { |
| 10037 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); | 10070 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); |
| 10038 if (break_point_info->IsUndefined()) return; | 10071 if (break_point_info->IsUndefined()) return; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10091 set_statement_position(Smi::FromInt(statement_position)); | 10124 set_statement_position(Smi::FromInt(statement_position)); |
| 10092 new_break_point_info->set_break_point_objects( | 10125 new_break_point_info->set_break_point_objects( |
| 10093 isolate->heap()->undefined_value()); | 10126 isolate->heap()->undefined_value()); |
| 10094 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); | 10127 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
| 10095 debug_info->break_points()->set(index, *new_break_point_info); | 10128 debug_info->break_points()->set(index, *new_break_point_info); |
| 10096 } | 10129 } |
| 10097 | 10130 |
| 10098 | 10131 |
| 10099 // Get the break point objects for a code position. | 10132 // Get the break point objects for a code position. |
| 10100 Object* DebugInfo::GetBreakPointObjects(int code_position) { | 10133 Object* DebugInfo::GetBreakPointObjects(int code_position) { |
| 10101 Heap* heap = GetHeap(); | |
| 10102 Object* break_point_info = GetBreakPointInfo(code_position); | 10134 Object* break_point_info = GetBreakPointInfo(code_position); |
| 10103 if (break_point_info->IsUndefined()) { | 10135 if (break_point_info->IsUndefined()) { |
| 10104 return heap->undefined_value(); | 10136 return GetHeap()->undefined_value(); |
| 10105 } | 10137 } |
| 10106 return BreakPointInfo::cast(break_point_info)->break_point_objects(); | 10138 return BreakPointInfo::cast(break_point_info)->break_point_objects(); |
| 10107 } | 10139 } |
| 10108 | 10140 |
| 10109 | 10141 |
| 10110 // Get the total number of break points. | 10142 // Get the total number of break points. |
| 10111 int DebugInfo::GetBreakPointCount() { | 10143 int DebugInfo::GetBreakPointCount() { |
| 10112 if (break_points()->IsUndefined()) return 0; | 10144 if (break_points()->IsUndefined()) return 0; |
| 10113 int count = 0; | 10145 int count = 0; |
| 10114 for (int i = 0; i < break_points()->length(); i++) { | 10146 for (int i = 0; i < break_points()->length(); i++) { |
| 10115 if (!break_points()->get(i)->IsUndefined()) { | 10147 if (!break_points()->get(i)->IsUndefined()) { |
| 10116 BreakPointInfo* break_point_info = | 10148 BreakPointInfo* break_point_info = |
| 10117 BreakPointInfo::cast(break_points()->get(i)); | 10149 BreakPointInfo::cast(break_points()->get(i)); |
| 10118 count += break_point_info->GetBreakPointCount(); | 10150 count += break_point_info->GetBreakPointCount(); |
| 10119 } | 10151 } |
| 10120 } | 10152 } |
| 10121 return count; | 10153 return count; |
| 10122 } | 10154 } |
| 10123 | 10155 |
| 10124 | 10156 |
| 10125 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, | 10157 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, |
| 10126 Handle<Object> break_point_object) { | 10158 Handle<Object> break_point_object) { |
| 10127 Heap* heap = Isolate::Current()->heap(); | 10159 Heap* heap = debug_info->GetHeap(); |
| 10128 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value(); | 10160 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value(); |
| 10129 for (int i = 0; i < debug_info->break_points()->length(); i++) { | 10161 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
| 10130 if (!debug_info->break_points()->get(i)->IsUndefined()) { | 10162 if (!debug_info->break_points()->get(i)->IsUndefined()) { |
| 10131 Handle<BreakPointInfo> break_point_info = | 10163 Handle<BreakPointInfo> break_point_info = |
| 10132 Handle<BreakPointInfo>(BreakPointInfo::cast( | 10164 Handle<BreakPointInfo>(BreakPointInfo::cast( |
| 10133 debug_info->break_points()->get(i))); | 10165 debug_info->break_points()->get(i))); |
| 10134 if (BreakPointInfo::HasBreakPointObject(break_point_info, | 10166 if (BreakPointInfo::HasBreakPointObject(break_point_info, |
| 10135 break_point_object)) { | 10167 break_point_object)) { |
| 10136 return *break_point_info; | 10168 return *break_point_info; |
| 10137 } | 10169 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10254 if (break_point_objects()->IsUndefined()) return 0; | 10286 if (break_point_objects()->IsUndefined()) return 0; |
| 10255 // Single beak point. | 10287 // Single beak point. |
| 10256 if (!break_point_objects()->IsFixedArray()) return 1; | 10288 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10257 // Multiple break points. | 10289 // Multiple break points. |
| 10258 return FixedArray::cast(break_point_objects())->length(); | 10290 return FixedArray::cast(break_point_objects())->length(); |
| 10259 } | 10291 } |
| 10260 #endif | 10292 #endif |
| 10261 | 10293 |
| 10262 | 10294 |
| 10263 } } // namespace v8::internal | 10295 } } // namespace v8::internal |
| OLD | NEW |