| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 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 HeapObject* heap_object = HeapObject::cast(this); | 116 if (IsUndefined() || IsNull()) { |
| 117 if (heap_object->IsUndefined() || heap_object->IsNull()) { | 117 return HeapObject::cast(this)->GetHeap()->false_value(); |
| 118 return heap_object->GetHeap()->false_value(); | |
| 119 } | 118 } |
| 120 // Undetectable object is false | 119 // Undetectable object is false |
| 121 if (heap_object->IsUndetectableObject()) { | 120 if (IsUndetectableObject()) { |
| 122 return heap_object->GetHeap()->false_value(); | 121 return HeapObject::cast(this)->GetHeap()->false_value(); |
| 123 } | 122 } |
| 124 if (heap_object->IsString()) { | 123 if (IsString()) { |
| 125 return heap_object->GetHeap()->ToBoolean( | 124 return HeapObject::cast(this)->GetHeap()->ToBoolean( |
| 126 String::cast(this)->length() != 0); | 125 String::cast(this)->length() != 0); |
| 127 } | 126 } |
| 128 if (heap_object->IsHeapNumber()) { | 127 if (IsHeapNumber()) { |
| 129 return HeapNumber::cast(this)->HeapNumberToBoolean(); | 128 return HeapNumber::cast(this)->HeapNumberToBoolean(); |
| 130 } | 129 } |
| 131 return heap_object->GetHeap()->true_value(); | 130 return Isolate::Current()->heap()->true_value(); |
| 132 } | 131 } |
| 133 | 132 |
| 134 | 133 |
| 135 void Object::Lookup(String* name, LookupResult* result) { | 134 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 (IsSmi()) { | 137 if (IsString()) { |
| 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()) { |
| 138 Heap* heap = Isolate::Current()->heap(); | 142 Heap* heap = Isolate::Current()->heap(); |
| 139 Context* global_context = heap->isolate()->context()->global_context(); | 143 Context* global_context = heap->isolate()->context()->global_context(); |
| 140 holder = global_context->number_function()->instance_prototype(); | 144 holder = global_context->number_function()->instance_prototype(); |
| 141 } else { | 145 } else if (IsBoolean()) { |
| 142 HeapObject* heap_object = HeapObject::cast(this); | 146 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 143 if (heap_object->IsJSObject()) { | 147 Context* global_context = heap->isolate()->context()->global_context(); |
| 144 return JSObject::cast(this)->Lookup(name, result); | 148 holder = global_context->boolean_function()->instance_prototype(); |
| 145 } | |
| 146 Heap* heap = heap_object->GetHeap(); | |
| 147 if (heap_object->IsString()) { | |
| 148 Context* global_context = heap->isolate()->context()->global_context(); | |
| 149 holder = global_context->string_function()->instance_prototype(); | |
| 150 } else if (heap_object->IsHeapNumber()) { | |
| 151 Context* global_context = heap->isolate()->context()->global_context(); | |
| 152 holder = global_context->number_function()->instance_prototype(); | |
| 153 } else if (heap_object->IsBoolean()) { | |
| 154 Context* global_context = heap->isolate()->context()->global_context(); | |
| 155 holder = global_context->boolean_function()->instance_prototype(); | |
| 156 } | |
| 157 } | 149 } |
| 158 ASSERT(holder != NULL); // Cannot handle null or undefined. | 150 ASSERT(holder != NULL); // Cannot handle null or undefined. |
| 159 JSObject::cast(holder)->Lookup(name, result); | 151 JSObject::cast(holder)->Lookup(name, result); |
| 160 } | 152 } |
| 161 | 153 |
| 162 | 154 |
| 163 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 155 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
| 164 String* name, | 156 String* name, |
| 165 PropertyAttributes* attributes) { | 157 PropertyAttributes* attributes) { |
| 166 LookupResult result; | 158 LookupResult result; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 return *result; | 240 return *result; |
| 249 } | 241 } |
| 250 | 242 |
| 251 | 243 |
| 252 // Only deal with CALLBACKS and INTERCEPTOR | 244 // Only deal with CALLBACKS and INTERCEPTOR |
| 253 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( | 245 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( |
| 254 Object* receiver, | 246 Object* receiver, |
| 255 LookupResult* result, | 247 LookupResult* result, |
| 256 String* name, | 248 String* name, |
| 257 PropertyAttributes* attributes) { | 249 PropertyAttributes* attributes) { |
| 250 Heap* heap = name->GetHeap(); |
| 258 if (result->IsProperty()) { | 251 if (result->IsProperty()) { |
| 259 switch (result->type()) { | 252 switch (result->type()) { |
| 260 case CALLBACKS: { | 253 case CALLBACKS: { |
| 261 // Only allow API accessors. | 254 // Only allow API accessors. |
| 262 Object* obj = result->GetCallbackObject(); | 255 Object* obj = result->GetCallbackObject(); |
| 263 if (obj->IsAccessorInfo()) { | 256 if (obj->IsAccessorInfo()) { |
| 264 AccessorInfo* info = AccessorInfo::cast(obj); | 257 AccessorInfo* info = AccessorInfo::cast(obj); |
| 265 if (info->all_can_read()) { | 258 if (info->all_can_read()) { |
| 266 *attributes = result->GetAttributes(); | 259 *attributes = result->GetAttributes(); |
| 267 return GetPropertyWithCallback(receiver, | 260 return GetPropertyWithCallback(receiver, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 } | 292 } |
| 300 break; | 293 break; |
| 301 } | 294 } |
| 302 default: | 295 default: |
| 303 UNREACHABLE(); | 296 UNREACHABLE(); |
| 304 } | 297 } |
| 305 } | 298 } |
| 306 | 299 |
| 307 // No accessible property found. | 300 // No accessible property found. |
| 308 *attributes = ABSENT; | 301 *attributes = ABSENT; |
| 309 Heap* heap = name->GetHeap(); | |
| 310 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 302 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 311 return heap->undefined_value(); | 303 return heap->undefined_value(); |
| 312 } | 304 } |
| 313 | 305 |
| 314 | 306 |
| 315 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 307 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
| 316 Object* receiver, | 308 Object* receiver, |
| 317 LookupResult* result, | 309 LookupResult* result, |
| 318 String* name, | 310 String* name, |
| 319 bool continue_search) { | 311 bool continue_search) { |
| 312 Heap* heap = name->GetHeap(); |
| 320 if (result->IsProperty()) { | 313 if (result->IsProperty()) { |
| 321 switch (result->type()) { | 314 switch (result->type()) { |
| 322 case CALLBACKS: { | 315 case CALLBACKS: { |
| 323 // Only allow API accessors. | 316 // Only allow API accessors. |
| 324 Object* obj = result->GetCallbackObject(); | 317 Object* obj = result->GetCallbackObject(); |
| 325 if (obj->IsAccessorInfo()) { | 318 if (obj->IsAccessorInfo()) { |
| 326 AccessorInfo* info = AccessorInfo::cast(obj); | 319 AccessorInfo* info = AccessorInfo::cast(obj); |
| 327 if (info->all_can_read()) { | 320 if (info->all_can_read()) { |
| 328 return result->GetAttributes(); | 321 return result->GetAttributes(); |
| 329 } | 322 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 continue_search); | 356 continue_search); |
| 364 } | 357 } |
| 365 break; | 358 break; |
| 366 } | 359 } |
| 367 | 360 |
| 368 default: | 361 default: |
| 369 UNREACHABLE(); | 362 UNREACHABLE(); |
| 370 } | 363 } |
| 371 } | 364 } |
| 372 | 365 |
| 373 GetHeap()->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 366 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 374 return ABSENT; | 367 return ABSENT; |
| 375 } | 368 } |
| 376 | 369 |
| 377 | 370 |
| 378 Object* JSObject::GetNormalizedProperty(LookupResult* result) { | 371 Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
| 379 ASSERT(!HasFastProperties()); | 372 ASSERT(!HasFastProperties()); |
| 380 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 373 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 381 if (IsGlobalObject()) { | 374 if (IsGlobalObject()) { |
| 382 value = JSGlobalPropertyCell::cast(value)->value(); | 375 value = JSGlobalPropertyCell::cast(value)->value(); |
| 383 } | 376 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 397 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 390 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 398 } | 391 } |
| 399 return value; | 392 return value; |
| 400 } | 393 } |
| 401 | 394 |
| 402 | 395 |
| 403 MaybeObject* JSObject::SetNormalizedProperty(String* name, | 396 MaybeObject* JSObject::SetNormalizedProperty(String* name, |
| 404 Object* value, | 397 Object* value, |
| 405 PropertyDetails details) { | 398 PropertyDetails details) { |
| 406 ASSERT(!HasFastProperties()); | 399 ASSERT(!HasFastProperties()); |
| 400 Heap* heap = name->GetHeap(); |
| 407 int entry = property_dictionary()->FindEntry(name); | 401 int entry = property_dictionary()->FindEntry(name); |
| 408 if (entry == StringDictionary::kNotFound) { | 402 if (entry == StringDictionary::kNotFound) { |
| 409 Object* store_value = value; | 403 Object* store_value = value; |
| 410 if (IsGlobalObject()) { | 404 if (IsGlobalObject()) { |
| 411 Heap* heap = name->GetHeap(); | |
| 412 MaybeObject* maybe_store_value = | 405 MaybeObject* maybe_store_value = |
| 413 heap->AllocateJSGlobalPropertyCell(value); | 406 heap->AllocateJSGlobalPropertyCell(value); |
| 414 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 407 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 415 } | 408 } |
| 416 Object* dict; | 409 Object* dict; |
| 417 { MaybeObject* maybe_dict = | 410 { MaybeObject* maybe_dict = |
| 418 property_dictionary()->Add(name, store_value, details); | 411 property_dictionary()->Add(name, store_value, details); |
| 419 if (!maybe_dict->ToObject(&dict)) return maybe_dict; | 412 if (!maybe_dict->ToObject(&dict)) return maybe_dict; |
| 420 } | 413 } |
| 421 set_properties(StringDictionary::cast(dict)); | 414 set_properties(StringDictionary::cast(dict)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 433 property_dictionary()->DetailsAtPut(entry, details); | 426 property_dictionary()->DetailsAtPut(entry, details); |
| 434 } else { | 427 } else { |
| 435 property_dictionary()->SetEntry(entry, name, value, details); | 428 property_dictionary()->SetEntry(entry, name, value, details); |
| 436 } | 429 } |
| 437 return value; | 430 return value; |
| 438 } | 431 } |
| 439 | 432 |
| 440 | 433 |
| 441 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 434 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
| 442 ASSERT(!HasFastProperties()); | 435 ASSERT(!HasFastProperties()); |
| 436 Heap* heap = GetHeap(); |
| 443 StringDictionary* dictionary = property_dictionary(); | 437 StringDictionary* dictionary = property_dictionary(); |
| 444 int entry = dictionary->FindEntry(name); | 438 int entry = dictionary->FindEntry(name); |
| 445 if (entry != StringDictionary::kNotFound) { | 439 if (entry != StringDictionary::kNotFound) { |
| 446 // If we have a global object set the cell to the hole. | 440 // If we have a global object set the cell to the hole. |
| 447 if (IsGlobalObject()) { | 441 if (IsGlobalObject()) { |
| 448 PropertyDetails details = dictionary->DetailsAt(entry); | 442 PropertyDetails details = dictionary->DetailsAt(entry); |
| 449 if (details.IsDontDelete()) { | 443 if (details.IsDontDelete()) { |
| 450 if (mode != FORCE_DELETION) return GetHeap()->false_value(); | 444 if (mode != FORCE_DELETION) return heap->false_value(); |
| 451 // When forced to delete global properties, we have to make a | 445 // When forced to delete global properties, we have to make a |
| 452 // map change to invalidate any ICs that think they can load | 446 // map change to invalidate any ICs that think they can load |
| 453 // from the DontDelete cell without checking if it contains | 447 // from the DontDelete cell without checking if it contains |
| 454 // the hole value. | 448 // the hole value. |
| 455 Object* new_map; | 449 Object* new_map; |
| 456 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 450 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 457 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 451 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 458 } | 452 } |
| 459 set_map(Map::cast(new_map)); | 453 set_map(Map::cast(new_map)); |
| 460 } | 454 } |
| 461 JSGlobalPropertyCell* cell = | 455 JSGlobalPropertyCell* cell = |
| 462 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 456 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
| 463 cell->set_value(cell->heap()->the_hole_value()); | 457 cell->set_value(heap->the_hole_value()); |
| 464 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 458 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 465 } else { | 459 } else { |
| 466 return dictionary->DeleteProperty(entry, mode); | 460 return dictionary->DeleteProperty(entry, mode); |
| 467 } | 461 } |
| 468 } | 462 } |
| 469 return GetHeap()->true_value(); | 463 return heap->true_value(); |
| 470 } | 464 } |
| 471 | 465 |
| 472 | 466 |
| 473 bool JSObject::IsDirty() { | 467 bool JSObject::IsDirty() { |
| 474 Object* cons_obj = map()->constructor(); | 468 Object* cons_obj = map()->constructor(); |
| 475 if (!cons_obj->IsJSFunction()) | 469 if (!cons_obj->IsJSFunction()) |
| 476 return true; | 470 return true; |
| 477 JSFunction* fun = JSFunction::cast(cons_obj); | 471 JSFunction* fun = JSFunction::cast(cons_obj); |
| 478 if (!fun->shared()->IsApiFunction()) | 472 if (!fun->shared()->IsApiFunction()) |
| 479 return true; | 473 return true; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 543 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
| 550 } | 544 } |
| 551 default: | 545 default: |
| 552 UNREACHABLE(); | 546 UNREACHABLE(); |
| 553 return NULL; | 547 return NULL; |
| 554 } | 548 } |
| 555 } | 549 } |
| 556 | 550 |
| 557 | 551 |
| 558 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 552 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
| 553 if (IsJSObject()) { |
| 554 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); |
| 555 } |
| 556 |
| 559 Object* holder = NULL; | 557 Object* holder = NULL; |
| 560 if (IsSmi()) { | 558 Context* global_context = Isolate::Current()->context()->global_context(); |
| 561 Context* global_context = Isolate::Current()->context()->global_context(); | 559 if (IsString()) { |
| 560 holder = global_context->string_function()->instance_prototype(); |
| 561 } else if (IsNumber()) { |
| 562 holder = global_context->number_function()->instance_prototype(); | 562 holder = global_context->number_function()->instance_prototype(); |
| 563 } else if (IsBoolean()) { |
| 564 holder = global_context->boolean_function()->instance_prototype(); |
| 563 } else { | 565 } else { |
| 564 HeapObject* heap_object = HeapObject::cast(this); | 566 // Undefined and null have no indexed properties. |
| 565 | 567 ASSERT(IsUndefined() || IsNull()); |
| 566 if (heap_object->IsJSObject()) { | 568 return HEAP->undefined_value(); |
| 567 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); | |
| 568 } | |
| 569 Heap* heap = heap_object->GetHeap(); | |
| 570 Isolate* isolate = heap->isolate(); | |
| 571 | |
| 572 Context* global_context = isolate->context()->global_context(); | |
| 573 if (heap_object->IsString()) { | |
| 574 holder = global_context->string_function()->instance_prototype(); | |
| 575 } else if (heap_object->IsHeapNumber()) { | |
| 576 holder = global_context->number_function()->instance_prototype(); | |
| 577 } else if (heap_object->IsBoolean()) { | |
| 578 holder = global_context->boolean_function()->instance_prototype(); | |
| 579 } else { | |
| 580 // Undefined and null have no indexed properties. | |
| 581 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); | |
| 582 return heap->undefined_value(); | |
| 583 } | |
| 584 } | 569 } |
| 585 | 570 |
| 586 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); | 571 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); |
| 587 } | 572 } |
| 588 | 573 |
| 589 | 574 |
| 590 Object* Object::GetPrototype() { | 575 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_object = HeapObject::cast(this); | |
| 598 | |
| 599 // The object is either a number, a string, a boolean, or a real JS object. | 576 // The object is either a number, a string, a boolean, or a real JS object. |
| 600 if (heap_object->IsJSObject()) { | 577 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
| 601 return JSObject::cast(this)->map()->prototype(); | 578 Heap* heap = Isolate::Current()->heap(); |
| 602 } | |
| 603 Heap* heap = heap_object->GetHeap(); | |
| 604 Context* context = heap->isolate()->context()->global_context(); | 579 Context* context = heap->isolate()->context()->global_context(); |
| 605 | 580 |
| 606 if (heap_object->IsHeapNumber()) { | 581 if (IsNumber()) return context->number_function()->instance_prototype(); |
| 607 return context->number_function()->instance_prototype(); | 582 if (IsString()) return context->string_function()->instance_prototype(); |
| 608 } | 583 if (IsBoolean()) { |
| 609 if (heap_object->IsString()) { | |
| 610 return context->string_function()->instance_prototype(); | |
| 611 } | |
| 612 if (heap_object->IsBoolean()) { | |
| 613 return context->boolean_function()->instance_prototype(); | 584 return context->boolean_function()->instance_prototype(); |
| 614 } else { | 585 } else { |
| 615 return heap->null_value(); | 586 return heap->null_value(); |
| 616 } | 587 } |
| 617 } | 588 } |
| 618 | 589 |
| 619 | 590 |
| 620 void Object::ShortPrint(FILE* out) { | 591 void Object::ShortPrint(FILE* out) { |
| 621 HeapStringAllocator allocator; | 592 HeapStringAllocator allocator; |
| 622 StringStream accumulator(&allocator); | 593 StringStream accumulator(&allocator); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 } | 901 } |
| 931 } | 902 } |
| 932 if (!printed) { | 903 if (!printed) { |
| 933 accumulator->Add("<JS Function>"); | 904 accumulator->Add("<JS Function>"); |
| 934 } | 905 } |
| 935 break; | 906 break; |
| 936 } | 907 } |
| 937 // All other JSObjects are rather similar to each other (JSObject, | 908 // All other JSObjects are rather similar to each other (JSObject, |
| 938 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). | 909 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). |
| 939 default: { | 910 default: { |
| 940 Map* map_of_this = map(); | 911 Heap* heap = GetHeap(); |
| 941 Heap* heap = map_of_this->heap(); | 912 Object* constructor = map()->constructor(); |
| 942 Object* constructor = map_of_this->constructor(); | |
| 943 bool printed = false; | 913 bool printed = false; |
| 944 if (constructor->IsHeapObject() && | 914 if (constructor->IsHeapObject() && |
| 945 !heap->Contains(HeapObject::cast(constructor))) { | 915 !heap->Contains(HeapObject::cast(constructor))) { |
| 946 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); | 916 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); |
| 947 } else { | 917 } else { |
| 948 bool global_object = IsJSGlobalProxy(); | 918 bool global_object = IsJSGlobalProxy(); |
| 949 if (constructor->IsJSFunction()) { | 919 if (constructor->IsJSFunction()) { |
| 950 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { | 920 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { |
| 951 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); | 921 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); |
| 952 } else { | 922 } else { |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1373 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1343 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1374 set_map(new_map); | 1344 set_map(new_map); |
| 1375 return FastPropertyAtPut(index, value); | 1345 return FastPropertyAtPut(index, value); |
| 1376 } | 1346 } |
| 1377 | 1347 |
| 1378 | 1348 |
| 1379 MaybeObject* JSObject::AddConstantFunctionProperty( | 1349 MaybeObject* JSObject::AddConstantFunctionProperty( |
| 1380 String* name, | 1350 String* name, |
| 1381 JSFunction* function, | 1351 JSFunction* function, |
| 1382 PropertyAttributes attributes) { | 1352 PropertyAttributes attributes) { |
| 1383 ASSERT(!GetHeap()->InNewSpace(function)); | 1353 Heap* heap = GetHeap(); |
| 1354 ASSERT(!heap->InNewSpace(function)); |
| 1384 | 1355 |
| 1385 // Allocate new instance descriptors with (name, function) added | 1356 // Allocate new instance descriptors with (name, function) added |
| 1386 ConstantFunctionDescriptor d(name, function, attributes); | 1357 ConstantFunctionDescriptor d(name, function, attributes); |
| 1387 Object* new_descriptors; | 1358 Object* new_descriptors; |
| 1388 { MaybeObject* maybe_new_descriptors = | 1359 { MaybeObject* maybe_new_descriptors = |
| 1389 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); | 1360 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); |
| 1390 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1361 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
| 1391 return maybe_new_descriptors; | 1362 return maybe_new_descriptors; |
| 1392 } | 1363 } |
| 1393 } | 1364 } |
| 1394 | 1365 |
| 1395 // Allocate a new map for the object. | 1366 // Allocate a new map for the object. |
| 1396 Object* new_map; | 1367 Object* new_map; |
| 1397 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 1368 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
| 1398 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 1369 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 1399 } | 1370 } |
| 1400 | 1371 |
| 1401 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); | 1372 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); |
| 1402 Map::cast(new_map)->set_instance_descriptors(descriptors); | 1373 Map::cast(new_map)->set_instance_descriptors(descriptors); |
| 1403 Map* old_map = map(); | 1374 Map* old_map = map(); |
| 1404 set_map(Map::cast(new_map)); | 1375 set_map(Map::cast(new_map)); |
| 1405 | 1376 |
| 1406 // If the old map is the global object map (from new Object()), | 1377 // If the old map is the global object map (from new Object()), |
| 1407 // then transitions are not added to it, so we are done. | 1378 // then transitions are not added to it, so we are done. |
| 1408 Heap* heap = old_map->heap(); | |
| 1409 if (old_map == heap->isolate()->context()->global_context()-> | 1379 if (old_map == heap->isolate()->context()->global_context()-> |
| 1410 object_function()->map()) { | 1380 object_function()->map()) { |
| 1411 return function; | 1381 return function; |
| 1412 } | 1382 } |
| 1413 | 1383 |
| 1414 // Do not add CONSTANT_TRANSITIONS to global objects | 1384 // Do not add CONSTANT_TRANSITIONS to global objects |
| 1415 if (IsGlobalObject()) { | 1385 if (IsGlobalObject()) { |
| 1416 return function; | 1386 return function; |
| 1417 } | 1387 } |
| 1418 | 1388 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1435 | 1405 |
| 1436 return function; | 1406 return function; |
| 1437 } | 1407 } |
| 1438 | 1408 |
| 1439 | 1409 |
| 1440 // Add property in slow mode | 1410 // Add property in slow mode |
| 1441 MaybeObject* JSObject::AddSlowProperty(String* name, | 1411 MaybeObject* JSObject::AddSlowProperty(String* name, |
| 1442 Object* value, | 1412 Object* value, |
| 1443 PropertyAttributes attributes) { | 1413 PropertyAttributes attributes) { |
| 1444 ASSERT(!HasFastProperties()); | 1414 ASSERT(!HasFastProperties()); |
| 1415 Heap* heap = GetHeap(); |
| 1445 StringDictionary* dict = property_dictionary(); | 1416 StringDictionary* dict = property_dictionary(); |
| 1446 Object* store_value = value; | 1417 Object* store_value = value; |
| 1447 if (IsGlobalObject()) { | 1418 if (IsGlobalObject()) { |
| 1448 // In case name is an orphaned property reuse the cell. | 1419 // In case name is an orphaned property reuse the cell. |
| 1449 int entry = dict->FindEntry(name); | 1420 int entry = dict->FindEntry(name); |
| 1450 if (entry != StringDictionary::kNotFound) { | 1421 if (entry != StringDictionary::kNotFound) { |
| 1451 store_value = dict->ValueAt(entry); | 1422 store_value = dict->ValueAt(entry); |
| 1452 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1423 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1453 // Assign an enumeration index to the property and update | 1424 // Assign an enumeration index to the property and update |
| 1454 // SetNextEnumerationIndex. | 1425 // SetNextEnumerationIndex. |
| 1455 int index = dict->NextEnumerationIndex(); | 1426 int index = dict->NextEnumerationIndex(); |
| 1456 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); | 1427 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
| 1457 dict->SetNextEnumerationIndex(index + 1); | 1428 dict->SetNextEnumerationIndex(index + 1); |
| 1458 dict->SetEntry(entry, name, store_value, details); | 1429 dict->SetEntry(entry, name, store_value, details); |
| 1459 return value; | 1430 return value; |
| 1460 } | 1431 } |
| 1461 Heap* heap = GetHeap(); | |
| 1462 { MaybeObject* maybe_store_value = | 1432 { MaybeObject* maybe_store_value = |
| 1463 heap->AllocateJSGlobalPropertyCell(value); | 1433 heap->AllocateJSGlobalPropertyCell(value); |
| 1464 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 1434 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| 1465 } | 1435 } |
| 1466 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1436 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1467 } | 1437 } |
| 1468 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1438 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1469 Object* result; | 1439 Object* result; |
| 1470 { MaybeObject* maybe_result = dict->Add(name, store_value, details); | 1440 { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
| 1471 if (!maybe_result->ToObject(&result)) return maybe_result; | 1441 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1472 } | 1442 } |
| 1473 if (dict != result) set_properties(StringDictionary::cast(result)); | 1443 if (dict != result) set_properties(StringDictionary::cast(result)); |
| 1474 return value; | 1444 return value; |
| 1475 } | 1445 } |
| 1476 | 1446 |
| 1477 | 1447 |
| 1478 MaybeObject* JSObject::AddProperty(String* name, | 1448 MaybeObject* JSObject::AddProperty(String* name, |
| 1479 Object* value, | 1449 Object* value, |
| 1480 PropertyAttributes attributes, | 1450 PropertyAttributes attributes, |
| 1481 StrictModeFlag strict_mode) { | 1451 StrictModeFlag strict_mode) { |
| 1482 ASSERT(!IsJSGlobalProxy()); | 1452 ASSERT(!IsJSGlobalProxy()); |
| 1483 Map* map_of_this = map(); | 1453 Heap* heap = GetHeap(); |
| 1484 Heap* heap = map_of_this->heap(); | 1454 if (!map()->is_extensible()) { |
| 1485 if (!map_of_this->is_extensible()) { | |
| 1486 if (strict_mode == kNonStrictMode) { | 1455 if (strict_mode == kNonStrictMode) { |
| 1487 return heap->undefined_value(); | 1456 return heap->undefined_value(); |
| 1488 } else { | 1457 } else { |
| 1489 Handle<Object> args[1] = {Handle<String>(name)}; | 1458 Handle<Object> args[1] = {Handle<String>(name)}; |
| 1490 return heap->isolate()->Throw( | 1459 return heap->isolate()->Throw( |
| 1491 *FACTORY->NewTypeError("object_not_extensible", | 1460 *FACTORY->NewTypeError("object_not_extensible", |
| 1492 HandleVector(args, 1))); | 1461 HandleVector(args, 1))); |
| 1493 } | 1462 } |
| 1494 } | 1463 } |
| 1495 if (HasFastProperties()) { | 1464 if (HasFastProperties()) { |
| 1496 // Ensure the descriptor array does not get too big. | 1465 // Ensure the descriptor array does not get too big. |
| 1497 if (map_of_this->instance_descriptors()->number_of_descriptors() < | 1466 if (map()->instance_descriptors()->number_of_descriptors() < |
| 1498 DescriptorArray::kMaxNumberOfDescriptors) { | 1467 DescriptorArray::kMaxNumberOfDescriptors) { |
| 1499 if (value->IsJSFunction() && !heap->InNewSpace(value)) { | 1468 if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
| 1500 return AddConstantFunctionProperty(name, | 1469 return AddConstantFunctionProperty(name, |
| 1501 JSFunction::cast(value), | 1470 JSFunction::cast(value), |
| 1502 attributes); | 1471 attributes); |
| 1503 } else { | 1472 } else { |
| 1504 return AddFastProperty(name, value, attributes); | 1473 return AddFastProperty(name, value, attributes); |
| 1505 } | 1474 } |
| 1506 } else { | 1475 } else { |
| 1507 // Normalize the object to prevent very large instance descriptors. | 1476 // Normalize the object to prevent very large instance descriptors. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 { MaybeObject* maybe_result = | 1530 { MaybeObject* maybe_result = |
| 1562 ConvertDescriptorToField(name, new_value, attributes); | 1531 ConvertDescriptorToField(name, new_value, attributes); |
| 1563 if (!maybe_result->ToObject(&result)) return maybe_result; | 1532 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1564 } | 1533 } |
| 1565 // If we get to this point we have succeeded - do not return failure | 1534 // If we get to this point we have succeeded - do not return failure |
| 1566 // after this point. Later stuff is optional. | 1535 // after this point. Later stuff is optional. |
| 1567 if (!HasFastProperties()) { | 1536 if (!HasFastProperties()) { |
| 1568 return result; | 1537 return result; |
| 1569 } | 1538 } |
| 1570 // Do not add transitions to the map of "new Object()". | 1539 // Do not add transitions to the map of "new Object()". |
| 1571 if (map() == old_map->heap()->isolate()->context()->global_context()-> | 1540 if (map() == GetHeap()->isolate()->context()->global_context()-> |
| 1572 object_function()->map()) { | 1541 object_function()->map()) { |
| 1573 return result; | 1542 return result; |
| 1574 } | 1543 } |
| 1575 | 1544 |
| 1576 MapTransitionDescriptor transition(name, | 1545 MapTransitionDescriptor transition(name, |
| 1577 map(), | 1546 map(), |
| 1578 attributes); | 1547 attributes); |
| 1579 Object* new_descriptors; | 1548 Object* new_descriptors; |
| 1580 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> | 1549 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> |
| 1581 CopyInsert(&transition, KEEP_TRANSITIONS); | 1550 CopyInsert(&transition, KEEP_TRANSITIONS); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 if (number != DescriptorArray::kNotFound) { | 1829 if (number != DescriptorArray::kNotFound) { |
| 1861 result->DescriptorResult(holder, descriptors->GetDetails(number), number); | 1830 result->DescriptorResult(holder, descriptors->GetDetails(number), number); |
| 1862 } else { | 1831 } else { |
| 1863 result->NotFound(); | 1832 result->NotFound(); |
| 1864 } | 1833 } |
| 1865 } | 1834 } |
| 1866 | 1835 |
| 1867 | 1836 |
| 1868 MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, | 1837 MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, |
| 1869 bool safe_to_add_transition) { | 1838 bool safe_to_add_transition) { |
| 1870 Heap* current_heap = heap(); | |
| 1871 DescriptorArray* descriptors = instance_descriptors(); | 1839 DescriptorArray* descriptors = instance_descriptors(); |
| 1872 String* external_array_sentinel_name = current_heap->empty_symbol(); | 1840 String* external_array_sentinel_name = GetIsolate()->heap()->empty_symbol(); |
| 1873 | 1841 |
| 1874 if (safe_to_add_transition) { | 1842 if (safe_to_add_transition) { |
| 1875 // It's only safe to manipulate the descriptor array if it would be | 1843 // It's only safe to manipulate the descriptor array if it would be |
| 1876 // safe to add a transition. | 1844 // safe to add a transition. |
| 1877 | 1845 |
| 1878 ASSERT(!is_shared()); // no transitions can be added to shared maps. | 1846 ASSERT(!is_shared()); // no transitions can be added to shared maps. |
| 1879 // Check if the external array transition already exists. | 1847 // Check if the external array transition already exists. |
| 1880 DescriptorLookupCache* cache = | 1848 DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache(); |
| 1881 current_heap->isolate()->descriptor_lookup_cache(); | |
| 1882 int index = cache->Lookup(descriptors, external_array_sentinel_name); | 1849 int index = cache->Lookup(descriptors, external_array_sentinel_name); |
| 1883 if (index == DescriptorLookupCache::kAbsent) { | 1850 if (index == DescriptorLookupCache::kAbsent) { |
| 1884 index = descriptors->Search(external_array_sentinel_name); | 1851 index = descriptors->Search(external_array_sentinel_name); |
| 1885 cache->Update(descriptors, | 1852 cache->Update(descriptors, |
| 1886 external_array_sentinel_name, | 1853 external_array_sentinel_name, |
| 1887 index); | 1854 index); |
| 1888 } | 1855 } |
| 1889 | 1856 |
| 1890 // If the transition already exists, check the type. If there is a match, | 1857 // If the transition already exists, check the type. If there is a match, |
| 1891 // return it. | 1858 // return it. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2005 } | 1972 } |
| 2006 result->NotFound(); | 1973 result->NotFound(); |
| 2007 } | 1974 } |
| 2008 | 1975 |
| 2009 | 1976 |
| 2010 // We only need to deal with CALLBACKS and INTERCEPTORS | 1977 // We only need to deal with CALLBACKS and INTERCEPTORS |
| 2011 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 1978 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, |
| 2012 String* name, | 1979 String* name, |
| 2013 Object* value, | 1980 Object* value, |
| 2014 bool check_prototype) { | 1981 bool check_prototype) { |
| 1982 Heap* heap = GetHeap(); |
| 2015 if (check_prototype && !result->IsProperty()) { | 1983 if (check_prototype && !result->IsProperty()) { |
| 2016 LookupCallbackSetterInPrototypes(name, result); | 1984 LookupCallbackSetterInPrototypes(name, result); |
| 2017 } | 1985 } |
| 2018 | 1986 |
| 2019 if (result->IsProperty()) { | 1987 if (result->IsProperty()) { |
| 2020 if (!result->IsReadOnly()) { | 1988 if (!result->IsReadOnly()) { |
| 2021 switch (result->type()) { | 1989 switch (result->type()) { |
| 2022 case CALLBACKS: { | 1990 case CALLBACKS: { |
| 2023 Object* obj = result->GetCallbackObject(); | 1991 Object* obj = result->GetCallbackObject(); |
| 2024 if (obj->IsAccessorInfo()) { | 1992 if (obj->IsAccessorInfo()) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2045 } | 2013 } |
| 2046 default: { | 2014 default: { |
| 2047 break; | 2015 break; |
| 2048 } | 2016 } |
| 2049 } | 2017 } |
| 2050 } | 2018 } |
| 2051 } | 2019 } |
| 2052 | 2020 |
| 2053 HandleScope scope; | 2021 HandleScope scope; |
| 2054 Handle<Object> value_handle(value); | 2022 Handle<Object> value_handle(value); |
| 2055 Heap* heap = GetHeap(); | |
| 2056 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2023 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2057 return *value_handle; | 2024 return *value_handle; |
| 2058 } | 2025 } |
| 2059 | 2026 |
| 2060 | 2027 |
| 2061 MaybeObject* JSObject::SetProperty(LookupResult* result, | 2028 MaybeObject* JSObject::SetProperty(LookupResult* result, |
| 2062 String* name, | 2029 String* name, |
| 2063 Object* value, | 2030 Object* value, |
| 2064 PropertyAttributes attributes, | 2031 PropertyAttributes attributes, |
| 2065 StrictModeFlag strict_mode) { | 2032 StrictModeFlag strict_mode) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2183 // Set a real local property, even if it is READ_ONLY. If the property is not | 2150 // Set a real local property, even if it is READ_ONLY. If the property is not |
| 2184 // present, add it with attributes NONE. This code is an exact clone of | 2151 // present, add it with attributes NONE. This code is an exact clone of |
| 2185 // SetProperty, with the check for IsReadOnly and the check for a | 2152 // SetProperty, with the check for IsReadOnly and the check for a |
| 2186 // callback setter removed. The two lines looking up the LookupResult | 2153 // callback setter removed. The two lines looking up the LookupResult |
| 2187 // result are also added. If one of the functions is changed, the other | 2154 // result are also added. If one of the functions is changed, the other |
| 2188 // should be. | 2155 // should be. |
| 2189 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 2156 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 2190 String* name, | 2157 String* name, |
| 2191 Object* value, | 2158 Object* value, |
| 2192 PropertyAttributes attributes) { | 2159 PropertyAttributes attributes) { |
| 2160 Heap* heap = GetHeap(); |
| 2193 | 2161 |
| 2194 // Make sure that the top context does not change when doing callbacks or | 2162 // Make sure that the top context does not change when doing callbacks or |
| 2195 // interceptor calls. | 2163 // interceptor calls. |
| 2196 AssertNoContextChange ncc; | 2164 AssertNoContextChange ncc; |
| 2197 LookupResult result; | 2165 LookupResult result; |
| 2198 LocalLookup(name, &result); | 2166 LocalLookup(name, &result); |
| 2199 // Check access rights if needed. | 2167 // Check access rights if needed. |
| 2200 if (IsAccessCheckNeeded()) { | 2168 if (IsAccessCheckNeeded() |
| 2201 Heap* heap = GetHeap(); | 2169 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2202 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2170 return SetPropertyWithFailedAccessCheck(&result, name, value, false); |
| 2203 return SetPropertyWithFailedAccessCheck(&result, name, value, false); | |
| 2204 } | |
| 2205 } | 2171 } |
| 2206 | 2172 |
| 2207 if (IsJSGlobalProxy()) { | 2173 if (IsJSGlobalProxy()) { |
| 2208 Object* proto = GetPrototype(); | 2174 Object* proto = GetPrototype(); |
| 2209 if (proto->IsNull()) return value; | 2175 if (proto->IsNull()) return value; |
| 2210 ASSERT(proto->IsJSGlobalObject()); | 2176 ASSERT(proto->IsJSGlobalObject()); |
| 2211 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 2177 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
| 2212 name, | 2178 name, |
| 2213 value, | 2179 value, |
| 2214 attributes); | 2180 attributes); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 LookupResult result; | 2311 LookupResult result; |
| 2346 Lookup(key, &result); | 2312 Lookup(key, &result); |
| 2347 return GetPropertyAttribute(receiver, &result, key, true); | 2313 return GetPropertyAttribute(receiver, &result, key, true); |
| 2348 } | 2314 } |
| 2349 | 2315 |
| 2350 | 2316 |
| 2351 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, | 2317 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, |
| 2352 LookupResult* result, | 2318 LookupResult* result, |
| 2353 String* name, | 2319 String* name, |
| 2354 bool continue_search) { | 2320 bool continue_search) { |
| 2321 Heap* heap = GetHeap(); |
| 2355 // Check access rights if needed. | 2322 // Check access rights if needed. |
| 2356 if (IsAccessCheckNeeded()) { | 2323 if (IsAccessCheckNeeded() && |
| 2357 Heap* heap = GetHeap(); | 2324 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 2358 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2325 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 2359 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2326 result, |
| 2360 result, | 2327 name, |
| 2361 name, | 2328 continue_search); |
| 2362 continue_search); | |
| 2363 } | |
| 2364 } | 2329 } |
| 2365 if (result->IsProperty()) { | 2330 if (result->IsProperty()) { |
| 2366 switch (result->type()) { | 2331 switch (result->type()) { |
| 2367 case NORMAL: // fall through | 2332 case NORMAL: // fall through |
| 2368 case FIELD: | 2333 case FIELD: |
| 2369 case CONSTANT_FUNCTION: | 2334 case CONSTANT_FUNCTION: |
| 2370 case CALLBACKS: | 2335 case CALLBACKS: |
| 2371 return result->GetAttributes(); | 2336 return result->GetAttributes(); |
| 2372 case INTERCEPTOR: | 2337 case INTERCEPTOR: |
| 2373 return result->holder()-> | 2338 return result->holder()-> |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 | 2458 |
| 2494 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 2459 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
| 2495 int expected_additional_properties) { | 2460 int expected_additional_properties) { |
| 2496 if (!HasFastProperties()) return this; | 2461 if (!HasFastProperties()) return this; |
| 2497 | 2462 |
| 2498 // The global object is always normalized. | 2463 // The global object is always normalized. |
| 2499 ASSERT(!IsGlobalObject()); | 2464 ASSERT(!IsGlobalObject()); |
| 2500 // JSGlobalProxy must never be normalized | 2465 // JSGlobalProxy must never be normalized |
| 2501 ASSERT(!IsJSGlobalProxy()); | 2466 ASSERT(!IsJSGlobalProxy()); |
| 2502 | 2467 |
| 2503 Map* map_of_this = map(); | 2468 Heap* heap = GetHeap(); |
| 2504 | 2469 |
| 2505 // Allocate new content. | 2470 // Allocate new content. |
| 2506 int property_count = map_of_this->NumberOfDescribedProperties(); | 2471 int property_count = map()->NumberOfDescribedProperties(); |
| 2507 if (expected_additional_properties > 0) { | 2472 if (expected_additional_properties > 0) { |
| 2508 property_count += expected_additional_properties; | 2473 property_count += expected_additional_properties; |
| 2509 } else { | 2474 } else { |
| 2510 property_count += 2; // Make space for two more properties. | 2475 property_count += 2; // Make space for two more properties. |
| 2511 } | 2476 } |
| 2512 Object* obj; | 2477 Object* obj; |
| 2513 { MaybeObject* maybe_obj = | 2478 { MaybeObject* maybe_obj = |
| 2514 StringDictionary::Allocate(property_count); | 2479 StringDictionary::Allocate(property_count); |
| 2515 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2480 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2516 } | 2481 } |
| 2517 StringDictionary* dictionary = StringDictionary::cast(obj); | 2482 StringDictionary* dictionary = StringDictionary::cast(obj); |
| 2518 | 2483 |
| 2519 DescriptorArray* descs = map_of_this->instance_descriptors(); | 2484 DescriptorArray* descs = map()->instance_descriptors(); |
| 2520 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 2485 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 2521 PropertyDetails details = descs->GetDetails(i); | 2486 PropertyDetails details = descs->GetDetails(i); |
| 2522 switch (details.type()) { | 2487 switch (details.type()) { |
| 2523 case CONSTANT_FUNCTION: { | 2488 case CONSTANT_FUNCTION: { |
| 2524 PropertyDetails d = | 2489 PropertyDetails d = |
| 2525 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2490 PropertyDetails(details.attributes(), NORMAL, details.index()); |
| 2526 Object* value = descs->GetConstantFunction(i); | 2491 Object* value = descs->GetConstantFunction(i); |
| 2527 Object* result; | 2492 Object* result; |
| 2528 { MaybeObject* maybe_result = | 2493 { MaybeObject* maybe_result = |
| 2529 dictionary->Add(descs->GetKey(i), value, d); | 2494 dictionary->Add(descs->GetKey(i), value, d); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2559 case MAP_TRANSITION: | 2524 case MAP_TRANSITION: |
| 2560 case CONSTANT_TRANSITION: | 2525 case CONSTANT_TRANSITION: |
| 2561 case NULL_DESCRIPTOR: | 2526 case NULL_DESCRIPTOR: |
| 2562 case INTERCEPTOR: | 2527 case INTERCEPTOR: |
| 2563 break; | 2528 break; |
| 2564 default: | 2529 default: |
| 2565 UNREACHABLE(); | 2530 UNREACHABLE(); |
| 2566 } | 2531 } |
| 2567 } | 2532 } |
| 2568 | 2533 |
| 2569 Heap* current_heap = map_of_this->heap(); | |
| 2570 | |
| 2571 // Copy the next enumeration index from instance descriptor. | 2534 // Copy the next enumeration index from instance descriptor. |
| 2572 int index = map_of_this->instance_descriptors()->NextEnumerationIndex(); | 2535 int index = map()->instance_descriptors()->NextEnumerationIndex(); |
| 2573 dictionary->SetNextEnumerationIndex(index); | 2536 dictionary->SetNextEnumerationIndex(index); |
| 2574 | 2537 |
| 2575 { MaybeObject* maybe_obj = | 2538 { MaybeObject* maybe_obj = heap->isolate()->context()->global_context()-> |
| 2576 current_heap->isolate()->context()->global_context()-> | |
| 2577 normalized_map_cache()->Get(this, mode); | 2539 normalized_map_cache()->Get(this, mode); |
| 2578 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2540 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2579 } | 2541 } |
| 2580 Map* new_map = Map::cast(obj); | 2542 Map* new_map = Map::cast(obj); |
| 2581 | 2543 |
| 2582 // We have now successfully allocated all the necessary objects. | 2544 // We have now successfully allocated all the necessary objects. |
| 2583 // Changes can now be made with the guarantee that all of them take effect. | 2545 // Changes can now be made with the guarantee that all of them take effect. |
| 2584 | 2546 |
| 2585 // Resize the object in the heap if necessary. | 2547 // Resize the object in the heap if necessary. |
| 2586 int new_instance_size = new_map->instance_size(); | 2548 int new_instance_size = new_map->instance_size(); |
| 2587 int instance_size_delta = map_of_this->instance_size() - new_instance_size; | 2549 int instance_size_delta = map()->instance_size() - new_instance_size; |
| 2588 ASSERT(instance_size_delta >= 0); | 2550 ASSERT(instance_size_delta >= 0); |
| 2589 current_heap->CreateFillerObjectAt(this->address() + new_instance_size, | 2551 heap->CreateFillerObjectAt(this->address() + new_instance_size, |
| 2590 instance_size_delta); | 2552 instance_size_delta); |
| 2591 | 2553 |
| 2592 set_map(new_map); | 2554 set_map(new_map); |
| 2593 new_map->set_instance_descriptors(current_heap->empty_descriptor_array()); | 2555 map()->set_instance_descriptors(heap->empty_descriptor_array()); |
| 2594 | 2556 |
| 2595 set_properties(dictionary); | 2557 set_properties(dictionary); |
| 2596 | 2558 |
| 2597 current_heap->isolate()->counters()->props_to_dictionary()->Increment(); | 2559 heap->isolate()->counters()->props_to_dictionary()->Increment(); |
| 2598 | 2560 |
| 2599 #ifdef DEBUG | 2561 #ifdef DEBUG |
| 2600 if (FLAG_trace_normalization) { | 2562 if (FLAG_trace_normalization) { |
| 2601 PrintF("Object properties have been normalized:\n"); | 2563 PrintF("Object properties have been normalized:\n"); |
| 2602 Print(); | 2564 Print(); |
| 2603 } | 2565 } |
| 2604 #endif | 2566 #endif |
| 2605 return this; | 2567 return this; |
| 2606 } | 2568 } |
| 2607 | 2569 |
| 2608 | 2570 |
| 2609 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { | 2571 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 2610 if (HasFastProperties()) return this; | 2572 if (HasFastProperties()) return this; |
| 2611 ASSERT(!IsGlobalObject()); | 2573 ASSERT(!IsGlobalObject()); |
| 2612 return property_dictionary()-> | 2574 return property_dictionary()-> |
| 2613 TransformPropertiesToFastFor(this, unused_property_fields); | 2575 TransformPropertiesToFastFor(this, unused_property_fields); |
| 2614 } | 2576 } |
| 2615 | 2577 |
| 2616 | 2578 |
| 2617 MaybeObject* JSObject::NormalizeElements() { | 2579 MaybeObject* JSObject::NormalizeElements() { |
| 2618 ASSERT(!HasExternalArrayElements()); | 2580 ASSERT(!HasExternalArrayElements()); |
| 2619 // Find the backing store. | 2581 // Find the backing store. |
| 2620 FixedArray* original = FixedArray::cast(elements()); | 2582 FixedArray* original = FixedArray::cast(elements()); |
| 2621 Map* old_map = original->map(); | |
| 2622 Heap* heap = old_map->heap(); | |
| 2623 bool is_arguments = | 2583 bool is_arguments = |
| 2624 (old_map == heap->non_strict_arguments_elements_map()); | 2584 (original->map() == GetHeap()->non_strict_arguments_elements_map()); |
| 2625 if (is_arguments) { | 2585 if (is_arguments) { |
| 2626 original = FixedArray::cast(original->get(1)); | 2586 original = FixedArray::cast(original->get(1)); |
| 2627 } | 2587 } |
| 2628 if (original->IsDictionary()) return original; | 2588 if (original->IsDictionary()) return original; |
| 2629 | 2589 |
| 2630 ASSERT(HasFastElements() || HasFastArgumentsElements()); | 2590 ASSERT(HasFastElements() || HasFastArgumentsElements()); |
| 2631 // Compute the effective length and allocate a new backing store. | 2591 // Compute the effective length and allocate a new backing store. |
| 2632 int length = IsJSArray() | 2592 int length = IsJSArray() |
| 2633 ? Smi::cast(JSArray::cast(this)->length())->value() | 2593 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 2634 : original->length(); | 2594 : original->length(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2651 } | 2611 } |
| 2652 } | 2612 } |
| 2653 | 2613 |
| 2654 // Switch to using the dictionary as the backing storage for elements. | 2614 // Switch to using the dictionary as the backing storage for elements. |
| 2655 if (is_arguments) { | 2615 if (is_arguments) { |
| 2656 FixedArray::cast(elements())->set(1, dictionary); | 2616 FixedArray::cast(elements())->set(1, dictionary); |
| 2657 } else { | 2617 } else { |
| 2658 // Set the new map first to satify the elements type assert in | 2618 // Set the new map first to satify the elements type assert in |
| 2659 // set_elements(). | 2619 // set_elements(). |
| 2660 Object* new_map; | 2620 Object* new_map; |
| 2661 MaybeObject* maybe = old_map->GetSlowElementsMap(); | 2621 MaybeObject* maybe = map()->GetSlowElementsMap(); |
| 2662 if (!maybe->ToObject(&new_map)) return maybe; | 2622 if (!maybe->ToObject(&new_map)) return maybe; |
| 2663 set_map(Map::cast(new_map)); | 2623 set_map(Map::cast(new_map)); |
| 2664 set_elements(dictionary); | 2624 set_elements(dictionary); |
| 2665 } | 2625 } |
| 2666 | 2626 |
| 2667 heap->isolate()->counters()->elements_to_dictionary()->Increment(); | 2627 GetIsolate()->counters()->elements_to_dictionary()->Increment(); |
| 2668 | 2628 |
| 2669 #ifdef DEBUG | 2629 #ifdef DEBUG |
| 2670 if (FLAG_trace_normalization) { | 2630 if (FLAG_trace_normalization) { |
| 2671 PrintF("Object elements have been normalized:\n"); | 2631 PrintF("Object elements have been normalized:\n"); |
| 2672 Print(); | 2632 Print(); |
| 2673 } | 2633 } |
| 2674 #endif | 2634 #endif |
| 2675 | 2635 |
| 2676 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 2636 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 2677 return dictionary; | 2637 return dictionary; |
| 2678 } | 2638 } |
| 2679 | 2639 |
| 2680 | 2640 |
| 2681 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 2641 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, |
| 2682 DeleteMode mode) { | 2642 DeleteMode mode) { |
| 2683 // Check local property, ignore interceptor. | 2643 // Check local property, ignore interceptor. |
| 2644 Heap* heap = GetHeap(); |
| 2684 LookupResult result; | 2645 LookupResult result; |
| 2685 LocalLookupRealNamedProperty(name, &result); | 2646 LocalLookupRealNamedProperty(name, &result); |
| 2686 if (!result.IsProperty()) return GetHeap()->true_value(); | 2647 if (!result.IsProperty()) return heap->true_value(); |
| 2687 | 2648 |
| 2688 // Normalize object if needed. | 2649 // Normalize object if needed. |
| 2689 Object* obj; | 2650 Object* obj; |
| 2690 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2651 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2691 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2652 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2692 } | 2653 } |
| 2693 | 2654 |
| 2694 return DeleteNormalizedProperty(name, mode); | 2655 return DeleteNormalizedProperty(name, mode); |
| 2695 } | 2656 } |
| 2696 | 2657 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2722 } | 2683 } |
| 2723 MaybeObject* raw_result = | 2684 MaybeObject* raw_result = |
| 2724 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 2685 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); |
| 2725 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2686 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2726 return raw_result; | 2687 return raw_result; |
| 2727 } | 2688 } |
| 2728 | 2689 |
| 2729 | 2690 |
| 2730 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2691 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, |
| 2731 DeleteMode mode) { | 2692 DeleteMode mode) { |
| 2693 Heap* heap = GetHeap(); |
| 2732 ASSERT(!HasExternalArrayElements()); | 2694 ASSERT(!HasExternalArrayElements()); |
| 2733 // We don't have to handle strict mode deletion of non-configurable | 2695 // We don't have to handle strict mode deletion of non-configurable |
| 2734 // properties. | 2696 // properties. |
| 2735 ASSERT(mode != STRICT_DELETION); | 2697 ASSERT(mode != STRICT_DELETION); |
| 2736 switch (GetElementsKind()) { | 2698 switch (GetElementsKind()) { |
| 2737 case FAST_ELEMENTS: { | 2699 case FAST_ELEMENTS: { |
| 2738 return DeleteFastElement(index); | 2700 return DeleteFastElement(index); |
| 2739 } | 2701 } |
| 2740 case DICTIONARY_ELEMENTS: { | 2702 case DICTIONARY_ELEMENTS: { |
| 2741 NumberDictionary* dictionary = element_dictionary(); | 2703 NumberDictionary* dictionary = element_dictionary(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2752 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2714 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2753 case EXTERNAL_SHORT_ELEMENTS: | 2715 case EXTERNAL_SHORT_ELEMENTS: |
| 2754 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2716 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2755 case EXTERNAL_INT_ELEMENTS: | 2717 case EXTERNAL_INT_ELEMENTS: |
| 2756 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2718 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2757 case EXTERNAL_FLOAT_ELEMENTS: | 2719 case EXTERNAL_FLOAT_ELEMENTS: |
| 2758 case EXTERNAL_PIXEL_ELEMENTS: | 2720 case EXTERNAL_PIXEL_ELEMENTS: |
| 2759 UNREACHABLE(); | 2721 UNREACHABLE(); |
| 2760 break; | 2722 break; |
| 2761 } | 2723 } |
| 2762 return GetHeap()->true_value(); | 2724 return heap->true_value(); |
| 2763 } | 2725 } |
| 2764 | 2726 |
| 2765 | 2727 |
| 2766 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2728 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
| 2767 Isolate* isolate = GetIsolate(); | 2729 Isolate* isolate = GetIsolate(); |
| 2768 Heap* heap = isolate->heap(); | 2730 Heap* heap = isolate->heap(); |
| 2769 // Make sure that the top context does not change when doing | 2731 // Make sure that the top context does not change when doing |
| 2770 // callbacks or interceptor calls. | 2732 // callbacks or interceptor calls. |
| 2771 AssertNoContextChange ncc; | 2733 AssertNoContextChange ncc; |
| 2772 HandleScope scope(isolate); | 2734 HandleScope scope(isolate); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2987 } else { | 2949 } else { |
| 2988 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); | 2950 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); |
| 2989 if (!key->IsUndefined()) return true; | 2951 if (!key->IsUndefined()) return true; |
| 2990 } | 2952 } |
| 2991 return false; | 2953 return false; |
| 2992 } | 2954 } |
| 2993 | 2955 |
| 2994 | 2956 |
| 2995 // Check whether this object references another object. | 2957 // Check whether this object references another object. |
| 2996 bool JSObject::ReferencesObject(Object* obj) { | 2958 bool JSObject::ReferencesObject(Object* obj) { |
| 2997 Map* map_of_this = map(); | 2959 Heap* heap = GetHeap(); |
| 2998 Heap* heap = map_of_this->heap(); | |
| 2999 AssertNoAllocation no_alloc; | 2960 AssertNoAllocation no_alloc; |
| 3000 | 2961 |
| 3001 // Is the object the constructor for this object? | 2962 // Is the object the constructor for this object? |
| 3002 if (map_of_this->constructor() == obj) { | 2963 if (map()->constructor() == obj) { |
| 3003 return true; | 2964 return true; |
| 3004 } | 2965 } |
| 3005 | 2966 |
| 3006 // Is the object the prototype for this object? | 2967 // Is the object the prototype for this object? |
| 3007 if (map_of_this->prototype() == obj) { | 2968 if (map()->prototype() == obj) { |
| 3008 return true; | 2969 return true; |
| 3009 } | 2970 } |
| 3010 | 2971 |
| 3011 // Check if the object is among the named properties. | 2972 // Check if the object is among the named properties. |
| 3012 Object* key = SlowReverseLookup(obj); | 2973 Object* key = SlowReverseLookup(obj); |
| 3013 if (!key->IsUndefined()) { | 2974 if (!key->IsUndefined()) { |
| 3014 return true; | 2975 return true; |
| 3015 } | 2976 } |
| 3016 | 2977 |
| 3017 // Check if the object is among the indexed properties. | 2978 // Check if the object is among the indexed properties. |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3645 } | 3606 } |
| 3646 } | 3607 } |
| 3647 } | 3608 } |
| 3648 } | 3609 } |
| 3649 } | 3610 } |
| 3650 return heap->undefined_value(); | 3611 return heap->undefined_value(); |
| 3651 } | 3612 } |
| 3652 | 3613 |
| 3653 | 3614 |
| 3654 Object* JSObject::SlowReverseLookup(Object* value) { | 3615 Object* JSObject::SlowReverseLookup(Object* value) { |
| 3616 Heap* heap = GetHeap(); |
| 3655 if (HasFastProperties()) { | 3617 if (HasFastProperties()) { |
| 3656 DescriptorArray* descs = map()->instance_descriptors(); | 3618 DescriptorArray* descs = map()->instance_descriptors(); |
| 3657 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 3619 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 3658 if (descs->GetType(i) == FIELD) { | 3620 if (descs->GetType(i) == FIELD) { |
| 3659 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { | 3621 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { |
| 3660 return descs->GetKey(i); | 3622 return descs->GetKey(i); |
| 3661 } | 3623 } |
| 3662 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { | 3624 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { |
| 3663 if (descs->GetConstantFunction(i) == value) { | 3625 if (descs->GetConstantFunction(i) == value) { |
| 3664 return descs->GetKey(i); | 3626 return descs->GetKey(i); |
| 3665 } | 3627 } |
| 3666 } | 3628 } |
| 3667 } | 3629 } |
| 3668 return GetHeap()->undefined_value(); | 3630 return heap->undefined_value(); |
| 3669 } else { | 3631 } else { |
| 3670 return property_dictionary()->SlowReverseLookup(value); | 3632 return property_dictionary()->SlowReverseLookup(value); |
| 3671 } | 3633 } |
| 3672 } | 3634 } |
| 3673 | 3635 |
| 3674 | 3636 |
| 3675 MaybeObject* Map::CopyDropDescriptors() { | 3637 MaybeObject* Map::CopyDropDescriptors() { |
| 3676 Heap* heap = GetHeap(); | 3638 Heap* heap = GetHeap(); |
| 3677 Object* result; | 3639 Object* result; |
| 3678 { MaybeObject* maybe_result = | 3640 { MaybeObject* maybe_result = |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3762 } | 3724 } |
| 3763 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); | 3725 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); |
| 3764 return new_map; | 3726 return new_map; |
| 3765 } | 3727 } |
| 3766 | 3728 |
| 3767 | 3729 |
| 3768 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { | 3730 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { |
| 3769 // Allocate the code cache if not present. | 3731 // Allocate the code cache if not present. |
| 3770 if (code_cache()->IsFixedArray()) { | 3732 if (code_cache()->IsFixedArray()) { |
| 3771 Object* result; | 3733 Object* result; |
| 3772 { MaybeObject* maybe_result = code->heap()->AllocateCodeCache(); | 3734 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); |
| 3773 if (!maybe_result->ToObject(&result)) return maybe_result; | 3735 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3774 } | 3736 } |
| 3775 set_code_cache(result); | 3737 set_code_cache(result); |
| 3776 } | 3738 } |
| 3777 | 3739 |
| 3778 // Update the code cache. | 3740 // Update the code cache. |
| 3779 return CodeCache::cast(code_cache())->Update(name, code); | 3741 return CodeCache::cast(code_cache())->Update(name, code); |
| 3780 } | 3742 } |
| 3781 | 3743 |
| 3782 | 3744 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 Object* CodeCache::Lookup(String* name, Code::Flags flags) { | 3910 Object* CodeCache::Lookup(String* name, Code::Flags flags) { |
| 3949 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { | 3911 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { |
| 3950 return LookupNormalTypeCache(name, flags); | 3912 return LookupNormalTypeCache(name, flags); |
| 3951 } else { | 3913 } else { |
| 3952 return LookupDefaultCache(name, flags); | 3914 return LookupDefaultCache(name, flags); |
| 3953 } | 3915 } |
| 3954 } | 3916 } |
| 3955 | 3917 |
| 3956 | 3918 |
| 3957 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { | 3919 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { |
| 3920 Heap* heap = GetHeap(); |
| 3958 FixedArray* cache = default_cache(); | 3921 FixedArray* cache = default_cache(); |
| 3959 int length = cache->length(); | 3922 int length = cache->length(); |
| 3960 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 3923 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
| 3961 Object* key = cache->get(i + kCodeCacheEntryNameOffset); | 3924 Object* key = cache->get(i + kCodeCacheEntryNameOffset); |
| 3962 // Skip deleted elements. | 3925 // Skip deleted elements. |
| 3963 if (key->IsNull()) continue; | 3926 if (key->IsNull()) continue; |
| 3964 if (key->IsUndefined()) return key; | 3927 if (key->IsUndefined()) return key; |
| 3965 if (name->Equals(String::cast(key))) { | 3928 if (name->Equals(String::cast(key))) { |
| 3966 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); | 3929 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); |
| 3967 if (code->flags() == flags) { | 3930 if (code->flags() == flags) { |
| 3968 return code; | 3931 return code; |
| 3969 } | 3932 } |
| 3970 } | 3933 } |
| 3971 } | 3934 } |
| 3972 return GetHeap()->undefined_value(); | 3935 return heap->undefined_value(); |
| 3973 } | 3936 } |
| 3974 | 3937 |
| 3975 | 3938 |
| 3976 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { | 3939 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { |
| 3977 if (!normal_type_cache()->IsUndefined()) { | 3940 if (!normal_type_cache()->IsUndefined()) { |
| 3978 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3941 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 3979 return cache->Lookup(name, flags); | 3942 return cache->Lookup(name, flags); |
| 3980 } else { | 3943 } else { |
| 3981 return GetHeap()->undefined_value(); | 3944 return GetHeap()->undefined_value(); |
| 3982 } | 3945 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4053 uint32_t HashForObject(Object* obj) { | 4016 uint32_t HashForObject(Object* obj) { |
| 4054 FixedArray* pair = FixedArray::cast(obj); | 4017 FixedArray* pair = FixedArray::cast(obj); |
| 4055 String* name = String::cast(pair->get(0)); | 4018 String* name = String::cast(pair->get(0)); |
| 4056 Code* code = Code::cast(pair->get(1)); | 4019 Code* code = Code::cast(pair->get(1)); |
| 4057 return NameFlagsHashHelper(name, code->flags()); | 4020 return NameFlagsHashHelper(name, code->flags()); |
| 4058 } | 4021 } |
| 4059 | 4022 |
| 4060 MUST_USE_RESULT MaybeObject* AsObject() { | 4023 MUST_USE_RESULT MaybeObject* AsObject() { |
| 4061 ASSERT(code_ != NULL); | 4024 ASSERT(code_ != NULL); |
| 4062 Object* obj; | 4025 Object* obj; |
| 4063 { MaybeObject* maybe_obj = code_->heap()->AllocateFixedArray(2); | 4026 { MaybeObject* maybe_obj = code_->GetHeap()->AllocateFixedArray(2); |
| 4064 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4027 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4065 } | 4028 } |
| 4066 FixedArray* pair = FixedArray::cast(obj); | 4029 FixedArray* pair = FixedArray::cast(obj); |
| 4067 pair->set(0, name_); | 4030 pair->set(0, name_); |
| 4068 pair->set(1, code_); | 4031 pair->set(1, code_); |
| 4069 return pair; | 4032 return pair; |
| 4070 } | 4033 } |
| 4071 | 4034 |
| 4072 private: | 4035 private: |
| 4073 String* name_; | 4036 String* name_; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4131 if (element->IsString() && | 4094 if (element->IsString() && |
| 4132 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 4095 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
| 4133 return true; | 4096 return true; |
| 4134 } | 4097 } |
| 4135 } | 4098 } |
| 4136 return false; | 4099 return false; |
| 4137 } | 4100 } |
| 4138 | 4101 |
| 4139 | 4102 |
| 4140 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 4103 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 4104 Heap* heap = GetHeap(); |
| 4141 ASSERT(!array->HasExternalArrayElements()); | 4105 ASSERT(!array->HasExternalArrayElements()); |
| 4142 switch (array->GetElementsKind()) { | 4106 switch (array->GetElementsKind()) { |
| 4143 case JSObject::FAST_ELEMENTS: | 4107 case JSObject::FAST_ELEMENTS: |
| 4144 return UnionOfKeys(FixedArray::cast(array->elements())); | 4108 return UnionOfKeys(FixedArray::cast(array->elements())); |
| 4145 case JSObject::DICTIONARY_ELEMENTS: { | 4109 case JSObject::DICTIONARY_ELEMENTS: { |
| 4146 NumberDictionary* dict = array->element_dictionary(); | 4110 NumberDictionary* dict = array->element_dictionary(); |
| 4147 int size = dict->NumberOfElements(); | 4111 int size = dict->NumberOfElements(); |
| 4148 | 4112 |
| 4149 // Allocate a temporary fixed array. | 4113 // Allocate a temporary fixed array. |
| 4150 Object* object; | 4114 Object* object; |
| 4151 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size); | 4115 { MaybeObject* maybe_object = heap->AllocateFixedArray(size); |
| 4152 if (!maybe_object->ToObject(&object)) return maybe_object; | 4116 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 4153 } | 4117 } |
| 4154 FixedArray* key_array = FixedArray::cast(object); | 4118 FixedArray* key_array = FixedArray::cast(object); |
| 4155 | 4119 |
| 4156 int capacity = dict->Capacity(); | 4120 int capacity = dict->Capacity(); |
| 4157 int pos = 0; | 4121 int pos = 0; |
| 4158 // Copy the elements from the JSArray to the temporary fixed array. | 4122 // Copy the elements from the JSArray to the temporary fixed array. |
| 4159 for (int i = 0; i < capacity; i++) { | 4123 for (int i = 0; i < capacity; i++) { |
| 4160 if (dict->IsKey(dict->KeyAt(i))) { | 4124 if (dict->IsKey(dict->KeyAt(i))) { |
| 4161 key_array->set(pos++, dict->ValueAt(i)); | 4125 key_array->set(pos++, dict->ValueAt(i)); |
| 4162 } | 4126 } |
| 4163 } | 4127 } |
| 4164 // Compute the union of this and the temporary fixed array. | 4128 // Compute the union of this and the temporary fixed array. |
| 4165 return UnionOfKeys(key_array); | 4129 return UnionOfKeys(key_array); |
| 4166 } | 4130 } |
| 4167 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: | 4131 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: |
| 4168 UNIMPLEMENTED(); | 4132 UNIMPLEMENTED(); |
| 4169 break; | 4133 break; |
| 4170 case JSObject::EXTERNAL_BYTE_ELEMENTS: | 4134 case JSObject::EXTERNAL_BYTE_ELEMENTS: |
| 4171 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4135 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4172 case JSObject::EXTERNAL_SHORT_ELEMENTS: | 4136 case JSObject::EXTERNAL_SHORT_ELEMENTS: |
| 4173 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 4137 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 4174 case JSObject::EXTERNAL_INT_ELEMENTS: | 4138 case JSObject::EXTERNAL_INT_ELEMENTS: |
| 4175 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | 4139 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 4176 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 4140 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
| 4177 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | 4141 case JSObject::EXTERNAL_PIXEL_ELEMENTS: |
| 4178 break; | 4142 break; |
| 4179 } | 4143 } |
| 4180 UNREACHABLE(); | 4144 UNREACHABLE(); |
| 4181 return GetHeap()->null_value(); // Failure case needs to "return" a value. | 4145 return heap->null_value(); // Failure case needs to "return" a value. |
| 4182 } | 4146 } |
| 4183 | 4147 |
| 4184 | 4148 |
| 4185 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { | 4149 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| 4150 Heap* heap = GetHeap(); |
| 4186 int len0 = length(); | 4151 int len0 = length(); |
| 4187 #ifdef DEBUG | 4152 #ifdef DEBUG |
| 4188 if (FLAG_enable_slow_asserts) { | 4153 if (FLAG_enable_slow_asserts) { |
| 4189 for (int i = 0; i < len0; i++) { | 4154 for (int i = 0; i < len0; i++) { |
| 4190 ASSERT(get(i)->IsString() || get(i)->IsNumber()); | 4155 ASSERT(get(i)->IsString() || get(i)->IsNumber()); |
| 4191 } | 4156 } |
| 4192 } | 4157 } |
| 4193 #endif | 4158 #endif |
| 4194 int len1 = other->length(); | 4159 int len1 = other->length(); |
| 4195 // Optimize if 'other' is empty. | 4160 // Optimize if 'other' is empty. |
| 4196 // We cannot optimize if 'this' is empty, as other may have holes | 4161 // We cannot optimize if 'this' is empty, as other may have holes |
| 4197 // or non keys. | 4162 // or non keys. |
| 4198 if (len1 == 0) return this; | 4163 if (len1 == 0) return this; |
| 4199 | 4164 |
| 4200 // Compute how many elements are not in this. | 4165 // Compute how many elements are not in this. |
| 4201 int extra = 0; | 4166 int extra = 0; |
| 4202 for (int y = 0; y < len1; y++) { | 4167 for (int y = 0; y < len1; y++) { |
| 4203 Object* value = other->get(y); | 4168 Object* value = other->get(y); |
| 4204 if (!value->IsTheHole() && !HasKey(this, value)) extra++; | 4169 if (!value->IsTheHole() && !HasKey(this, value)) extra++; |
| 4205 } | 4170 } |
| 4206 | 4171 |
| 4207 if (extra == 0) return this; | 4172 if (extra == 0) return this; |
| 4208 | 4173 |
| 4209 // Allocate the result | 4174 // Allocate the result |
| 4210 Object* obj; | 4175 Object* obj; |
| 4211 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); | 4176 { MaybeObject* maybe_obj = heap->AllocateFixedArray(len0 + extra); |
| 4212 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4177 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4213 } | 4178 } |
| 4214 // Fill in the content | 4179 // Fill in the content |
| 4215 AssertNoAllocation no_gc; | 4180 AssertNoAllocation no_gc; |
| 4216 FixedArray* result = FixedArray::cast(obj); | 4181 FixedArray* result = FixedArray::cast(obj); |
| 4217 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4182 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 4218 for (int i = 0; i < len0; i++) { | 4183 for (int i = 0; i < len0; i++) { |
| 4219 Object* e = get(i); | 4184 Object* e = get(i); |
| 4220 ASSERT(e->IsString() || e->IsNumber()); | 4185 ASSERT(e->IsString() || e->IsNumber()); |
| 4221 result->set(i, e, mode); | 4186 result->set(i, e, mode); |
| (...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5521 return CompareStringContentsPartial(isolate, | 5486 return CompareStringContentsPartial(isolate, |
| 5522 isolate->objects_string_compare_buffer_a(), rhs); | 5487 isolate->objects_string_compare_buffer_a(), rhs); |
| 5523 } | 5488 } |
| 5524 } | 5489 } |
| 5525 | 5490 |
| 5526 | 5491 |
| 5527 bool String::MarkAsUndetectable() { | 5492 bool String::MarkAsUndetectable() { |
| 5528 if (StringShape(this).IsSymbol()) return false; | 5493 if (StringShape(this).IsSymbol()) return false; |
| 5529 | 5494 |
| 5530 Map* map = this->map(); | 5495 Map* map = this->map(); |
| 5531 Heap* heap = map->heap(); | 5496 Heap* heap = map->GetHeap(); |
| 5532 if (map == heap->string_map()) { | 5497 if (map == heap->string_map()) { |
| 5533 this->set_map(heap->undetectable_string_map()); | 5498 this->set_map(heap->undetectable_string_map()); |
| 5534 return true; | 5499 return true; |
| 5535 } else if (map == heap->ascii_string_map()) { | 5500 } else if (map == heap->ascii_string_map()) { |
| 5536 this->set_map(heap->undetectable_ascii_string_map()); | 5501 this->set_map(heap->undetectable_ascii_string_map()); |
| 5537 return true; | 5502 return true; |
| 5538 } | 5503 } |
| 5539 // Rest cannot be marked as undetectable | 5504 // Rest cannot be marked as undetectable |
| 5540 return false; | 5505 return false; |
| 5541 } | 5506 } |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5850 | 5815 |
| 5851 MaybeObject* JSFunction::SetPrototype(Object* value) { | 5816 MaybeObject* JSFunction::SetPrototype(Object* value) { |
| 5852 ASSERT(should_have_prototype()); | 5817 ASSERT(should_have_prototype()); |
| 5853 Object* construct_prototype = value; | 5818 Object* construct_prototype = value; |
| 5854 | 5819 |
| 5855 // If the value is not a JSObject, store the value in the map's | 5820 // If the value is not a JSObject, store the value in the map's |
| 5856 // constructor field so it can be accessed. Also, set the prototype | 5821 // constructor field so it can be accessed. Also, set the prototype |
| 5857 // used for constructing objects to the original object prototype. | 5822 // used for constructing objects to the original object prototype. |
| 5858 // See ECMA-262 13.2.2. | 5823 // See ECMA-262 13.2.2. |
| 5859 if (!value->IsJSObject()) { | 5824 if (!value->IsJSObject()) { |
| 5825 Heap* heap = GetHeap(); |
| 5860 // Copy the map so this does not affect unrelated functions. | 5826 // Copy the map so this does not affect unrelated functions. |
| 5861 // Remove map transitions because they point to maps with a | 5827 // Remove map transitions because they point to maps with a |
| 5862 // different prototype. | 5828 // different prototype. |
| 5863 Object* new_object; | 5829 Object* new_map; |
| 5864 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); | 5830 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); |
| 5865 if (!maybe_new_map->ToObject(&new_object)) return maybe_new_map; | 5831 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 5866 } | 5832 } |
| 5867 Map* new_map = Map::cast(new_object); | 5833 set_map(Map::cast(new_map)); |
| 5868 Heap* heap = new_map->heap(); | 5834 map()->set_constructor(value); |
| 5869 set_map(new_map); | 5835 map()->set_non_instance_prototype(true); |
| 5870 new_map->set_constructor(value); | |
| 5871 new_map->set_non_instance_prototype(true); | |
| 5872 construct_prototype = | 5836 construct_prototype = |
| 5873 heap->isolate()->context()->global_context()-> | 5837 heap->isolate()->context()->global_context()-> |
| 5874 initial_object_prototype(); | 5838 initial_object_prototype(); |
| 5875 } else { | 5839 } else { |
| 5876 map()->set_non_instance_prototype(false); | 5840 map()->set_non_instance_prototype(false); |
| 5877 } | 5841 } |
| 5878 | 5842 |
| 5879 return SetInstancePrototype(construct_prototype); | 5843 return SetInstancePrototype(construct_prototype); |
| 5880 } | 5844 } |
| 5881 | 5845 |
| 5882 | 5846 |
| 5883 Object* JSFunction::RemovePrototype() { | 5847 Object* JSFunction::RemovePrototype() { |
| 5884 Context* global_context = context()->global_context(); | 5848 Context* global_context = context()->global_context(); |
| 5885 Map* no_prototype_map = shared()->strict_mode() | 5849 Map* no_prototype_map = shared()->strict_mode() |
| 5886 ? global_context->strict_mode_function_without_prototype_map() | 5850 ? global_context->strict_mode_function_without_prototype_map() |
| 5887 : global_context->function_without_prototype_map(); | 5851 : global_context->function_without_prototype_map(); |
| 5888 | 5852 |
| 5889 if (map() == no_prototype_map) { | 5853 if (map() == no_prototype_map) { |
| 5890 // Be idempotent. | 5854 // Be idempotent. |
| 5891 return this; | 5855 return this; |
| 5892 } | 5856 } |
| 5893 | 5857 |
| 5894 ASSERT(!shared()->strict_mode() || | 5858 ASSERT(!shared()->strict_mode() || |
| 5895 map() == global_context->strict_mode_function_map()); | 5859 map() == global_context->strict_mode_function_map()); |
| 5896 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); | 5860 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); |
| 5897 | 5861 |
| 5898 set_map(no_prototype_map); | 5862 set_map(no_prototype_map); |
| 5899 set_prototype_or_initial_map(no_prototype_map->heap()->the_hole_value()); | 5863 set_prototype_or_initial_map(GetHeap()->the_hole_value()); |
| 5900 return this; | 5864 return this; |
| 5901 } | 5865 } |
| 5902 | 5866 |
| 5903 | 5867 |
| 5904 Object* JSFunction::SetInstanceClassName(String* name) { | 5868 Object* JSFunction::SetInstanceClassName(String* name) { |
| 5905 shared()->set_instance_class_name(name); | 5869 shared()->set_instance_class_name(name); |
| 5906 return this; | 5870 return this; |
| 5907 } | 5871 } |
| 5908 | 5872 |
| 5909 | 5873 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5971 return instance_size; | 5935 return instance_size; |
| 5972 } | 5936 } |
| 5973 | 5937 |
| 5974 | 5938 |
| 5975 int SharedFunctionInfo::CalculateInObjectProperties() { | 5939 int SharedFunctionInfo::CalculateInObjectProperties() { |
| 5976 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; | 5940 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
| 5977 } | 5941 } |
| 5978 | 5942 |
| 5979 | 5943 |
| 5980 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { | 5944 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { |
| 5945 Heap* heap = GetHeap(); |
| 5946 |
| 5981 // Check the basic conditions for generating inline constructor code. | 5947 // Check the basic conditions for generating inline constructor code. |
| 5982 if (!FLAG_inline_new | 5948 if (!FLAG_inline_new |
| 5983 || !has_only_simple_this_property_assignments() | 5949 || !has_only_simple_this_property_assignments() |
| 5984 || this_property_assignments_count() == 0) { | 5950 || this_property_assignments_count() == 0) { |
| 5985 return false; | 5951 return false; |
| 5986 } | 5952 } |
| 5987 | 5953 |
| 5988 // If the prototype is null inline constructors cause no problems. | 5954 // If the prototype is null inline constructors cause no problems. |
| 5989 if (!prototype->IsJSObject()) { | 5955 if (!prototype->IsJSObject()) { |
| 5990 ASSERT(prototype->IsNull()); | 5956 ASSERT(prototype->IsNull()); |
| 5991 return true; | 5957 return true; |
| 5992 } | 5958 } |
| 5993 | 5959 |
| 5994 Heap* heap = GetHeap(); | |
| 5995 | |
| 5996 // Traverse the proposed prototype chain looking for setters for properties of | 5960 // Traverse the proposed prototype chain looking for setters for properties of |
| 5997 // the same names as are set by the inline constructor. | 5961 // the same names as are set by the inline constructor. |
| 5998 for (Object* obj = prototype; | 5962 for (Object* obj = prototype; |
| 5999 obj != heap->null_value(); | 5963 obj != heap->null_value(); |
| 6000 obj = obj->GetPrototype()) { | 5964 obj = obj->GetPrototype()) { |
| 6001 JSObject* js_object = JSObject::cast(obj); | 5965 JSObject* js_object = JSObject::cast(obj); |
| 6002 for (int i = 0; i < this_property_assignments_count(); i++) { | 5966 for (int i = 0; i < this_property_assignments_count(); i++) { |
| 6003 LookupResult result; | 5967 LookupResult result; |
| 6004 String* name = GetThisPropertyAssignmentName(i); | 5968 String* name = GetThisPropertyAssignmentName(i); |
| 6005 js_object->LocalLookupRealNamedProperty(name, &result); | 5969 js_object->LocalLookupRealNamedProperty(name, &result); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6305 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 6269 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
| 6306 rinfo->IsPatchedDebugBreakSlotSequence())); | 6270 rinfo->IsPatchedDebugBreakSlotSequence())); |
| 6307 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 6271 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
| 6308 Object* old_target = target; | 6272 Object* old_target = target; |
| 6309 VisitPointer(&target); | 6273 VisitPointer(&target); |
| 6310 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 6274 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
| 6311 } | 6275 } |
| 6312 | 6276 |
| 6313 | 6277 |
| 6314 void Code::InvalidateRelocation() { | 6278 void Code::InvalidateRelocation() { |
| 6315 set_relocation_info(heap()->empty_byte_array()); | 6279 set_relocation_info(GetHeap()->empty_byte_array()); |
| 6316 } | 6280 } |
| 6317 | 6281 |
| 6318 | 6282 |
| 6319 void Code::Relocate(intptr_t delta) { | 6283 void Code::Relocate(intptr_t delta) { |
| 6320 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 6284 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
| 6321 it.rinfo()->apply(delta); | 6285 it.rinfo()->apply(delta); |
| 6322 } | 6286 } |
| 6323 CPU::FlushICache(instruction_start(), instruction_size()); | 6287 CPU::FlushICache(instruction_start(), instruction_size()); |
| 6324 } | 6288 } |
| 6325 | 6289 |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6933 | 6897 |
| 6934 static Failure* ArrayLengthRangeError(Heap* heap) { | 6898 static Failure* ArrayLengthRangeError(Heap* heap) { |
| 6935 HandleScope scope; | 6899 HandleScope scope; |
| 6936 return heap->isolate()->Throw( | 6900 return heap->isolate()->Throw( |
| 6937 *FACTORY->NewRangeError("invalid_array_length", | 6901 *FACTORY->NewRangeError("invalid_array_length", |
| 6938 HandleVector<Object>(NULL, 0))); | 6902 HandleVector<Object>(NULL, 0))); |
| 6939 } | 6903 } |
| 6940 | 6904 |
| 6941 | 6905 |
| 6942 MaybeObject* JSObject::SetElementsLength(Object* len) { | 6906 MaybeObject* JSObject::SetElementsLength(Object* len) { |
| 6907 Heap* heap = GetHeap(); |
| 6943 // We should never end in here with a pixel or external array. | 6908 // We should never end in here with a pixel or external array. |
| 6944 ASSERT(AllowsSetElementsLength()); | 6909 ASSERT(AllowsSetElementsLength()); |
| 6945 | 6910 |
| 6946 MaybeObject* maybe_smi_length = len->ToSmi(); | 6911 MaybeObject* maybe_smi_length = len->ToSmi(); |
| 6947 Object* smi_length = Smi::FromInt(0); | 6912 Object* smi_length = Smi::FromInt(0); |
| 6948 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { | 6913 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
| 6949 const int value = Smi::cast(smi_length)->value(); | 6914 const int value = Smi::cast(smi_length)->value(); |
| 6950 if (value < 0) return ArrayLengthRangeError(GetHeap()); | 6915 if (value < 0) return ArrayLengthRangeError(heap); |
| 6951 switch (GetElementsKind()) { | 6916 switch (GetElementsKind()) { |
| 6952 case FAST_ELEMENTS: { | 6917 case FAST_ELEMENTS: { |
| 6953 int old_capacity = FixedArray::cast(elements())->length(); | 6918 int old_capacity = FixedArray::cast(elements())->length(); |
| 6954 if (value <= old_capacity) { | 6919 if (value <= old_capacity) { |
| 6955 if (IsJSArray()) { | 6920 if (IsJSArray()) { |
| 6956 Object* obj; | 6921 Object* obj; |
| 6957 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 6922 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 6958 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6923 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6959 } | 6924 } |
| 6960 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 6925 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7014 break; | 6979 break; |
| 7015 } | 6980 } |
| 7016 } | 6981 } |
| 7017 | 6982 |
| 7018 // General slow case. | 6983 // General slow case. |
| 7019 if (len->IsNumber()) { | 6984 if (len->IsNumber()) { |
| 7020 uint32_t length; | 6985 uint32_t length; |
| 7021 if (len->ToArrayIndex(&length)) { | 6986 if (len->ToArrayIndex(&length)) { |
| 7022 return SetSlowElements(len); | 6987 return SetSlowElements(len); |
| 7023 } else { | 6988 } else { |
| 7024 return ArrayLengthRangeError(GetHeap()); | 6989 return ArrayLengthRangeError(heap); |
| 7025 } | 6990 } |
| 7026 } | 6991 } |
| 7027 | 6992 |
| 7028 // len is not a number so make the array size one and | 6993 // len is not a number so make the array size one and |
| 7029 // set only element to len. | 6994 // set only element to len. |
| 7030 Object* obj; | 6995 Object* obj; |
| 7031 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); | 6996 { MaybeObject* maybe_obj = heap->AllocateFixedArray(1); |
| 7032 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6997 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7033 } | 6998 } |
| 7034 FixedArray::cast(obj)->set(0, len); | 6999 FixedArray::cast(obj)->set(0, len); |
| 7035 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 7000 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); |
| 7036 set_elements(FixedArray::cast(obj)); | 7001 set_elements(FixedArray::cast(obj)); |
| 7037 return this; | 7002 return this; |
| 7038 } | 7003 } |
| 7039 | 7004 |
| 7040 | 7005 |
| 7041 MaybeObject* JSObject::SetPrototype(Object* value, | 7006 MaybeObject* JSObject::SetPrototype(Object* value, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7176 VMState state(isolate, EXTERNAL); | 7141 VMState state(isolate, EXTERNAL); |
| 7177 result = getter(index, info); | 7142 result = getter(index, info); |
| 7178 } | 7143 } |
| 7179 if (!result.IsEmpty()) return true; | 7144 if (!result.IsEmpty()) return true; |
| 7180 } | 7145 } |
| 7181 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); | 7146 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); |
| 7182 } | 7147 } |
| 7183 | 7148 |
| 7184 | 7149 |
| 7185 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { | 7150 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { |
| 7151 Heap* heap = GetHeap(); |
| 7152 |
| 7186 // Check access rights if needed. | 7153 // Check access rights if needed. |
| 7187 if (IsAccessCheckNeeded()) { | 7154 if (IsAccessCheckNeeded() && |
| 7188 Heap* heap = GetHeap(); | 7155 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 7189 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7156 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 7190 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7157 return UNDEFINED_ELEMENT; |
| 7191 return UNDEFINED_ELEMENT; | |
| 7192 } | |
| 7193 } | 7158 } |
| 7194 | 7159 |
| 7195 if (IsJSGlobalProxy()) { | 7160 if (IsJSGlobalProxy()) { |
| 7196 Object* proto = GetPrototype(); | 7161 Object* proto = GetPrototype(); |
| 7197 if (proto->IsNull()) return UNDEFINED_ELEMENT; | 7162 if (proto->IsNull()) return UNDEFINED_ELEMENT; |
| 7198 ASSERT(proto->IsJSGlobalObject()); | 7163 ASSERT(proto->IsJSGlobalObject()); |
| 7199 return JSObject::cast(proto)->HasLocalElement(index); | 7164 return JSObject::cast(proto)->HasLocalElement(index); |
| 7200 } | 7165 } |
| 7201 | 7166 |
| 7202 // Check for lookup interceptor | 7167 // Check for lookup interceptor |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7290 if (NumberDictionary::cast(elements)->FindEntry(index) != | 7255 if (NumberDictionary::cast(elements)->FindEntry(index) != |
| 7291 NumberDictionary::kNotFound) { | 7256 NumberDictionary::kNotFound) { |
| 7292 return true; | 7257 return true; |
| 7293 } | 7258 } |
| 7294 } | 7259 } |
| 7295 return false; | 7260 return false; |
| 7296 } | 7261 } |
| 7297 | 7262 |
| 7298 | 7263 |
| 7299 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 7264 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 7265 Heap* heap = GetHeap(); |
| 7266 |
| 7300 // Check access rights if needed. | 7267 // Check access rights if needed. |
| 7301 if (IsAccessCheckNeeded()) { | 7268 if (IsAccessCheckNeeded() && |
| 7302 Heap* heap = GetHeap(); | 7269 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 7303 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7270 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 7304 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7271 return false; |
| 7305 return false; | |
| 7306 } | |
| 7307 } | 7272 } |
| 7308 | 7273 |
| 7309 // Check for lookup interceptor | 7274 // Check for lookup interceptor |
| 7310 if (HasIndexedInterceptor()) { | 7275 if (HasIndexedInterceptor()) { |
| 7311 return HasElementWithInterceptor(receiver, index); | 7276 return HasElementWithInterceptor(receiver, index); |
| 7312 } | 7277 } |
| 7313 | 7278 |
| 7314 ElementsKind kind = GetElementsKind(); | 7279 ElementsKind kind = GetElementsKind(); |
| 7315 switch (kind) { | 7280 switch (kind) { |
| 7316 case FAST_ELEMENTS: | 7281 case FAST_ELEMENTS: |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7696 #endif | 7661 #endif |
| 7697 } | 7662 } |
| 7698 return value; | 7663 return value; |
| 7699 } | 7664 } |
| 7700 | 7665 |
| 7701 | 7666 |
| 7702 MaybeObject* JSObject::SetElement(uint32_t index, | 7667 MaybeObject* JSObject::SetElement(uint32_t index, |
| 7703 Object* value, | 7668 Object* value, |
| 7704 StrictModeFlag strict_mode, | 7669 StrictModeFlag strict_mode, |
| 7705 bool check_prototype) { | 7670 bool check_prototype) { |
| 7671 Heap* heap = GetHeap(); |
| 7706 // Check access rights if needed. | 7672 // Check access rights if needed. |
| 7707 if (IsAccessCheckNeeded()) { | 7673 if (IsAccessCheckNeeded() && |
| 7708 Heap* heap = GetHeap(); | 7674 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 7709 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7675 HandleScope scope; |
| 7710 HandleScope scope; | 7676 Handle<Object> value_handle(value); |
| 7711 Handle<Object> value_handle(value); | 7677 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 7712 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7678 return *value_handle; |
| 7713 return *value_handle; | |
| 7714 } | |
| 7715 } | 7679 } |
| 7716 | 7680 |
| 7717 if (IsJSGlobalProxy()) { | 7681 if (IsJSGlobalProxy()) { |
| 7718 Object* proto = GetPrototype(); | 7682 Object* proto = GetPrototype(); |
| 7719 if (proto->IsNull()) return value; | 7683 if (proto->IsNull()) return value; |
| 7720 ASSERT(proto->IsJSGlobalObject()); | 7684 ASSERT(proto->IsJSGlobalObject()); |
| 7721 return JSObject::cast(proto)->SetElement(index, | 7685 return JSObject::cast(proto)->SetElement(index, |
| 7722 value, | 7686 value, |
| 7723 strict_mode, | 7687 strict_mode, |
| 7724 check_prototype); | 7688 check_prototype); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7827 if (!maybe_len->ToObject(&len)) return maybe_len; | 7791 if (!maybe_len->ToObject(&len)) return maybe_len; |
| 7828 } | 7792 } |
| 7829 set_length(len); | 7793 set_length(len); |
| 7830 } | 7794 } |
| 7831 return value; | 7795 return value; |
| 7832 } | 7796 } |
| 7833 | 7797 |
| 7834 | 7798 |
| 7835 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, | 7799 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, |
| 7836 uint32_t index) { | 7800 uint32_t index) { |
| 7801 Heap* heap = GetHeap(); |
| 7837 // Get element works for both JSObject and JSArray since | 7802 // Get element works for both JSObject and JSArray since |
| 7838 // JSArray::length cannot change. | 7803 // JSArray::length cannot change. |
| 7839 switch (GetElementsKind()) { | 7804 switch (GetElementsKind()) { |
| 7840 case FAST_ELEMENTS: { | 7805 case FAST_ELEMENTS: { |
| 7841 FixedArray* elms = FixedArray::cast(elements()); | 7806 FixedArray* elms = FixedArray::cast(elements()); |
| 7842 if (index < static_cast<uint32_t>(elms->length())) { | 7807 if (index < static_cast<uint32_t>(elms->length())) { |
| 7843 Object* value = elms->get(index); | 7808 Object* value = elms->get(index); |
| 7844 if (!value->IsTheHole()) return value; | 7809 if (!value->IsTheHole()) return value; |
| 7845 } | 7810 } |
| 7846 break; | 7811 break; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7875 } | 7840 } |
| 7876 break; | 7841 break; |
| 7877 } | 7842 } |
| 7878 case NON_STRICT_ARGUMENTS_ELEMENTS: | 7843 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 7879 UNIMPLEMENTED(); | 7844 UNIMPLEMENTED(); |
| 7880 break; | 7845 break; |
| 7881 } | 7846 } |
| 7882 | 7847 |
| 7883 // Continue searching via the prototype chain. | 7848 // Continue searching via the prototype chain. |
| 7884 Object* pt = GetPrototype(); | 7849 Object* pt = GetPrototype(); |
| 7885 if (pt->IsNull()) return GetHeap()->undefined_value(); | 7850 if (pt->IsNull()) return heap->undefined_value(); |
| 7886 return pt->GetElementWithReceiver(receiver, index); | 7851 return pt->GetElementWithReceiver(receiver, index); |
| 7887 } | 7852 } |
| 7888 | 7853 |
| 7889 | 7854 |
| 7890 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, | 7855 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
| 7891 uint32_t index) { | 7856 uint32_t index) { |
| 7892 Isolate* isolate = GetIsolate(); | 7857 Isolate* isolate = GetIsolate(); |
| 7893 // Make sure that the top context does not change when doing | 7858 // Make sure that the top context does not change when doing |
| 7894 // callbacks or interceptor calls. | 7859 // callbacks or interceptor calls. |
| 7895 AssertNoContextChange ncc; | 7860 AssertNoContextChange ncc; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 7917 | 7882 |
| 7918 MaybeObject* raw_result = | 7883 MaybeObject* raw_result = |
| 7919 holder_handle->GetElementPostInterceptor(*this_handle, index); | 7884 holder_handle->GetElementPostInterceptor(*this_handle, index); |
| 7920 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7885 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7921 return raw_result; | 7886 return raw_result; |
| 7922 } | 7887 } |
| 7923 | 7888 |
| 7924 | 7889 |
| 7925 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, | 7890 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, |
| 7926 uint32_t index) { | 7891 uint32_t index) { |
| 7892 Heap* heap = GetHeap(); |
| 7927 // Check access rights if needed. | 7893 // Check access rights if needed. |
| 7928 if (IsAccessCheckNeeded()) { | 7894 if (IsAccessCheckNeeded() && |
| 7929 Heap* heap = GetHeap(); | 7895 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
| 7930 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 7896 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 7931 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 7897 return heap->undefined_value(); |
| 7932 return heap->undefined_value(); | |
| 7933 } | |
| 7934 } | 7898 } |
| 7935 | 7899 |
| 7936 if (HasIndexedInterceptor()) { | 7900 if (HasIndexedInterceptor()) { |
| 7937 return GetElementWithInterceptor(receiver, index); | 7901 return GetElementWithInterceptor(receiver, index); |
| 7938 } | 7902 } |
| 7939 | 7903 |
| 7940 // Get element works for both JSObject and JSArray since | 7904 // Get element works for both JSObject and JSArray since |
| 7941 // JSArray::length cannot change. | 7905 // JSArray::length cannot change. |
| 7942 switch (GetElementsKind()) { | 7906 switch (GetElementsKind()) { |
| 7943 case FAST_ELEMENTS: { | 7907 case FAST_ELEMENTS: { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8008 } else if (index < static_cast<uint32_t>(arguments->length())) { | 7972 } else if (index < static_cast<uint32_t>(arguments->length())) { |
| 8009 Object* value = arguments->get(index); | 7973 Object* value = arguments->get(index); |
| 8010 if (!value->IsTheHole()) return value; | 7974 if (!value->IsTheHole()) return value; |
| 8011 } | 7975 } |
| 8012 } | 7976 } |
| 8013 break; | 7977 break; |
| 8014 } | 7978 } |
| 8015 } | 7979 } |
| 8016 | 7980 |
| 8017 Object* pt = GetPrototype(); | 7981 Object* pt = GetPrototype(); |
| 8018 Heap* heap = GetHeap(); | |
| 8019 if (pt == heap->null_value()) return heap->undefined_value(); | 7982 if (pt == heap->null_value()) return heap->undefined_value(); |
| 8020 return pt->GetElementWithReceiver(receiver, index); | 7983 return pt->GetElementWithReceiver(receiver, index); |
| 8021 } | 7984 } |
| 8022 | 7985 |
| 8023 | 7986 |
| 8024 MaybeObject* JSObject::GetExternalElement(uint32_t index) { | 7987 MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
| 8025 // Get element works for both JSObject and JSArray since | 7988 // Get element works for both JSObject and JSArray since |
| 8026 // JSArray::length cannot change. | 7989 // JSArray::length cannot change. |
| 8027 switch (GetElementsKind()) { | 7990 switch (GetElementsKind()) { |
| 8028 case EXTERNAL_PIXEL_ELEMENTS: { | 7991 case EXTERNAL_PIXEL_ELEMENTS: { |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8251 Object* result = | 8214 Object* result = |
| 8252 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 8215 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 8253 return InterceptorInfo::cast(result); | 8216 return InterceptorInfo::cast(result); |
| 8254 } | 8217 } |
| 8255 | 8218 |
| 8256 | 8219 |
| 8257 MaybeObject* JSObject::GetPropertyPostInterceptor( | 8220 MaybeObject* JSObject::GetPropertyPostInterceptor( |
| 8258 JSObject* receiver, | 8221 JSObject* receiver, |
| 8259 String* name, | 8222 String* name, |
| 8260 PropertyAttributes* attributes) { | 8223 PropertyAttributes* attributes) { |
| 8224 Heap* heap = GetHeap(); |
| 8261 // Check local property in holder, ignore interceptor. | 8225 // Check local property in holder, ignore interceptor. |
| 8262 LookupResult result; | 8226 LookupResult result; |
| 8263 LocalLookupRealNamedProperty(name, &result); | 8227 LocalLookupRealNamedProperty(name, &result); |
| 8264 if (result.IsProperty()) { | 8228 if (result.IsProperty()) { |
| 8265 return GetProperty(receiver, &result, name, attributes); | 8229 return GetProperty(receiver, &result, name, attributes); |
| 8266 } | 8230 } |
| 8267 // Continue searching via the prototype chain. | 8231 // Continue searching via the prototype chain. |
| 8268 Object* pt = GetPrototype(); | 8232 Object* pt = GetPrototype(); |
| 8269 *attributes = ABSENT; | 8233 *attributes = ABSENT; |
| 8270 if (pt->IsNull()) return GetHeap()->undefined_value(); | 8234 if (pt->IsNull()) return heap->undefined_value(); |
| 8271 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 8235 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
| 8272 } | 8236 } |
| 8273 | 8237 |
| 8274 | 8238 |
| 8275 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( | 8239 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
| 8276 JSObject* receiver, | 8240 JSObject* receiver, |
| 8277 String* name, | 8241 String* name, |
| 8278 PropertyAttributes* attributes) { | 8242 PropertyAttributes* attributes) { |
| 8243 Heap* heap = GetHeap(); |
| 8279 // Check local property in holder, ignore interceptor. | 8244 // Check local property in holder, ignore interceptor. |
| 8280 LookupResult result; | 8245 LookupResult result; |
| 8281 LocalLookupRealNamedProperty(name, &result); | 8246 LocalLookupRealNamedProperty(name, &result); |
| 8282 if (result.IsProperty()) { | 8247 if (result.IsProperty()) { |
| 8283 return GetProperty(receiver, &result, name, attributes); | 8248 return GetProperty(receiver, &result, name, attributes); |
| 8284 } | 8249 } |
| 8285 return GetHeap()->undefined_value(); | 8250 return heap->undefined_value(); |
| 8286 } | 8251 } |
| 8287 | 8252 |
| 8288 | 8253 |
| 8289 MaybeObject* JSObject::GetPropertyWithInterceptor( | 8254 MaybeObject* JSObject::GetPropertyWithInterceptor( |
| 8290 JSObject* receiver, | 8255 JSObject* receiver, |
| 8291 String* name, | 8256 String* name, |
| 8292 PropertyAttributes* attributes) { | 8257 PropertyAttributes* attributes) { |
| 8293 Isolate* isolate = GetIsolate(); | 8258 Isolate* isolate = GetIsolate(); |
| 8294 InterceptorInfo* interceptor = GetNamedInterceptor(); | 8259 InterceptorInfo* interceptor = GetNamedInterceptor(); |
| 8295 HandleScope scope(isolate); | 8260 HandleScope scope(isolate); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 8320 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( | 8285 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( |
| 8321 *receiver_handle, | 8286 *receiver_handle, |
| 8322 *name_handle, | 8287 *name_handle, |
| 8323 attributes); | 8288 attributes); |
| 8324 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 8289 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 8325 return result; | 8290 return result; |
| 8326 } | 8291 } |
| 8327 | 8292 |
| 8328 | 8293 |
| 8329 bool JSObject::HasRealNamedProperty(String* key) { | 8294 bool JSObject::HasRealNamedProperty(String* key) { |
| 8295 Heap* heap = GetHeap(); |
| 8330 // Check access rights if needed. | 8296 // Check access rights if needed. |
| 8331 if (IsAccessCheckNeeded()) { | 8297 if (IsAccessCheckNeeded() && |
| 8332 Heap* heap = GetHeap(); | 8298 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 8333 if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 8299 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 8334 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8300 return false; |
| 8335 return false; | |
| 8336 } | |
| 8337 } | 8301 } |
| 8338 | 8302 |
| 8339 LookupResult result; | 8303 LookupResult result; |
| 8340 LocalLookupRealNamedProperty(key, &result); | 8304 LocalLookupRealNamedProperty(key, &result); |
| 8341 return result.IsProperty() && (result.type() != INTERCEPTOR); | 8305 return result.IsProperty() && (result.type() != INTERCEPTOR); |
| 8342 } | 8306 } |
| 8343 | 8307 |
| 8344 | 8308 |
| 8345 bool JSObject::HasRealElementProperty(uint32_t index) { | 8309 bool JSObject::HasRealElementProperty(uint32_t index) { |
| 8310 Heap* heap = GetHeap(); |
| 8346 // Check access rights if needed. | 8311 // Check access rights if needed. |
| 8347 if (IsAccessCheckNeeded()) { | 8312 if (IsAccessCheckNeeded() && |
| 8348 Heap* heap = GetHeap(); | 8313 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 8349 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 8314 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 8350 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8315 return false; |
| 8351 return false; | |
| 8352 } | |
| 8353 } | 8316 } |
| 8354 | 8317 |
| 8355 // Handle [] on String objects. | 8318 // Handle [] on String objects. |
| 8356 if (this->IsStringObjectWithCharacterAt(index)) return true; | 8319 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 8357 | 8320 |
| 8358 switch (GetElementsKind()) { | 8321 switch (GetElementsKind()) { |
| 8359 case FAST_ELEMENTS: { | 8322 case FAST_ELEMENTS: { |
| 8360 uint32_t length = IsJSArray() ? | 8323 uint32_t length = IsJSArray() ? |
| 8361 static_cast<uint32_t>( | 8324 static_cast<uint32_t>( |
| 8362 Smi::cast(JSArray::cast(this)->length())->value()) : | 8325 Smi::cast(JSArray::cast(this)->length())->value()) : |
| (...skipping 18 matching lines...) Expand all Loading... |
| 8381 case DICTIONARY_ELEMENTS: { | 8344 case DICTIONARY_ELEMENTS: { |
| 8382 return element_dictionary()->FindEntry(index) | 8345 return element_dictionary()->FindEntry(index) |
| 8383 != NumberDictionary::kNotFound; | 8346 != NumberDictionary::kNotFound; |
| 8384 } | 8347 } |
| 8385 case NON_STRICT_ARGUMENTS_ELEMENTS: | 8348 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 8386 UNIMPLEMENTED(); | 8349 UNIMPLEMENTED(); |
| 8387 break; | 8350 break; |
| 8388 } | 8351 } |
| 8389 // All possibilities have been handled above already. | 8352 // All possibilities have been handled above already. |
| 8390 UNREACHABLE(); | 8353 UNREACHABLE(); |
| 8391 return GetHeap()->null_value(); | 8354 return heap->null_value(); |
| 8392 } | 8355 } |
| 8393 | 8356 |
| 8394 | 8357 |
| 8395 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 8358 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 8359 Heap* heap = GetHeap(); |
| 8396 // Check access rights if needed. | 8360 // Check access rights if needed. |
| 8397 if (IsAccessCheckNeeded()) { | 8361 if (IsAccessCheckNeeded() && |
| 8398 Heap* heap = GetHeap(); | 8362 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 8399 if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 8363 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 8400 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8364 return false; |
| 8401 return false; | |
| 8402 } | |
| 8403 } | 8365 } |
| 8404 | 8366 |
| 8405 LookupResult result; | 8367 LookupResult result; |
| 8406 LocalLookupRealNamedProperty(key, &result); | 8368 LocalLookupRealNamedProperty(key, &result); |
| 8407 return result.IsProperty() && (result.type() == CALLBACKS); | 8369 return result.IsProperty() && (result.type() == CALLBACKS); |
| 8408 } | 8370 } |
| 8409 | 8371 |
| 8410 | 8372 |
| 8411 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 8373 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
| 8412 if (HasFastProperties()) { | 8374 if (HasFastProperties()) { |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9053 } | 9015 } |
| 9054 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); | 9016 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); |
| 9055 entry = NextProbe(entry, count++, capacity); | 9017 entry = NextProbe(entry, count++, capacity); |
| 9056 } | 9018 } |
| 9057 return kNotFound; | 9019 return kNotFound; |
| 9058 } | 9020 } |
| 9059 | 9021 |
| 9060 | 9022 |
| 9061 template<typename Shape, typename Key> | 9023 template<typename Shape, typename Key> |
| 9062 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 9024 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
| 9025 Heap* heap = GetHeap(); |
| 9063 int capacity = Capacity(); | 9026 int capacity = Capacity(); |
| 9064 int nof = NumberOfElements() + n; | 9027 int nof = NumberOfElements() + n; |
| 9065 int nod = NumberOfDeletedElements(); | 9028 int nod = NumberOfDeletedElements(); |
| 9066 // Return if: | 9029 // Return if: |
| 9067 // 50% is still free after adding n elements and | 9030 // 50% is still free after adding n elements and |
| 9068 // at most 50% of the free elements are deleted elements. | 9031 // at most 50% of the free elements are deleted elements. |
| 9069 if (nod <= (capacity - nof) >> 1) { | 9032 if (nod <= (capacity - nof) >> 1) { |
| 9070 int needed_free = nof >> 1; | 9033 int needed_free = nof >> 1; |
| 9071 if (nof + needed_free <= capacity) return this; | 9034 if (nof + needed_free <= capacity) return this; |
| 9072 } | 9035 } |
| 9073 | 9036 |
| 9074 const int kMinCapacityForPretenure = 256; | 9037 const int kMinCapacityForPretenure = 256; |
| 9075 bool pretenure = | 9038 bool pretenure = |
| 9076 (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this); | 9039 (capacity > kMinCapacityForPretenure) && !heap->InNewSpace(this); |
| 9077 Object* obj; | 9040 Object* obj; |
| 9078 { MaybeObject* maybe_obj = | 9041 { MaybeObject* maybe_obj = |
| 9079 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); | 9042 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); |
| 9080 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9043 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 9081 } | 9044 } |
| 9082 | 9045 |
| 9083 AssertNoAllocation no_gc; | 9046 AssertNoAllocation no_gc; |
| 9084 HashTable* table = HashTable::cast(obj); | 9047 HashTable* table = HashTable::cast(obj); |
| 9085 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); | 9048 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); |
| 9086 | 9049 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9198 template | 9161 template |
| 9199 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 9162 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
| 9200 | 9163 |
| 9201 template | 9164 template |
| 9202 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 9165 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
| 9203 | 9166 |
| 9204 | 9167 |
| 9205 // Collates undefined and unexisting elements below limit from position | 9168 // Collates undefined and unexisting elements below limit from position |
| 9206 // zero of the elements. The object stays in Dictionary mode. | 9169 // zero of the elements. The object stays in Dictionary mode. |
| 9207 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 9170 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 9171 Heap* heap = GetHeap(); |
| 9208 ASSERT(HasDictionaryElements()); | 9172 ASSERT(HasDictionaryElements()); |
| 9209 // Must stay in dictionary mode, either because of requires_slow_elements, | 9173 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 9210 // or because we are not going to sort (and therefore compact) all of the | 9174 // or because we are not going to sort (and therefore compact) all of the |
| 9211 // elements. | 9175 // elements. |
| 9212 NumberDictionary* dict = element_dictionary(); | 9176 NumberDictionary* dict = element_dictionary(); |
| 9213 HeapNumber* result_double = NULL; | 9177 HeapNumber* result_double = NULL; |
| 9214 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 9178 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 9215 // Allocate space for result before we start mutating the object. | 9179 // Allocate space for result before we start mutating the object. |
| 9216 Object* new_double; | 9180 Object* new_double; |
| 9217 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); | 9181 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); |
| 9218 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 9182 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
| 9219 } | 9183 } |
| 9220 result_double = HeapNumber::cast(new_double); | 9184 result_double = HeapNumber::cast(new_double); |
| 9221 } | 9185 } |
| 9222 | 9186 |
| 9223 Object* obj; | 9187 Object* obj; |
| 9224 { MaybeObject* maybe_obj = | 9188 { MaybeObject* maybe_obj = |
| 9225 NumberDictionary::Allocate(dict->NumberOfElements()); | 9189 NumberDictionary::Allocate(dict->NumberOfElements()); |
| 9226 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9190 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 9227 } | 9191 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9267 // allocation. Bailout. | 9231 // allocation. Bailout. |
| 9268 return Smi::FromInt(-1); | 9232 return Smi::FromInt(-1); |
| 9269 } | 9233 } |
| 9270 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); | 9234 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked(); |
| 9271 } | 9235 } |
| 9272 } | 9236 } |
| 9273 } | 9237 } |
| 9274 | 9238 |
| 9275 uint32_t result = pos; | 9239 uint32_t result = pos; |
| 9276 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); | 9240 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); |
| 9277 Heap* heap = GetHeap(); | |
| 9278 while (undefs > 0) { | 9241 while (undefs > 0) { |
| 9279 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 9242 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 9280 // Adding an entry with the key beyond smi-range requires | 9243 // Adding an entry with the key beyond smi-range requires |
| 9281 // allocation. Bailout. | 9244 // allocation. Bailout. |
| 9282 return Smi::FromInt(-1); | 9245 return Smi::FromInt(-1); |
| 9283 } | 9246 } |
| 9284 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> | 9247 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> |
| 9285 ToObjectUnchecked(); | 9248 ToObjectUnchecked(); |
| 9286 pos++; | 9249 pos++; |
| 9287 undefs--; | 9250 undefs--; |
| 9288 } | 9251 } |
| 9289 | 9252 |
| 9290 set_elements(new_dict); | 9253 set_elements(new_dict); |
| 9291 | 9254 |
| 9292 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 9255 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 9293 return Smi::FromInt(static_cast<int>(result)); | 9256 return Smi::FromInt(static_cast<int>(result)); |
| 9294 } | 9257 } |
| 9295 | 9258 |
| 9296 ASSERT_NE(NULL, result_double); | 9259 ASSERT_NE(NULL, result_double); |
| 9297 result_double->set_value(static_cast<double>(result)); | 9260 result_double->set_value(static_cast<double>(result)); |
| 9298 return result_double; | 9261 return result_double; |
| 9299 } | 9262 } |
| 9300 | 9263 |
| 9301 | 9264 |
| 9302 // Collects all defined (non-hole) and non-undefined (array) elements at | 9265 // Collects all defined (non-hole) and non-undefined (array) elements at |
| 9303 // the start of the elements array. | 9266 // the start of the elements array. |
| 9304 // If the object is in dictionary mode, it is converted to fast elements | 9267 // If the object is in dictionary mode, it is converted to fast elements |
| 9305 // mode. | 9268 // mode. |
| 9306 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { | 9269 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 9270 Heap* heap = GetHeap(); |
| 9307 ASSERT(!HasExternalArrayElements()); | 9271 ASSERT(!HasExternalArrayElements()); |
| 9308 | 9272 |
| 9309 Heap* heap = GetHeap(); | |
| 9310 | |
| 9311 if (HasDictionaryElements()) { | 9273 if (HasDictionaryElements()) { |
| 9312 // Convert to fast elements containing only the existing properties. | 9274 // Convert to fast elements containing only the existing properties. |
| 9313 // Ordering is irrelevant, since we are going to sort anyway. | 9275 // Ordering is irrelevant, since we are going to sort anyway. |
| 9314 NumberDictionary* dict = element_dictionary(); | 9276 NumberDictionary* dict = element_dictionary(); |
| 9315 if (IsJSArray() || dict->requires_slow_elements() || | 9277 if (IsJSArray() || dict->requires_slow_elements() || |
| 9316 dict->max_number_key() >= limit) { | 9278 dict->max_number_key() >= limit) { |
| 9317 return PrepareSlowElementsForSort(limit); | 9279 return PrepareSlowElementsForSort(limit); |
| 9318 } | 9280 } |
| 9319 // Convert to fast elements. | 9281 // Convert to fast elements. |
| 9320 | 9282 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9554 | 9516 |
| 9555 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { | 9517 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
| 9556 ASSERT(!HasFastProperties()); | 9518 ASSERT(!HasFastProperties()); |
| 9557 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 9519 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 9558 return JSGlobalPropertyCell::cast(value); | 9520 return JSGlobalPropertyCell::cast(value); |
| 9559 } | 9521 } |
| 9560 | 9522 |
| 9561 | 9523 |
| 9562 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { | 9524 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { |
| 9563 ASSERT(!HasFastProperties()); | 9525 ASSERT(!HasFastProperties()); |
| 9526 Heap* heap = GetHeap(); |
| 9564 int entry = property_dictionary()->FindEntry(name); | 9527 int entry = property_dictionary()->FindEntry(name); |
| 9565 if (entry == StringDictionary::kNotFound) { | 9528 if (entry == StringDictionary::kNotFound) { |
| 9566 Heap* heap = GetHeap(); | |
| 9567 Object* cell; | 9529 Object* cell; |
| 9568 { MaybeObject* maybe_cell = | 9530 { MaybeObject* maybe_cell = |
| 9569 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); | 9531 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); |
| 9570 if (!maybe_cell->ToObject(&cell)) return maybe_cell; | 9532 if (!maybe_cell->ToObject(&cell)) return maybe_cell; |
| 9571 } | 9533 } |
| 9572 PropertyDetails details(NONE, NORMAL); | 9534 PropertyDetails details(NONE, NORMAL); |
| 9573 details = details.AsDeleted(); | 9535 details = details.AsDeleted(); |
| 9574 Object* dictionary; | 9536 Object* dictionary; |
| 9575 { MaybeObject* maybe_dictionary = | 9537 { MaybeObject* maybe_dictionary = |
| 9576 property_dictionary()->Add(name, cell, details); | 9538 property_dictionary()->Add(name, cell, details); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9731 // Add the new symbol and return it along with the symbol table. | 9693 // Add the new symbol and return it along with the symbol table. |
| 9732 entry = table->FindInsertionEntry(key->Hash()); | 9694 entry = table->FindInsertionEntry(key->Hash()); |
| 9733 table->set(EntryToIndex(entry), symbol); | 9695 table->set(EntryToIndex(entry), symbol); |
| 9734 table->ElementAdded(); | 9696 table->ElementAdded(); |
| 9735 *s = symbol; | 9697 *s = symbol; |
| 9736 return table; | 9698 return table; |
| 9737 } | 9699 } |
| 9738 | 9700 |
| 9739 | 9701 |
| 9740 Object* CompilationCacheTable::Lookup(String* src) { | 9702 Object* CompilationCacheTable::Lookup(String* src) { |
| 9703 Heap* heap = GetHeap(); |
| 9741 StringKey key(src); | 9704 StringKey key(src); |
| 9742 int entry = FindEntry(&key); | 9705 int entry = FindEntry(&key); |
| 9743 if (entry == kNotFound) return GetHeap()->undefined_value(); | 9706 if (entry == kNotFound) return heap->undefined_value(); |
| 9744 return get(EntryToIndex(entry) + 1); | 9707 return get(EntryToIndex(entry) + 1); |
| 9745 } | 9708 } |
| 9746 | 9709 |
| 9747 | 9710 |
| 9748 Object* CompilationCacheTable::LookupEval(String* src, | 9711 Object* CompilationCacheTable::LookupEval(String* src, |
| 9749 Context* context, | 9712 Context* context, |
| 9750 StrictModeFlag strict_mode) { | 9713 StrictModeFlag strict_mode) { |
| 9751 StringSharedKey key(src, context->closure()->shared(), strict_mode); | 9714 StringSharedKey key(src, context->closure()->shared(), strict_mode); |
| 9752 int entry = FindEntry(&key); | 9715 int entry = FindEntry(&key); |
| 9753 if (entry == kNotFound) return GetHeap()->undefined_value(); | 9716 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 9754 return get(EntryToIndex(entry) + 1); | 9717 return get(EntryToIndex(entry) + 1); |
| 9755 } | 9718 } |
| 9756 | 9719 |
| 9757 | 9720 |
| 9758 Object* CompilationCacheTable::LookupRegExp(String* src, | 9721 Object* CompilationCacheTable::LookupRegExp(String* src, |
| 9759 JSRegExp::Flags flags) { | 9722 JSRegExp::Flags flags) { |
| 9723 Heap* heap = GetHeap(); |
| 9760 RegExpKey key(src, flags); | 9724 RegExpKey key(src, flags); |
| 9761 int entry = FindEntry(&key); | 9725 int entry = FindEntry(&key); |
| 9762 if (entry == kNotFound) return GetHeap()->undefined_value(); | 9726 if (entry == kNotFound) return heap->undefined_value(); |
| 9763 return get(EntryToIndex(entry) + 1); | 9727 return get(EntryToIndex(entry) + 1); |
| 9764 } | 9728 } |
| 9765 | 9729 |
| 9766 | 9730 |
| 9767 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { | 9731 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { |
| 9768 StringKey key(src); | 9732 StringKey key(src); |
| 9769 Object* obj; | 9733 Object* obj; |
| 9770 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 9734 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 9771 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9735 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 9772 } | 9736 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9872 } | 9836 } |
| 9873 | 9837 |
| 9874 Object* AsObject() { return symbols_; } | 9838 Object* AsObject() { return symbols_; } |
| 9875 | 9839 |
| 9876 private: | 9840 private: |
| 9877 FixedArray* symbols_; | 9841 FixedArray* symbols_; |
| 9878 }; | 9842 }; |
| 9879 | 9843 |
| 9880 | 9844 |
| 9881 Object* MapCache::Lookup(FixedArray* array) { | 9845 Object* MapCache::Lookup(FixedArray* array) { |
| 9846 Heap* heap = GetHeap(); |
| 9882 SymbolsKey key(array); | 9847 SymbolsKey key(array); |
| 9883 int entry = FindEntry(&key); | 9848 int entry = FindEntry(&key); |
| 9884 if (entry == kNotFound) return GetHeap()->undefined_value(); | 9849 if (entry == kNotFound) return heap->undefined_value(); |
| 9885 return get(EntryToIndex(entry) + 1); | 9850 return get(EntryToIndex(entry) + 1); |
| 9886 } | 9851 } |
| 9887 | 9852 |
| 9888 | 9853 |
| 9889 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { | 9854 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { |
| 9890 SymbolsKey key(array); | 9855 SymbolsKey key(array); |
| 9891 Object* obj; | 9856 Object* obj; |
| 9892 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 9857 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
| 9893 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9858 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 9894 } | 9859 } |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10230 storage->set(index++, k); | 10195 storage->set(index++, k); |
| 10231 } | 10196 } |
| 10232 } | 10197 } |
| 10233 ASSERT(storage->length() >= index); | 10198 ASSERT(storage->length() >= index); |
| 10234 } | 10199 } |
| 10235 | 10200 |
| 10236 | 10201 |
| 10237 // Backwards lookup (slow). | 10202 // Backwards lookup (slow). |
| 10238 template<typename Shape, typename Key> | 10203 template<typename Shape, typename Key> |
| 10239 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 10204 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
| 10205 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 10240 int capacity = HashTable<Shape, Key>::Capacity(); | 10206 int capacity = HashTable<Shape, Key>::Capacity(); |
| 10241 for (int i = 0; i < capacity; i++) { | 10207 for (int i = 0; i < capacity; i++) { |
| 10242 Object* k = HashTable<Shape, Key>::KeyAt(i); | 10208 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 10243 if (Dictionary<Shape, Key>::IsKey(k)) { | 10209 if (Dictionary<Shape, Key>::IsKey(k)) { |
| 10244 Object* e = ValueAt(i); | 10210 Object* e = ValueAt(i); |
| 10245 if (e->IsJSGlobalPropertyCell()) { | 10211 if (e->IsJSGlobalPropertyCell()) { |
| 10246 e = JSGlobalPropertyCell::cast(e)->value(); | 10212 e = JSGlobalPropertyCell::cast(e)->value(); |
| 10247 } | 10213 } |
| 10248 if (e == value) return k; | 10214 if (e == value) return k; |
| 10249 } | 10215 } |
| 10250 } | 10216 } |
| 10251 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | |
| 10252 return heap->undefined_value(); | 10217 return heap->undefined_value(); |
| 10253 } | 10218 } |
| 10254 | 10219 |
| 10255 | 10220 |
| 10256 MaybeObject* StringDictionary::TransformPropertiesToFastFor( | 10221 MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
| 10257 JSObject* obj, int unused_property_fields) { | 10222 JSObject* obj, int unused_property_fields) { |
| 10223 Heap* heap = GetHeap(); |
| 10258 // Make sure we preserve dictionary representation if there are too many | 10224 // Make sure we preserve dictionary representation if there are too many |
| 10259 // descriptors. | 10225 // descriptors. |
| 10260 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 10226 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
| 10261 | 10227 |
| 10262 // Figure out if it is necessary to generate new enumeration indices. | 10228 // Figure out if it is necessary to generate new enumeration indices. |
| 10263 int max_enumeration_index = | 10229 int max_enumeration_index = |
| 10264 NextEnumerationIndex() + | 10230 NextEnumerationIndex() + |
| 10265 (DescriptorArray::kMaxNumberOfDescriptors - | 10231 (DescriptorArray::kMaxNumberOfDescriptors - |
| 10266 NumberOfElements()); | 10232 NumberOfElements()); |
| 10267 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { | 10233 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { |
| 10268 Object* result; | 10234 Object* result; |
| 10269 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 10235 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 10270 if (!maybe_result->ToObject(&result)) return maybe_result; | 10236 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 10271 } | 10237 } |
| 10272 } | 10238 } |
| 10273 | 10239 |
| 10274 int instance_descriptor_length = 0; | 10240 int instance_descriptor_length = 0; |
| 10275 int number_of_fields = 0; | 10241 int number_of_fields = 0; |
| 10276 | 10242 |
| 10277 Heap* heap = GetHeap(); | |
| 10278 | |
| 10279 // Compute the length of the instance descriptor. | 10243 // Compute the length of the instance descriptor. |
| 10280 int capacity = Capacity(); | 10244 int capacity = Capacity(); |
| 10281 for (int i = 0; i < capacity; i++) { | 10245 for (int i = 0; i < capacity; i++) { |
| 10282 Object* k = KeyAt(i); | 10246 Object* k = KeyAt(i); |
| 10283 if (IsKey(k)) { | 10247 if (IsKey(k)) { |
| 10284 Object* value = ValueAt(i); | 10248 Object* value = ValueAt(i); |
| 10285 PropertyType type = DetailsAt(i).type(); | 10249 PropertyType type = DetailsAt(i).type(); |
| 10286 ASSERT(type != FIELD); | 10250 ASSERT(type != FIELD); |
| 10287 instance_descriptor_length++; | 10251 instance_descriptor_length++; |
| 10288 if (type == NORMAL && | 10252 if (type == NORMAL && |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10397 | 10361 |
| 10398 // If there is no break point info object or no break points in the break | 10362 // If there is no break point info object or no break points in the break |
| 10399 // point info object there is no break point at this code position. | 10363 // point info object there is no break point at this code position. |
| 10400 if (break_point_info->IsUndefined()) return false; | 10364 if (break_point_info->IsUndefined()) return false; |
| 10401 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 10365 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
| 10402 } | 10366 } |
| 10403 | 10367 |
| 10404 | 10368 |
| 10405 // Get the break point info object for this code position. | 10369 // Get the break point info object for this code position. |
| 10406 Object* DebugInfo::GetBreakPointInfo(int code_position) { | 10370 Object* DebugInfo::GetBreakPointInfo(int code_position) { |
| 10371 Heap* heap = GetHeap(); |
| 10407 // Find the index of the break point info object for this code position. | 10372 // Find the index of the break point info object for this code position. |
| 10408 int index = GetBreakPointInfoIndex(code_position); | 10373 int index = GetBreakPointInfoIndex(code_position); |
| 10409 | 10374 |
| 10410 // Return the break point info object if any. | 10375 // Return the break point info object if any. |
| 10411 if (index == kNoBreakPointInfo) return GetHeap()->undefined_value(); | 10376 if (index == kNoBreakPointInfo) return heap->undefined_value(); |
| 10412 return BreakPointInfo::cast(break_points()->get(index)); | 10377 return BreakPointInfo::cast(break_points()->get(index)); |
| 10413 } | 10378 } |
| 10414 | 10379 |
| 10415 | 10380 |
| 10416 // Clear a break point at the specified code position. | 10381 // Clear a break point at the specified code position. |
| 10417 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, | 10382 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, |
| 10418 int code_position, | 10383 int code_position, |
| 10419 Handle<Object> break_point_object) { | 10384 Handle<Object> break_point_object) { |
| 10420 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); | 10385 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); |
| 10421 if (break_point_info->IsUndefined()) return; | 10386 if (break_point_info->IsUndefined()) return; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10474 set_statement_position(Smi::FromInt(statement_position)); | 10439 set_statement_position(Smi::FromInt(statement_position)); |
| 10475 new_break_point_info->set_break_point_objects( | 10440 new_break_point_info->set_break_point_objects( |
| 10476 isolate->heap()->undefined_value()); | 10441 isolate->heap()->undefined_value()); |
| 10477 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); | 10442 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
| 10478 debug_info->break_points()->set(index, *new_break_point_info); | 10443 debug_info->break_points()->set(index, *new_break_point_info); |
| 10479 } | 10444 } |
| 10480 | 10445 |
| 10481 | 10446 |
| 10482 // Get the break point objects for a code position. | 10447 // Get the break point objects for a code position. |
| 10483 Object* DebugInfo::GetBreakPointObjects(int code_position) { | 10448 Object* DebugInfo::GetBreakPointObjects(int code_position) { |
| 10449 Heap* heap = GetHeap(); |
| 10484 Object* break_point_info = GetBreakPointInfo(code_position); | 10450 Object* break_point_info = GetBreakPointInfo(code_position); |
| 10485 if (break_point_info->IsUndefined()) { | 10451 if (break_point_info->IsUndefined()) { |
| 10486 return GetHeap()->undefined_value(); | 10452 return heap->undefined_value(); |
| 10487 } | 10453 } |
| 10488 return BreakPointInfo::cast(break_point_info)->break_point_objects(); | 10454 return BreakPointInfo::cast(break_point_info)->break_point_objects(); |
| 10489 } | 10455 } |
| 10490 | 10456 |
| 10491 | 10457 |
| 10492 // Get the total number of break points. | 10458 // Get the total number of break points. |
| 10493 int DebugInfo::GetBreakPointCount() { | 10459 int DebugInfo::GetBreakPointCount() { |
| 10494 if (break_points()->IsUndefined()) return 0; | 10460 if (break_points()->IsUndefined()) return 0; |
| 10495 int count = 0; | 10461 int count = 0; |
| 10496 for (int i = 0; i < break_points()->length(); i++) { | 10462 for (int i = 0; i < break_points()->length(); i++) { |
| 10497 if (!break_points()->get(i)->IsUndefined()) { | 10463 if (!break_points()->get(i)->IsUndefined()) { |
| 10498 BreakPointInfo* break_point_info = | 10464 BreakPointInfo* break_point_info = |
| 10499 BreakPointInfo::cast(break_points()->get(i)); | 10465 BreakPointInfo::cast(break_points()->get(i)); |
| 10500 count += break_point_info->GetBreakPointCount(); | 10466 count += break_point_info->GetBreakPointCount(); |
| 10501 } | 10467 } |
| 10502 } | 10468 } |
| 10503 return count; | 10469 return count; |
| 10504 } | 10470 } |
| 10505 | 10471 |
| 10506 | 10472 |
| 10507 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, | 10473 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, |
| 10508 Handle<Object> break_point_object) { | 10474 Handle<Object> break_point_object) { |
| 10509 Heap* heap = debug_info->GetHeap(); | 10475 Heap* heap = Isolate::Current()->heap(); |
| 10510 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value(); | 10476 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value(); |
| 10511 for (int i = 0; i < debug_info->break_points()->length(); i++) { | 10477 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
| 10512 if (!debug_info->break_points()->get(i)->IsUndefined()) { | 10478 if (!debug_info->break_points()->get(i)->IsUndefined()) { |
| 10513 Handle<BreakPointInfo> break_point_info = | 10479 Handle<BreakPointInfo> break_point_info = |
| 10514 Handle<BreakPointInfo>(BreakPointInfo::cast( | 10480 Handle<BreakPointInfo>(BreakPointInfo::cast( |
| 10515 debug_info->break_points()->get(i))); | 10481 debug_info->break_points()->get(i))); |
| 10516 if (BreakPointInfo::HasBreakPointObject(break_point_info, | 10482 if (BreakPointInfo::HasBreakPointObject(break_point_info, |
| 10517 break_point_object)) { | 10483 break_point_object)) { |
| 10518 return *break_point_info; | 10484 return *break_point_info; |
| 10519 } | 10485 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10636 if (break_point_objects()->IsUndefined()) return 0; | 10602 if (break_point_objects()->IsUndefined()) return 0; |
| 10637 // Single beak point. | 10603 // Single beak point. |
| 10638 if (!break_point_objects()->IsFixedArray()) return 1; | 10604 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10639 // Multiple break points. | 10605 // Multiple break points. |
| 10640 return FixedArray::cast(break_point_objects())->length(); | 10606 return FixedArray::cast(break_point_objects())->length(); |
| 10641 } | 10607 } |
| 10642 #endif | 10608 #endif |
| 10643 | 10609 |
| 10644 | 10610 |
| 10645 } } // namespace v8::internal | 10611 } } // namespace v8::internal |
| OLD | NEW |