| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 CALL_HEAP_FUNCTION_PASS_EXCEPTION( | 800 CALL_HEAP_FUNCTION_PASS_EXCEPTION( |
| 801 isolate, | 801 isolate, |
| 802 object->GetProperty(*receiver, result, *key, attributes)); | 802 object->GetProperty(*receiver, result, *key, attributes)); |
| 803 } | 803 } |
| 804 | 804 |
| 805 | 805 |
| 806 MaybeObject* Object::GetProperty(Object* receiver, | 806 MaybeObject* Object::GetProperty(Object* receiver, |
| 807 LookupResult* result, | 807 LookupResult* result, |
| 808 Name* name, | 808 Name* name, |
| 809 PropertyAttributes* attributes) { | 809 PropertyAttributes* attributes) { |
| 810 Isolate* isolate = name->GetIsolate(); |
| 811 Heap* heap = isolate->heap(); |
| 812 |
| 813 #ifdef DEBUG |
| 814 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon |
| 815 // as this method has been fully handlified. |
| 816 HandleScope scope(isolate); |
| 817 #endif |
| 818 |
| 810 // Make sure that the top context does not change when doing | 819 // Make sure that the top context does not change when doing |
| 811 // callbacks or interceptor calls. | 820 // callbacks or interceptor calls. |
| 812 AssertNoContextChangeWithHandleScope ncc; | 821 AssertNoContextChange ncc(isolate); |
| 813 | |
| 814 Isolate* isolate = name->GetIsolate(); | |
| 815 Heap* heap = isolate->heap(); | |
| 816 | 822 |
| 817 // Traverse the prototype chain from the current object (this) to | 823 // Traverse the prototype chain from the current object (this) to |
| 818 // the holder and check for access rights. This avoids traversing the | 824 // the holder and check for access rights. This avoids traversing the |
| 819 // objects more than once in case of interceptors, because the | 825 // objects more than once in case of interceptors, because the |
| 820 // holder will always be the interceptor holder and the search may | 826 // holder will always be the interceptor holder and the search may |
| 821 // only continue with a current object just after the interceptor | 827 // only continue with a current object just after the interceptor |
| 822 // holder in the prototype chain. | 828 // holder in the prototype chain. |
| 823 // Proxy handlers do not use the proxy's prototype, so we can skip this. | 829 // Proxy handlers do not use the proxy's prototype, so we can skip this. |
| 824 if (!result->IsHandler()) { | 830 if (!result->IsHandler()) { |
| 825 Object* last = result->IsProperty() | 831 Object* last = result->IsProperty() |
| (...skipping 3077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3903 LookupResult* lookup, | 3909 LookupResult* lookup, |
| 3904 Handle<Name> name, | 3910 Handle<Name> name, |
| 3905 Handle<Object> value, | 3911 Handle<Object> value, |
| 3906 PropertyAttributes attributes, | 3912 PropertyAttributes attributes, |
| 3907 StrictModeFlag strict_mode, | 3913 StrictModeFlag strict_mode, |
| 3908 StoreFromKeyed store_mode) { | 3914 StoreFromKeyed store_mode) { |
| 3909 Isolate* isolate = object->GetIsolate(); | 3915 Isolate* isolate = object->GetIsolate(); |
| 3910 | 3916 |
| 3911 // Make sure that the top context does not change when doing callbacks or | 3917 // Make sure that the top context does not change when doing callbacks or |
| 3912 // interceptor calls. | 3918 // interceptor calls. |
| 3913 AssertNoContextChange ncc; | 3919 AssertNoContextChange ncc(isolate); |
| 3914 | 3920 |
| 3915 // Optimization for 2-byte strings often used as keys in a decompression | 3921 // Optimization for 2-byte strings often used as keys in a decompression |
| 3916 // dictionary. We internalize these short keys to avoid constantly | 3922 // dictionary. We internalize these short keys to avoid constantly |
| 3917 // reallocating them. | 3923 // reallocating them. |
| 3918 if (name->IsString() && !name->IsInternalizedString() && | 3924 if (name->IsString() && !name->IsInternalizedString() && |
| 3919 Handle<String>::cast(name)->length() <= 2) { | 3925 Handle<String>::cast(name)->length() <= 2) { |
| 3920 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); | 3926 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); |
| 3921 } | 3927 } |
| 3922 | 3928 |
| 3923 // Check access rights if needed. | 3929 // Check access rights if needed. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4061 Handle<Name> name, | 4067 Handle<Name> name, |
| 4062 Handle<Object> value, | 4068 Handle<Object> value, |
| 4063 PropertyAttributes attributes, | 4069 PropertyAttributes attributes, |
| 4064 ValueType value_type, | 4070 ValueType value_type, |
| 4065 StoreMode mode, | 4071 StoreMode mode, |
| 4066 ExtensibilityCheck extensibility_check) { | 4072 ExtensibilityCheck extensibility_check) { |
| 4067 Isolate* isolate = object->GetIsolate(); | 4073 Isolate* isolate = object->GetIsolate(); |
| 4068 | 4074 |
| 4069 // Make sure that the top context does not change when doing callbacks or | 4075 // Make sure that the top context does not change when doing callbacks or |
| 4070 // interceptor calls. | 4076 // interceptor calls. |
| 4071 AssertNoContextChange ncc; | 4077 AssertNoContextChange ncc(isolate); |
| 4072 | 4078 |
| 4073 LookupResult lookup(isolate); | 4079 LookupResult lookup(isolate); |
| 4074 object->LocalLookup(*name, &lookup, true); | 4080 object->LocalLookup(*name, &lookup, true); |
| 4075 if (!lookup.IsFound()) { | 4081 if (!lookup.IsFound()) { |
| 4076 object->map()->LookupTransition(*object, *name, &lookup); | 4082 object->map()->LookupTransition(*object, *name, &lookup); |
| 4077 } | 4083 } |
| 4078 | 4084 |
| 4079 // Check access rights if needed. | 4085 // Check access rights if needed. |
| 4080 if (object->IsAccessCheckNeeded()) { | 4086 if (object->IsAccessCheckNeeded()) { |
| 4081 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { | 4087 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4195 Name* name, | 4201 Name* name, |
| 4196 bool continue_search) { | 4202 bool continue_search) { |
| 4197 // TODO(rossberg): Support symbols in the API. | 4203 // TODO(rossberg): Support symbols in the API. |
| 4198 if (name->IsSymbol()) return ABSENT; | 4204 if (name->IsSymbol()) return ABSENT; |
| 4199 | 4205 |
| 4200 Isolate* isolate = GetIsolate(); | 4206 Isolate* isolate = GetIsolate(); |
| 4201 HandleScope scope(isolate); | 4207 HandleScope scope(isolate); |
| 4202 | 4208 |
| 4203 // Make sure that the top context does not change when doing | 4209 // Make sure that the top context does not change when doing |
| 4204 // callbacks or interceptor calls. | 4210 // callbacks or interceptor calls. |
| 4205 AssertNoContextChange ncc; | 4211 AssertNoContextChange ncc(isolate); |
| 4206 | 4212 |
| 4207 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 4213 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 4208 Handle<JSObject> receiver_handle(receiver); | 4214 Handle<JSObject> receiver_handle(receiver); |
| 4209 Handle<JSObject> holder_handle(this); | 4215 Handle<JSObject> holder_handle(this); |
| 4210 Handle<String> name_handle(String::cast(name)); | 4216 Handle<String> name_handle(String::cast(name)); |
| 4211 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this); | 4217 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this); |
| 4212 if (!interceptor->query()->IsUndefined()) { | 4218 if (!interceptor->query()->IsUndefined()) { |
| 4213 v8::NamedPropertyQueryCallback query = | 4219 v8::NamedPropertyQueryCallback query = |
| 4214 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); | 4220 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); |
| 4215 LOG(isolate, | 4221 LOG(isolate, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4330 } | 4336 } |
| 4331 | 4337 |
| 4332 | 4338 |
| 4333 PropertyAttributes JSObject::GetElementAttributeWithInterceptor( | 4339 PropertyAttributes JSObject::GetElementAttributeWithInterceptor( |
| 4334 JSReceiver* receiver, uint32_t index, bool continue_search) { | 4340 JSReceiver* receiver, uint32_t index, bool continue_search) { |
| 4335 Isolate* isolate = GetIsolate(); | 4341 Isolate* isolate = GetIsolate(); |
| 4336 HandleScope scope(isolate); | 4342 HandleScope scope(isolate); |
| 4337 | 4343 |
| 4338 // Make sure that the top context does not change when doing | 4344 // Make sure that the top context does not change when doing |
| 4339 // callbacks or interceptor calls. | 4345 // callbacks or interceptor calls. |
| 4340 AssertNoContextChange ncc; | 4346 AssertNoContextChange ncc(isolate); |
| 4341 | 4347 |
| 4342 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 4348 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 4343 Handle<JSReceiver> hreceiver(receiver); | 4349 Handle<JSReceiver> hreceiver(receiver); |
| 4344 Handle<JSObject> holder(this); | 4350 Handle<JSObject> holder(this); |
| 4345 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this); | 4351 PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this); |
| 4346 if (!interceptor->query()->IsUndefined()) { | 4352 if (!interceptor->query()->IsUndefined()) { |
| 4347 v8::IndexedPropertyQueryCallback query = | 4353 v8::IndexedPropertyQueryCallback query = |
| 4348 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); | 4354 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); |
| 4349 LOG(isolate, | 4355 LOG(isolate, |
| 4350 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); | 4356 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4442 for (int i = 0; i != entries; i++) { | 4448 for (int i = 0; i != entries; i++) { |
| 4443 set_undefined(i); | 4449 set_undefined(i); |
| 4444 } | 4450 } |
| 4445 } | 4451 } |
| 4446 | 4452 |
| 4447 | 4453 |
| 4448 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object, | 4454 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object, |
| 4449 Handle<Name> name, | 4455 Handle<Name> name, |
| 4450 Handle<Code> code) { | 4456 Handle<Code> code) { |
| 4451 Handle<Map> map(object->map()); | 4457 Handle<Map> map(object->map()); |
| 4452 if (map->is_shared()) { | |
| 4453 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | |
| 4454 // Fast case maps are never marked as shared. | |
| 4455 ASSERT(!receiver->HasFastProperties()); | |
| 4456 // Replace the map with an identical copy that can be safely modified. | |
| 4457 map = Map::CopyNormalized(map, KEEP_INOBJECT_PROPERTIES, | |
| 4458 UNIQUE_NORMALIZED_MAP); | |
| 4459 receiver->GetIsolate()->counters()->normalized_maps()->Increment(); | |
| 4460 receiver->set_map(*map); | |
| 4461 } | |
| 4462 Map::UpdateCodeCache(map, name, code); | 4458 Map::UpdateCodeCache(map, name, code); |
| 4463 } | 4459 } |
| 4464 | 4460 |
| 4465 | 4461 |
| 4466 void JSObject::NormalizeProperties(Handle<JSObject> object, | 4462 void JSObject::NormalizeProperties(Handle<JSObject> object, |
| 4467 PropertyNormalizationMode mode, | 4463 PropertyNormalizationMode mode, |
| 4468 int expected_additional_properties) { | 4464 int expected_additional_properties) { |
| 4469 if (!object->HasFastProperties()) return; | 4465 if (!object->HasFastProperties()) return; |
| 4470 | 4466 |
| 4471 // The global object is always normalized. | 4467 // The global object is always normalized. |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5040 } | 5036 } |
| 5041 | 5037 |
| 5042 | 5038 |
| 5043 Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object, | 5039 Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object, |
| 5044 uint32_t index) { | 5040 uint32_t index) { |
| 5045 Isolate* isolate = object->GetIsolate(); | 5041 Isolate* isolate = object->GetIsolate(); |
| 5046 Factory* factory = isolate->factory(); | 5042 Factory* factory = isolate->factory(); |
| 5047 | 5043 |
| 5048 // Make sure that the top context does not change when doing | 5044 // Make sure that the top context does not change when doing |
| 5049 // callbacks or interceptor calls. | 5045 // callbacks or interceptor calls. |
| 5050 AssertNoContextChange ncc; | 5046 AssertNoContextChange ncc(isolate); |
| 5051 | 5047 |
| 5052 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | 5048 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
| 5053 if (interceptor->deleter()->IsUndefined()) return factory->false_value(); | 5049 if (interceptor->deleter()->IsUndefined()) return factory->false_value(); |
| 5054 v8::IndexedPropertyDeleterCallback deleter = | 5050 v8::IndexedPropertyDeleterCallback deleter = |
| 5055 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); | 5051 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); |
| 5056 LOG(isolate, | 5052 LOG(isolate, |
| 5057 ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index)); | 5053 ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index)); |
| 5058 PropertyCallbackArguments args( | 5054 PropertyCallbackArguments args( |
| 5059 isolate, interceptor->data(), *object, *object); | 5055 isolate, interceptor->data(), *object, *object); |
| 5060 v8::Handle<v8::Boolean> result = args.Call(deleter, index); | 5056 v8::Handle<v8::Boolean> result = args.Call(deleter, index); |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5576 } | 5572 } |
| 5577 | 5573 |
| 5578 | 5574 |
| 5579 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { | 5575 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { |
| 5580 Isolate* isolate = object->GetIsolate(); | 5576 Isolate* isolate = object->GetIsolate(); |
| 5581 CALL_HEAP_FUNCTION(isolate, | 5577 CALL_HEAP_FUNCTION(isolate, |
| 5582 isolate->heap()->CopyJSObject(*object), JSObject); | 5578 isolate->heap()->CopyJSObject(*object), JSObject); |
| 5583 } | 5579 } |
| 5584 | 5580 |
| 5585 | 5581 |
| 5586 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { | 5582 class JSObjectWalkVisitor { |
| 5583 public: |
| 5584 explicit JSObjectWalkVisitor() {} |
| 5585 virtual ~JSObjectWalkVisitor() {} |
| 5586 |
| 5587 Handle<JSObject> Visit(Handle<JSObject> object) { |
| 5588 return StructureWalk(object); |
| 5589 } |
| 5590 |
| 5591 // Returns true if the visitor is a copying visitor. |
| 5592 virtual bool is_copying() = 0; |
| 5593 |
| 5594 protected: |
| 5595 Handle<JSObject> StructureWalk(Handle<JSObject> object); |
| 5596 |
| 5597 // The returned handle should point to a new object if the visitor is a |
| 5598 // copying visitor, otherwise it should be the same as the input object. |
| 5599 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; |
| 5600 |
| 5601 // The returned handle should point to a new value if the visitor is a |
| 5602 // copying visitor, otherwise it should be the same as the input value. |
| 5603 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, |
| 5604 Handle<JSObject> value) = 0; |
| 5605 }; |
| 5606 |
| 5607 |
| 5608 class JSObjectCopyVisitor: public JSObjectWalkVisitor { |
| 5609 public: |
| 5610 explicit JSObjectCopyVisitor() {} |
| 5611 |
| 5612 virtual bool is_copying() V8_OVERRIDE { return true; } |
| 5613 |
| 5614 protected: |
| 5615 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { |
| 5616 return JSObject::Copy(object); |
| 5617 } |
| 5618 |
| 5619 virtual Handle<JSObject> VisitElementOrProperty( |
| 5620 Handle<JSObject> object, |
| 5621 Handle<JSObject> value) V8_OVERRIDE { |
| 5622 return StructureWalk(value); |
| 5623 } |
| 5624 }; |
| 5625 |
| 5626 |
| 5627 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { |
| 5628 bool copying = is_copying(); |
| 5587 Isolate* isolate = object->GetIsolate(); | 5629 Isolate* isolate = object->GetIsolate(); |
| 5588 StackLimitCheck check(isolate); | 5630 StackLimitCheck check(isolate); |
| 5589 if (check.HasOverflowed()) { | 5631 if (check.HasOverflowed()) { |
| 5590 isolate->StackOverflow(); | 5632 isolate->StackOverflow(); |
| 5591 return Handle<JSObject>::null(); | 5633 return Handle<JSObject>::null(); |
| 5592 } | 5634 } |
| 5593 | 5635 |
| 5594 if (object->map()->is_deprecated()) { | 5636 if (object->map()->is_deprecated()) { |
| 5595 MigrateInstance(object); | 5637 JSObject::MigrateInstance(object); |
| 5596 } | 5638 } |
| 5597 | 5639 |
| 5598 Handle<JSObject> copy = Copy(object); | 5640 Handle<JSObject> copy = VisitObject(object); |
| 5641 ASSERT(copying || copy.is_identical_to(object)); |
| 5599 | 5642 |
| 5600 HandleScope scope(isolate); | 5643 HandleScope scope(isolate); |
| 5601 | 5644 |
| 5602 // Deep copy local properties. | 5645 // Deep copy local properties. |
| 5603 if (copy->HasFastProperties()) { | 5646 if (copy->HasFastProperties()) { |
| 5604 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5647 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
| 5605 int limit = copy->map()->NumberOfOwnDescriptors(); | 5648 int limit = copy->map()->NumberOfOwnDescriptors(); |
| 5606 for (int i = 0; i < limit; i++) { | 5649 for (int i = 0; i < limit; i++) { |
| 5607 PropertyDetails details = descriptors->GetDetails(i); | 5650 PropertyDetails details = descriptors->GetDetails(i); |
| 5608 if (details.type() != FIELD) continue; | 5651 if (details.type() != FIELD) continue; |
| 5609 int index = descriptors->GetFieldIndex(i); | 5652 int index = descriptors->GetFieldIndex(i); |
| 5610 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5653 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 5611 if (value->IsJSObject()) { | 5654 if (value->IsJSObject()) { |
| 5612 value = DeepCopy(Handle<JSObject>::cast(value)); | 5655 value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value)); |
| 5613 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); | 5656 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); |
| 5614 } else { | 5657 } else { |
| 5615 Representation representation = details.representation(); | 5658 Representation representation = details.representation(); |
| 5616 value = NewStorageFor(isolate, value, representation); | 5659 value = NewStorageFor(isolate, value, representation); |
| 5617 } | 5660 } |
| 5618 copy->FastPropertyAtPut(index, *value); | 5661 if (copying) { |
| 5662 copy->FastPropertyAtPut(index, *value); |
| 5663 } |
| 5619 } | 5664 } |
| 5620 } else { | 5665 } else { |
| 5621 Handle<FixedArray> names = | 5666 Handle<FixedArray> names = |
| 5622 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); | 5667 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); |
| 5623 copy->GetLocalPropertyNames(*names, 0); | 5668 copy->GetLocalPropertyNames(*names, 0); |
| 5624 for (int i = 0; i < names->length(); i++) { | 5669 for (int i = 0; i < names->length(); i++) { |
| 5625 ASSERT(names->get(i)->IsString()); | 5670 ASSERT(names->get(i)->IsString()); |
| 5626 Handle<String> key_string(String::cast(names->get(i))); | 5671 Handle<String> key_string(String::cast(names->get(i))); |
| 5627 PropertyAttributes attributes = | 5672 PropertyAttributes attributes = |
| 5628 copy->GetLocalPropertyAttribute(*key_string); | 5673 copy->GetLocalPropertyAttribute(*key_string); |
| 5629 // Only deep copy fields from the object literal expression. | 5674 // Only deep copy fields from the object literal expression. |
| 5630 // In particular, don't try to copy the length attribute of | 5675 // In particular, don't try to copy the length attribute of |
| 5631 // an array. | 5676 // an array. |
| 5632 if (attributes != NONE) continue; | 5677 if (attributes != NONE) continue; |
| 5633 Handle<Object> value( | 5678 Handle<Object> value( |
| 5634 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), | 5679 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
| 5635 isolate); | 5680 isolate); |
| 5636 if (value->IsJSObject()) { | 5681 if (value->IsJSObject()) { |
| 5637 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); | 5682 Handle<JSObject> result = VisitElementOrProperty( |
| 5683 copy, Handle<JSObject>::cast(value)); |
| 5638 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5684 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5639 // Creating object copy for literals. No strict mode needed. | 5685 if (copying) { |
| 5640 CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( | 5686 // Creating object copy for literals. No strict mode needed. |
| 5641 copy, key_string, result, NONE, kNonStrictMode)); | 5687 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( |
| 5688 copy, key_string, result, NONE, kNonStrictMode)); |
| 5689 } |
| 5642 } | 5690 } |
| 5643 } | 5691 } |
| 5644 } | 5692 } |
| 5645 | 5693 |
| 5646 // Deep copy local elements. | 5694 // Deep copy local elements. |
| 5647 // Pixel elements cannot be created using an object literal. | 5695 // Pixel elements cannot be created using an object literal. |
| 5648 ASSERT(!copy->HasExternalArrayElements()); | 5696 ASSERT(!copy->HasExternalArrayElements()); |
| 5649 switch (copy->GetElementsKind()) { | 5697 switch (copy->GetElementsKind()) { |
| 5650 case FAST_SMI_ELEMENTS: | 5698 case FAST_SMI_ELEMENTS: |
| 5651 case FAST_ELEMENTS: | 5699 case FAST_ELEMENTS: |
| 5652 case FAST_HOLEY_SMI_ELEMENTS: | 5700 case FAST_HOLEY_SMI_ELEMENTS: |
| 5653 case FAST_HOLEY_ELEMENTS: { | 5701 case FAST_HOLEY_ELEMENTS: { |
| 5654 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | 5702 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
| 5655 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | 5703 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 5656 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 5704 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
| 5657 #ifdef DEBUG | 5705 #ifdef DEBUG |
| 5658 for (int i = 0; i < elements->length(); i++) { | 5706 for (int i = 0; i < elements->length(); i++) { |
| 5659 ASSERT(!elements->get(i)->IsJSObject()); | 5707 ASSERT(!elements->get(i)->IsJSObject()); |
| 5660 } | 5708 } |
| 5661 #endif | 5709 #endif |
| 5662 } else { | 5710 } else { |
| 5663 for (int i = 0; i < elements->length(); i++) { | 5711 for (int i = 0; i < elements->length(); i++) { |
| 5664 Handle<Object> value(elements->get(i), isolate); | 5712 Handle<Object> value(elements->get(i), isolate); |
| 5665 ASSERT(value->IsSmi() || | 5713 ASSERT(value->IsSmi() || |
| 5666 value->IsTheHole() || | 5714 value->IsTheHole() || |
| 5667 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5715 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
| 5668 if (value->IsJSObject()) { | 5716 if (value->IsJSObject()) { |
| 5669 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); | 5717 Handle<JSObject> result = VisitElementOrProperty( |
| 5718 copy, Handle<JSObject>::cast(value)); |
| 5670 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5719 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5671 elements->set(i, *result); | 5720 if (copying) { |
| 5721 elements->set(i, *result); |
| 5722 } |
| 5672 } | 5723 } |
| 5673 } | 5724 } |
| 5674 } | 5725 } |
| 5675 break; | 5726 break; |
| 5676 } | 5727 } |
| 5677 case DICTIONARY_ELEMENTS: { | 5728 case DICTIONARY_ELEMENTS: { |
| 5678 Handle<SeededNumberDictionary> element_dictionary( | 5729 Handle<SeededNumberDictionary> element_dictionary( |
| 5679 copy->element_dictionary()); | 5730 copy->element_dictionary()); |
| 5680 int capacity = element_dictionary->Capacity(); | 5731 int capacity = element_dictionary->Capacity(); |
| 5681 for (int i = 0; i < capacity; i++) { | 5732 for (int i = 0; i < capacity; i++) { |
| 5682 Object* k = element_dictionary->KeyAt(i); | 5733 Object* k = element_dictionary->KeyAt(i); |
| 5683 if (element_dictionary->IsKey(k)) { | 5734 if (element_dictionary->IsKey(k)) { |
| 5684 Handle<Object> value(element_dictionary->ValueAt(i), isolate); | 5735 Handle<Object> value(element_dictionary->ValueAt(i), isolate); |
| 5685 if (value->IsJSObject()) { | 5736 if (value->IsJSObject()) { |
| 5686 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); | 5737 Handle<JSObject> result = VisitElementOrProperty( |
| 5738 copy, Handle<JSObject>::cast(value)); |
| 5687 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5739 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5688 element_dictionary->ValueAtPut(i, *result); | 5740 if (copying) { |
| 5741 element_dictionary->ValueAtPut(i, *result); |
| 5742 } |
| 5689 } | 5743 } |
| 5690 } | 5744 } |
| 5691 } | 5745 } |
| 5692 break; | 5746 break; |
| 5693 } | 5747 } |
| 5694 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5748 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 5695 UNIMPLEMENTED(); | 5749 UNIMPLEMENTED(); |
| 5696 break; | 5750 break; |
| 5697 case EXTERNAL_PIXEL_ELEMENTS: | 5751 case EXTERNAL_PIXEL_ELEMENTS: |
| 5698 case EXTERNAL_BYTE_ELEMENTS: | 5752 case EXTERNAL_BYTE_ELEMENTS: |
| 5699 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 5753 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 5700 case EXTERNAL_SHORT_ELEMENTS: | 5754 case EXTERNAL_SHORT_ELEMENTS: |
| 5701 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 5755 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 5702 case EXTERNAL_INT_ELEMENTS: | 5756 case EXTERNAL_INT_ELEMENTS: |
| 5703 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 5757 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 5704 case EXTERNAL_FLOAT_ELEMENTS: | 5758 case EXTERNAL_FLOAT_ELEMENTS: |
| 5705 case EXTERNAL_DOUBLE_ELEMENTS: | 5759 case EXTERNAL_DOUBLE_ELEMENTS: |
| 5706 case FAST_DOUBLE_ELEMENTS: | 5760 case FAST_DOUBLE_ELEMENTS: |
| 5707 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5761 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 5708 // No contained objects, nothing to do. | 5762 // No contained objects, nothing to do. |
| 5709 break; | 5763 break; |
| 5710 } | 5764 } |
| 5711 return copy; | 5765 return copy; |
| 5712 } | 5766 } |
| 5713 | 5767 |
| 5714 | 5768 |
| 5769 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { |
| 5770 JSObjectCopyVisitor v; |
| 5771 Handle<JSObject> copy = v.Visit(object); |
| 5772 ASSERT(v.is_copying() && !copy.is_identical_to(object)); |
| 5773 return copy; |
| 5774 } |
| 5775 |
| 5776 |
| 5715 // Tests for the fast common case for property enumeration: | 5777 // Tests for the fast common case for property enumeration: |
| 5716 // - This object and all prototypes has an enum cache (which means that | 5778 // - This object and all prototypes has an enum cache (which means that |
| 5717 // it is no proxy, has no interceptors and needs no access checks). | 5779 // it is no proxy, has no interceptors and needs no access checks). |
| 5718 // - This object has no elements. | 5780 // - This object has no elements. |
| 5719 // - No prototype has enumerable properties/elements. | 5781 // - No prototype has enumerable properties/elements. |
| 5720 bool JSReceiver::IsSimpleEnum() { | 5782 bool JSReceiver::IsSimpleEnum() { |
| 5721 Heap* heap = GetHeap(); | 5783 Heap* heap = GetHeap(); |
| 5722 for (Object* o = this; | 5784 for (Object* o = this; |
| 5723 o != heap->null_value(); | 5785 o != heap->null_value(); |
| 5724 o = JSObject::cast(o)->GetPrototype()) { | 5786 o = JSObject::cast(o)->GetPrototype()) { |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6104 name, | 6166 name, |
| 6105 getter, | 6167 getter, |
| 6106 setter, | 6168 setter, |
| 6107 attributes, | 6169 attributes, |
| 6108 access_control); | 6170 access_control); |
| 6109 return; | 6171 return; |
| 6110 } | 6172 } |
| 6111 | 6173 |
| 6112 // Make sure that the top context does not change when doing callbacks or | 6174 // Make sure that the top context does not change when doing callbacks or |
| 6113 // interceptor calls. | 6175 // interceptor calls. |
| 6114 AssertNoContextChangeWithHandleScope ncc; | 6176 AssertNoContextChange ncc(isolate); |
| 6115 | 6177 |
| 6116 // Try to flatten before operating on the string. | 6178 // Try to flatten before operating on the string. |
| 6117 if (name->IsString()) String::cast(*name)->TryFlatten(); | 6179 if (name->IsString()) String::cast(*name)->TryFlatten(); |
| 6118 | 6180 |
| 6119 if (!object->CanSetCallback(*name)) return; | 6181 if (!object->CanSetCallback(*name)) return; |
| 6120 | 6182 |
| 6121 uint32_t index = 0; | 6183 uint32_t index = 0; |
| 6122 bool is_element = name->AsArrayIndex(&index); | 6184 bool is_element = name->AsArrayIndex(&index); |
| 6123 | 6185 |
| 6124 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6186 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6290 | 6352 |
| 6291 if (object->IsJSGlobalProxy()) { | 6353 if (object->IsJSGlobalProxy()) { |
| 6292 Handle<Object> proto(object->GetPrototype(), isolate); | 6354 Handle<Object> proto(object->GetPrototype(), isolate); |
| 6293 if (proto->IsNull()) return object; | 6355 if (proto->IsNull()) return object; |
| 6294 ASSERT(proto->IsJSGlobalObject()); | 6356 ASSERT(proto->IsJSGlobalObject()); |
| 6295 return SetAccessor(Handle<JSObject>::cast(proto), info); | 6357 return SetAccessor(Handle<JSObject>::cast(proto), info); |
| 6296 } | 6358 } |
| 6297 | 6359 |
| 6298 // Make sure that the top context does not change when doing callbacks or | 6360 // Make sure that the top context does not change when doing callbacks or |
| 6299 // interceptor calls. | 6361 // interceptor calls. |
| 6300 AssertNoContextChange ncc; | 6362 AssertNoContextChange ncc(isolate); |
| 6301 | 6363 |
| 6302 // Try to flatten before operating on the string. | 6364 // Try to flatten before operating on the string. |
| 6303 if (name->IsString()) FlattenString(Handle<String>::cast(name)); | 6365 if (name->IsString()) FlattenString(Handle<String>::cast(name)); |
| 6304 | 6366 |
| 6305 if (!object->CanSetCallback(*name)) return factory->undefined_value(); | 6367 if (!object->CanSetCallback(*name)) return factory->undefined_value(); |
| 6306 | 6368 |
| 6307 uint32_t index = 0; | 6369 uint32_t index = 0; |
| 6308 bool is_element = name->AsArrayIndex(&index); | 6370 bool is_element = name->AsArrayIndex(&index); |
| 6309 | 6371 |
| 6310 if (is_element) { | 6372 if (is_element) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6349 return factory->undefined_value(); | 6411 return factory->undefined_value(); |
| 6350 } | 6412 } |
| 6351 | 6413 |
| 6352 SetPropertyCallback(object, name, info, info->property_attributes()); | 6414 SetPropertyCallback(object, name, info, info->property_attributes()); |
| 6353 } | 6415 } |
| 6354 | 6416 |
| 6355 return object; | 6417 return object; |
| 6356 } | 6418 } |
| 6357 | 6419 |
| 6358 | 6420 |
| 6359 MaybeObject* JSObject::LookupAccessor(Name* name, AccessorComponent component) { | 6421 Handle<Object> JSObject::GetAccessor(Handle<JSObject> object, |
| 6360 Heap* heap = GetHeap(); | 6422 Handle<Name> name, |
| 6423 AccessorComponent component) { |
| 6424 Isolate* isolate = object->GetIsolate(); |
| 6361 | 6425 |
| 6362 // Make sure that the top context does not change when doing callbacks or | 6426 // Make sure that the top context does not change when doing callbacks or |
| 6363 // interceptor calls. | 6427 // interceptor calls. |
| 6364 AssertNoContextChangeWithHandleScope ncc; | 6428 AssertNoContextChange ncc(isolate); |
| 6365 | 6429 |
| 6366 // Check access rights if needed. | 6430 // Check access rights if needed. |
| 6367 if (IsAccessCheckNeeded() && | 6431 if (object->IsAccessCheckNeeded() && |
| 6368 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 6432 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) { |
| 6369 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6433 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); |
| 6370 RETURN_IF_SCHEDULED_EXCEPTION(heap->isolate()); | 6434 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6371 return heap->undefined_value(); | 6435 return isolate->factory()->undefined_value(); |
| 6372 } | 6436 } |
| 6373 | 6437 |
| 6374 // Make the lookup and include prototypes. | 6438 // Make the lookup and include prototypes. |
| 6375 uint32_t index = 0; | 6439 uint32_t index = 0; |
| 6376 if (name->AsArrayIndex(&index)) { | 6440 if (name->AsArrayIndex(&index)) { |
| 6377 for (Object* obj = this; | 6441 for (Handle<Object> obj = object; |
| 6378 obj != heap->null_value(); | 6442 *obj != isolate->heap()->null_value(); |
| 6379 obj = JSReceiver::cast(obj)->GetPrototype()) { | 6443 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { |
| 6380 if (obj->IsJSObject() && JSObject::cast(obj)->HasDictionaryElements()) { | 6444 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) { |
| 6381 JSObject* js_object = JSObject::cast(obj); | 6445 JSObject* js_object = JSObject::cast(*obj); |
| 6382 SeededNumberDictionary* dictionary = js_object->element_dictionary(); | 6446 SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
| 6383 int entry = dictionary->FindEntry(index); | 6447 int entry = dictionary->FindEntry(index); |
| 6384 if (entry != SeededNumberDictionary::kNotFound) { | 6448 if (entry != SeededNumberDictionary::kNotFound) { |
| 6385 Object* element = dictionary->ValueAt(entry); | 6449 Object* element = dictionary->ValueAt(entry); |
| 6386 if (dictionary->DetailsAt(entry).type() == CALLBACKS && | 6450 if (dictionary->DetailsAt(entry).type() == CALLBACKS && |
| 6387 element->IsAccessorPair()) { | 6451 element->IsAccessorPair()) { |
| 6388 return AccessorPair::cast(element)->GetComponent(component); | 6452 return handle(AccessorPair::cast(element)->GetComponent(component), |
| 6453 isolate); |
| 6389 } | 6454 } |
| 6390 } | 6455 } |
| 6391 } | 6456 } |
| 6392 } | 6457 } |
| 6393 } else { | 6458 } else { |
| 6394 for (Object* obj = this; | 6459 for (Handle<Object> obj = object; |
| 6395 obj != heap->null_value(); | 6460 *obj != isolate->heap()->null_value(); |
| 6396 obj = JSReceiver::cast(obj)->GetPrototype()) { | 6461 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { |
| 6397 LookupResult result(heap->isolate()); | 6462 LookupResult result(isolate); |
| 6398 JSReceiver::cast(obj)->LocalLookup(name, &result); | 6463 JSReceiver::cast(*obj)->LocalLookup(*name, &result); |
| 6399 if (result.IsFound()) { | 6464 if (result.IsFound()) { |
| 6400 if (result.IsReadOnly()) return heap->undefined_value(); | 6465 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); |
| 6401 if (result.IsPropertyCallbacks()) { | 6466 if (result.IsPropertyCallbacks()) { |
| 6402 Object* obj = result.GetCallbackObject(); | 6467 Object* obj = result.GetCallbackObject(); |
| 6403 if (obj->IsAccessorPair()) { | 6468 if (obj->IsAccessorPair()) { |
| 6404 return AccessorPair::cast(obj)->GetComponent(component); | 6469 return handle(AccessorPair::cast(obj)->GetComponent(component), |
| 6470 isolate); |
| 6405 } | 6471 } |
| 6406 } | 6472 } |
| 6407 } | 6473 } |
| 6408 } | 6474 } |
| 6409 } | 6475 } |
| 6410 return heap->undefined_value(); | 6476 return isolate->factory()->undefined_value(); |
| 6411 } | 6477 } |
| 6412 | 6478 |
| 6413 | 6479 |
| 6414 Object* JSObject::SlowReverseLookup(Object* value) { | 6480 Object* JSObject::SlowReverseLookup(Object* value) { |
| 6415 if (HasFastProperties()) { | 6481 if (HasFastProperties()) { |
| 6416 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6482 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
| 6417 DescriptorArray* descs = map()->instance_descriptors(); | 6483 DescriptorArray* descs = map()->instance_descriptors(); |
| 6418 for (int i = 0; i < number_of_own_descriptors; i++) { | 6484 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 6419 if (descs->GetType(i) == FIELD) { | 6485 if (descs->GetType(i) == FIELD) { |
| 6420 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i)); | 6486 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i)); |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6950 void Map::UpdateCodeCache(Handle<Map> map, | 7016 void Map::UpdateCodeCache(Handle<Map> map, |
| 6951 Handle<Name> name, | 7017 Handle<Name> name, |
| 6952 Handle<Code> code) { | 7018 Handle<Code> code) { |
| 6953 Isolate* isolate = map->GetIsolate(); | 7019 Isolate* isolate = map->GetIsolate(); |
| 6954 CALL_HEAP_FUNCTION_VOID(isolate, | 7020 CALL_HEAP_FUNCTION_VOID(isolate, |
| 6955 map->UpdateCodeCache(*name, *code)); | 7021 map->UpdateCodeCache(*name, *code)); |
| 6956 } | 7022 } |
| 6957 | 7023 |
| 6958 | 7024 |
| 6959 MaybeObject* Map::UpdateCodeCache(Name* name, Code* code) { | 7025 MaybeObject* Map::UpdateCodeCache(Name* name, Code* code) { |
| 6960 ASSERT(!is_shared() || code->allowed_in_shared_map_code_cache()); | |
| 6961 | |
| 6962 // Allocate the code cache if not present. | 7026 // Allocate the code cache if not present. |
| 6963 if (code_cache()->IsFixedArray()) { | 7027 if (code_cache()->IsFixedArray()) { |
| 6964 Object* result; | 7028 Object* result; |
| 6965 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); | 7029 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); |
| 6966 if (!maybe_result->ToObject(&result)) return maybe_result; | 7030 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6967 } | 7031 } |
| 6968 set_code_cache(result); | 7032 set_code_cache(result); |
| 6969 } | 7033 } |
| 6970 | 7034 |
| 6971 // Update the code cache. | 7035 // Update the code cache. |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7278 Object* new_cache; | 7342 Object* new_cache; |
| 7279 { MaybeObject* maybe_new_cache = cache->Put(name, code); | 7343 { MaybeObject* maybe_new_cache = cache->Put(name, code); |
| 7280 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; | 7344 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; |
| 7281 } | 7345 } |
| 7282 set_normal_type_cache(new_cache); | 7346 set_normal_type_cache(new_cache); |
| 7283 return this; | 7347 return this; |
| 7284 } | 7348 } |
| 7285 | 7349 |
| 7286 | 7350 |
| 7287 Object* CodeCache::Lookup(Name* name, Code::Flags flags) { | 7351 Object* CodeCache::Lookup(Name* name, Code::Flags flags) { |
| 7288 if (Code::ExtractTypeFromFlags(flags) == Code::NORMAL) { | 7352 flags = Code::RemoveTypeFromFlags(flags); |
| 7289 return LookupNormalTypeCache(name, flags); | 7353 Object* result = LookupDefaultCache(name, flags); |
| 7290 } else { | 7354 if (result->IsCode()) return result; |
| 7291 return LookupDefaultCache(name, flags); | 7355 return LookupNormalTypeCache(name, flags); |
| 7292 } | |
| 7293 } | 7356 } |
| 7294 | 7357 |
| 7295 | 7358 |
| 7296 Object* CodeCache::LookupDefaultCache(Name* name, Code::Flags flags) { | 7359 Object* CodeCache::LookupDefaultCache(Name* name, Code::Flags flags) { |
| 7297 FixedArray* cache = default_cache(); | 7360 FixedArray* cache = default_cache(); |
| 7298 int length = cache->length(); | 7361 int length = cache->length(); |
| 7299 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 7362 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
| 7300 Object* key = cache->get(i + kCodeCacheEntryNameOffset); | 7363 Object* key = cache->get(i + kCodeCacheEntryNameOffset); |
| 7301 // Skip deleted elements. | 7364 // Skip deleted elements. |
| 7302 if (key->IsNull()) continue; | 7365 if (key->IsNull()) continue; |
| 7303 if (key->IsUndefined()) return key; | 7366 if (key->IsUndefined()) return key; |
| 7304 if (name->Equals(Name::cast(key))) { | 7367 if (name->Equals(Name::cast(key))) { |
| 7305 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); | 7368 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); |
| 7306 if (code->flags() == flags) { | 7369 if (Code::RemoveTypeFromFlags(code->flags()) == flags) { |
| 7307 return code; | 7370 return code; |
| 7308 } | 7371 } |
| 7309 } | 7372 } |
| 7310 } | 7373 } |
| 7311 return GetHeap()->undefined_value(); | 7374 return GetHeap()->undefined_value(); |
| 7312 } | 7375 } |
| 7313 | 7376 |
| 7314 | 7377 |
| 7315 Object* CodeCache::LookupNormalTypeCache(Name* name, Code::Flags flags) { | 7378 Object* CodeCache::LookupNormalTypeCache(Name* name, Code::Flags flags) { |
| 7316 if (!normal_type_cache()->IsUndefined()) { | 7379 if (!normal_type_cache()->IsUndefined()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7360 // The key in the code cache hash table consists of the property name and the | 7423 // The key in the code cache hash table consists of the property name and the |
| 7361 // code object. The actual match is on the name and the code flags. If a key | 7424 // code object. The actual match is on the name and the code flags. If a key |
| 7362 // is created using the flags and not a code object it can only be used for | 7425 // is created using the flags and not a code object it can only be used for |
| 7363 // lookup not to create a new entry. | 7426 // lookup not to create a new entry. |
| 7364 class CodeCacheHashTableKey : public HashTableKey { | 7427 class CodeCacheHashTableKey : public HashTableKey { |
| 7365 public: | 7428 public: |
| 7366 CodeCacheHashTableKey(Name* name, Code::Flags flags) | 7429 CodeCacheHashTableKey(Name* name, Code::Flags flags) |
| 7367 : name_(name), flags_(flags), code_(NULL) { } | 7430 : name_(name), flags_(flags), code_(NULL) { } |
| 7368 | 7431 |
| 7369 CodeCacheHashTableKey(Name* name, Code* code) | 7432 CodeCacheHashTableKey(Name* name, Code* code) |
| 7370 : name_(name), | 7433 : name_(name), flags_(code->flags()), code_(code) { } |
| 7371 flags_(code->flags()), | |
| 7372 code_(code) { } | |
| 7373 | 7434 |
| 7374 | 7435 |
| 7375 bool IsMatch(Object* other) { | 7436 bool IsMatch(Object* other) { |
| 7376 if (!other->IsFixedArray()) return false; | 7437 if (!other->IsFixedArray()) return false; |
| 7377 FixedArray* pair = FixedArray::cast(other); | 7438 FixedArray* pair = FixedArray::cast(other); |
| 7378 Name* name = Name::cast(pair->get(0)); | 7439 Name* name = Name::cast(pair->get(0)); |
| 7379 Code::Flags flags = Code::cast(pair->get(1))->flags(); | 7440 Code::Flags flags = Code::cast(pair->get(1))->flags(); |
| 7380 if (flags != flags_) { | 7441 if (flags != flags_) { |
| 7381 return false; | 7442 return false; |
| 7382 } | 7443 } |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7664 for (int i = 0; i < result->length(); i++) { | 7725 for (int i = 0; i < result->length(); i++) { |
| 7665 Object* current = result->get(i); | 7726 Object* current = result->get(i); |
| 7666 ASSERT(current->IsNumber() || current->IsName()); | 7727 ASSERT(current->IsNumber() || current->IsName()); |
| 7667 } | 7728 } |
| 7668 } | 7729 } |
| 7669 #endif | 7730 #endif |
| 7670 return result; | 7731 return result; |
| 7671 } | 7732 } |
| 7672 | 7733 |
| 7673 | 7734 |
| 7674 MaybeObject* FixedArray::CopySize(int new_length) { | 7735 MaybeObject* FixedArray::CopySize(int new_length, PretenureFlag pretenure) { |
| 7675 Heap* heap = GetHeap(); | 7736 Heap* heap = GetHeap(); |
| 7676 if (new_length == 0) return heap->empty_fixed_array(); | 7737 if (new_length == 0) return heap->empty_fixed_array(); |
| 7677 Object* obj; | 7738 Object* obj; |
| 7678 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); | 7739 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length, pretenure); |
| 7679 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7740 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7680 } | 7741 } |
| 7681 FixedArray* result = FixedArray::cast(obj); | 7742 FixedArray* result = FixedArray::cast(obj); |
| 7682 // Copy the content | 7743 // Copy the content |
| 7683 DisallowHeapAllocation no_gc; | 7744 DisallowHeapAllocation no_gc; |
| 7684 int len = length(); | 7745 int len = length(); |
| 7685 if (new_length < len) len = new_length; | 7746 if (new_length < len) len = new_length; |
| 7686 // We are taking the map from the old fixed array so the map is sure to | 7747 // We are taking the map from the old fixed array so the map is sure to |
| 7687 // be an immortal immutable object. | 7748 // be an immortal immutable object. |
| 7688 result->set_map_no_write_barrier(map()); | 7749 result->set_map_no_write_barrier(map()); |
| (...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8978 if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) { | 9039 if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) { |
| 8979 MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta); | 9040 MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta); |
| 8980 } | 9041 } |
| 8981 | 9042 |
| 8982 | 9043 |
| 8983 if (new_length == 0) return heap->isolate()->factory()->empty_string(); | 9044 if (new_length == 0) return heap->isolate()->factory()->empty_string(); |
| 8984 return string; | 9045 return string; |
| 8985 } | 9046 } |
| 8986 | 9047 |
| 8987 | 9048 |
| 8988 AllocationMemento* AllocationMemento::FindForJSObject(JSObject* object) { | 9049 AllocationMemento* AllocationMemento::FindForJSObject(JSObject* object, |
| 9050 bool in_GC) { |
| 8989 // Currently, AllocationMemento objects are only allocated immediately | 9051 // Currently, AllocationMemento objects are only allocated immediately |
| 8990 // after JSArrays in NewSpace, and detecting whether a JSArray has one | 9052 // after JSArrays in NewSpace, and detecting whether a JSArray has one |
| 8991 // involves carefully checking the object immediately after the JSArray | 9053 // involves carefully checking the object immediately after the JSArray |
| 8992 // (if there is one) to see if it's an AllocationMemento. | 9054 // (if there is one) to see if it's an AllocationMemento. |
| 8993 if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) { | 9055 if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) { |
| 8994 ASSERT(object->GetHeap()->InToSpace(object)); | |
| 8995 Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) + | 9056 Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) + |
| 8996 object->Size(); | 9057 object->Size(); |
| 8997 if ((ptr_end + AllocationMemento::kSize) <= | 9058 Address top; |
| 8998 object->GetHeap()->NewSpaceTop()) { | 9059 if (in_GC) { |
| 9060 top = object->GetHeap()->new_space()->FromSpacePageHigh(); |
| 9061 } else { |
| 9062 top = object->GetHeap()->NewSpaceTop(); |
| 9063 } |
| 9064 if ((ptr_end + AllocationMemento::kSize) <= top) { |
| 8999 // There is room in newspace for allocation info. Do we have some? | 9065 // There is room in newspace for allocation info. Do we have some? |
| 9000 Map** possible_allocation_memento_map = | 9066 Map** possible_allocation_memento_map = |
| 9001 reinterpret_cast<Map**>(ptr_end); | 9067 reinterpret_cast<Map**>(ptr_end); |
| 9002 if (*possible_allocation_memento_map == | 9068 if (*possible_allocation_memento_map == |
| 9003 object->GetHeap()->allocation_memento_map()) { | 9069 object->GetHeap()->allocation_memento_map()) { |
| 9004 AllocationMemento* memento = AllocationMemento::cast( | 9070 AllocationMemento* memento = AllocationMemento::cast( |
| 9005 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag)); | 9071 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag)); |
| 9006 return memento; | 9072 return memento; |
| 9007 } | 9073 } |
| 9008 } | 9074 } |
| (...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10290 if (object->IsMap()) maps->Add(Handle<Map>(Map::cast(object))); | 10356 if (object->IsMap()) maps->Add(Handle<Map>(Map::cast(object))); |
| 10291 } | 10357 } |
| 10292 } | 10358 } |
| 10293 | 10359 |
| 10294 | 10360 |
| 10295 void Code::ReplaceFirstMap(Map* replace_with) { | 10361 void Code::ReplaceFirstMap(Map* replace_with) { |
| 10296 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); | 10362 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); |
| 10297 } | 10363 } |
| 10298 | 10364 |
| 10299 | 10365 |
| 10300 Code* Code::FindFirstCode() { | 10366 Code* Code::FindFirstHandler() { |
| 10301 ASSERT(is_inline_cache_stub()); | 10367 ASSERT(is_inline_cache_stub()); |
| 10302 DisallowHeapAllocation no_allocation; | 10368 DisallowHeapAllocation no_allocation; |
| 10303 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 10369 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
| 10304 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10370 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10305 RelocInfo* info = it.rinfo(); | 10371 RelocInfo* info = it.rinfo(); |
| 10306 return Code::GetCodeFromTargetAddress(info->target_address()); | 10372 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); |
| 10373 if (code->kind() == Code::HANDLER) return code; |
| 10307 } | 10374 } |
| 10308 return NULL; | 10375 return NULL; |
| 10309 } | 10376 } |
| 10310 | 10377 |
| 10311 | 10378 |
| 10312 void Code::FindAllCode(CodeHandleList* code_list, int length) { | 10379 bool Code::FindHandlers(CodeHandleList* code_list, int length) { |
| 10313 ASSERT(is_inline_cache_stub()); | 10380 ASSERT(is_inline_cache_stub()); |
| 10314 DisallowHeapAllocation no_allocation; | 10381 DisallowHeapAllocation no_allocation; |
| 10315 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 10382 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
| 10316 int i = 0; | 10383 int i = 0; |
| 10317 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10384 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10318 if (i++ == length) return; | 10385 if (i == length) return true; |
| 10319 RelocInfo* info = it.rinfo(); | 10386 RelocInfo* info = it.rinfo(); |
| 10320 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); | 10387 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); |
| 10321 ASSERT(code->kind() == Code::STUB); | 10388 // IC stubs with handlers never contain non-handler code objects before |
| 10389 // handler targets. |
| 10390 if (code->kind() != Code::HANDLER) break; |
| 10322 code_list->Add(Handle<Code>(code)); | 10391 code_list->Add(Handle<Code>(code)); |
| 10392 i++; |
| 10323 } | 10393 } |
| 10324 UNREACHABLE(); | 10394 return i == length; |
| 10325 } | 10395 } |
| 10326 | 10396 |
| 10327 | 10397 |
| 10328 Name* Code::FindFirstName() { | 10398 Name* Code::FindFirstName() { |
| 10329 ASSERT(is_inline_cache_stub()); | 10399 ASSERT(is_inline_cache_stub()); |
| 10330 DisallowHeapAllocation no_allocation; | 10400 DisallowHeapAllocation no_allocation; |
| 10331 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10401 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10332 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10402 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10333 RelocInfo* info = it.rinfo(); | 10403 RelocInfo* info = it.rinfo(); |
| 10334 Object* object = info->target_object(); | 10404 Object* object = info->target_object(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10390 DisallowHeapAllocation no_gc; | 10460 DisallowHeapAllocation no_gc; |
| 10391 ASSERT(kind() == FUNCTION); | 10461 ASSERT(kind() == FUNCTION); |
| 10392 BackEdgeTable back_edges(this, &no_gc); | 10462 BackEdgeTable back_edges(this, &no_gc); |
| 10393 for (uint32_t i = 0; i < back_edges.length(); i++) { | 10463 for (uint32_t i = 0; i < back_edges.length(); i++) { |
| 10394 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); | 10464 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); |
| 10395 } | 10465 } |
| 10396 return BailoutId::None(); | 10466 return BailoutId::None(); |
| 10397 } | 10467 } |
| 10398 | 10468 |
| 10399 | 10469 |
| 10400 bool Code::allowed_in_shared_map_code_cache() { | |
| 10401 return is_keyed_load_stub() || is_keyed_store_stub() || | |
| 10402 (is_compare_ic_stub() && | |
| 10403 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); | |
| 10404 } | |
| 10405 | |
| 10406 | |
| 10407 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { | 10470 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { |
| 10408 PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY); | 10471 PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY); |
| 10409 } | 10472 } |
| 10410 | 10473 |
| 10411 | 10474 |
| 10412 void Code::MakeOlder(MarkingParity current_parity) { | 10475 void Code::MakeOlder(MarkingParity current_parity) { |
| 10413 byte* sequence = FindCodeAgeSequence(); | 10476 byte* sequence = FindCodeAgeSequence(); |
| 10414 if (sequence != NULL) { | 10477 if (sequence != NULL) { |
| 10415 Age age; | 10478 Age age; |
| 10416 MarkingParity code_parity; | 10479 MarkingParity code_parity; |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10952 GetElementsKind(), new_elements); | 11015 GetElementsKind(), new_elements); |
| 10953 } | 11016 } |
| 10954 | 11017 |
| 10955 if (IsJSArray()) { | 11018 if (IsJSArray()) { |
| 10956 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 11019 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
| 10957 } | 11020 } |
| 10958 return new_elements; | 11021 return new_elements; |
| 10959 } | 11022 } |
| 10960 | 11023 |
| 10961 | 11024 |
| 11025 bool Code::IsWeakEmbeddedObject(Kind kind, Object* object) { |
| 11026 if (kind != Code::OPTIMIZED_FUNCTION) return false; |
| 11027 |
| 11028 if (object->IsMap()) { |
| 11029 return Map::cast(object)->CanTransition() && |
| 11030 FLAG_collect_maps && |
| 11031 FLAG_weak_embedded_maps_in_optimized_code; |
| 11032 } |
| 11033 |
| 11034 if (object->IsJSObject()) { |
| 11035 return FLAG_weak_embedded_objects_in_optimized_code; |
| 11036 } |
| 11037 |
| 11038 return false; |
| 11039 } |
| 11040 |
| 10962 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11041 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
| 10963 int capacity, | 11042 int capacity, |
| 10964 int length) { | 11043 int length) { |
| 10965 Heap* heap = GetHeap(); | 11044 Heap* heap = GetHeap(); |
| 10966 // We should never end in here with a pixel or external array. | 11045 // We should never end in here with a pixel or external array. |
| 10967 ASSERT(!HasExternalArrayElements()); | 11046 ASSERT(!HasExternalArrayElements()); |
| 10968 ASSERT(!map()->is_observed()); | 11047 ASSERT(!map()->is_observed()); |
| 10969 | 11048 |
| 10970 FixedArrayBase* elems; | 11049 FixedArrayBase* elems; |
| 10971 { MaybeObject* maybe_obj = | 11050 { MaybeObject* maybe_obj = |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11312 // Do not append the compilation info if it is already in the array. | 11391 // Do not append the compilation info if it is already in the array. |
| 11313 // It is sufficient to just check only the last element because | 11392 // It is sufficient to just check only the last element because |
| 11314 // we process embedded maps of an optimized code in one batch. | 11393 // we process embedded maps of an optimized code in one batch. |
| 11315 return entries; | 11394 return entries; |
| 11316 } | 11395 } |
| 11317 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { | 11396 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { |
| 11318 Factory* factory = entries->GetIsolate()->factory(); | 11397 Factory* factory = entries->GetIsolate()->factory(); |
| 11319 int capacity = kCodesStartIndex + number_of_entries + 1; | 11398 int capacity = kCodesStartIndex + number_of_entries + 1; |
| 11320 if (capacity > 5) capacity = capacity * 5 / 4; | 11399 if (capacity > 5) capacity = capacity * 5 / 4; |
| 11321 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( | 11400 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( |
| 11322 factory->CopySizeFixedArray(entries, capacity)); | 11401 factory->CopySizeFixedArray(entries, capacity, TENURED)); |
| 11323 // The number of codes can change after GC. | 11402 // The number of codes can change after GC. |
| 11324 starts.Recompute(*entries); | 11403 starts.Recompute(*entries); |
| 11325 start = starts.at(group); | 11404 start = starts.at(group); |
| 11326 end = starts.at(group + 1); | 11405 end = starts.at(group + 1); |
| 11327 number_of_entries = starts.number_of_entries(); | 11406 number_of_entries = starts.number_of_entries(); |
| 11328 for (int i = 0; i < number_of_entries; i++) { | 11407 for (int i = 0; i < number_of_entries; i++) { |
| 11329 entries->clear_at(i); | 11408 entries->clear_at(i); |
| 11330 } | 11409 } |
| 11331 // If the old fixed array was empty, we need to reset counters of the | 11410 // If the old fixed array was empty, we need to reset counters of the |
| 11332 // new array. | 11411 // new array. |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11546 EnsureElementsMode mode) { | 11625 EnsureElementsMode mode) { |
| 11547 // Elements in |Arguments| are ordered backwards (because they're on the | 11626 // Elements in |Arguments| are ordered backwards (because they're on the |
| 11548 // stack), but the method that's called here iterates over them in forward | 11627 // stack), but the method that's called here iterates over them in forward |
| 11549 // direction. | 11628 // direction. |
| 11550 return EnsureCanContainElements( | 11629 return EnsureCanContainElements( |
| 11551 args->arguments() - first_arg - (arg_count - 1), | 11630 args->arguments() - first_arg - (arg_count - 1), |
| 11552 arg_count, mode); | 11631 arg_count, mode); |
| 11553 } | 11632 } |
| 11554 | 11633 |
| 11555 | 11634 |
| 11556 PropertyType JSObject::GetLocalPropertyType(Name* name) { | |
| 11557 uint32_t index = 0; | |
| 11558 if (name->AsArrayIndex(&index)) { | |
| 11559 return GetLocalElementType(index); | |
| 11560 } | |
| 11561 LookupResult lookup(GetIsolate()); | |
| 11562 LocalLookup(name, &lookup, true); | |
| 11563 return lookup.type(); | |
| 11564 } | |
| 11565 | |
| 11566 | |
| 11567 PropertyType JSObject::GetLocalElementType(uint32_t index) { | |
| 11568 return GetElementsAccessor()->GetType(this, this, index); | |
| 11569 } | |
| 11570 | |
| 11571 | |
| 11572 AccessorPair* JSObject::GetLocalPropertyAccessorPair(Name* name) { | 11635 AccessorPair* JSObject::GetLocalPropertyAccessorPair(Name* name) { |
| 11573 uint32_t index = 0; | 11636 uint32_t index = 0; |
| 11574 if (name->AsArrayIndex(&index)) { | 11637 if (name->AsArrayIndex(&index)) { |
| 11575 return GetLocalElementAccessorPair(index); | 11638 return GetLocalElementAccessorPair(index); |
| 11576 } | 11639 } |
| 11577 | 11640 |
| 11578 LookupResult lookup(GetIsolate()); | 11641 LookupResult lookup(GetIsolate()); |
| 11579 LocalLookupRealNamedProperty(name, &lookup); | 11642 LocalLookupRealNamedProperty(name, &lookup); |
| 11580 | 11643 |
| 11581 if (lookup.IsPropertyCallbacks() && | 11644 if (lookup.IsPropertyCallbacks() && |
| (...skipping 23 matching lines...) Expand all Loading... |
| 11605 Object* value, | 11668 Object* value, |
| 11606 PropertyAttributes attributes, | 11669 PropertyAttributes attributes, |
| 11607 StrictModeFlag strict_mode, | 11670 StrictModeFlag strict_mode, |
| 11608 bool check_prototype, | 11671 bool check_prototype, |
| 11609 SetPropertyMode set_mode) { | 11672 SetPropertyMode set_mode) { |
| 11610 Isolate* isolate = GetIsolate(); | 11673 Isolate* isolate = GetIsolate(); |
| 11611 HandleScope scope(isolate); | 11674 HandleScope scope(isolate); |
| 11612 | 11675 |
| 11613 // Make sure that the top context does not change when doing | 11676 // Make sure that the top context does not change when doing |
| 11614 // callbacks or interceptor calls. | 11677 // callbacks or interceptor calls. |
| 11615 AssertNoContextChange ncc; | 11678 AssertNoContextChange ncc(isolate); |
| 11616 | 11679 |
| 11617 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 11680 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 11618 Handle<JSObject> this_handle(this); | 11681 Handle<JSObject> this_handle(this); |
| 11619 Handle<Object> value_handle(value, isolate); | 11682 Handle<Object> value_handle(value, isolate); |
| 11620 if (!interceptor->setter()->IsUndefined()) { | 11683 if (!interceptor->setter()->IsUndefined()) { |
| 11621 v8::IndexedPropertySetterCallback setter = | 11684 v8::IndexedPropertySetterCallback setter = |
| 11622 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 11685 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 11623 LOG(isolate, | 11686 LOG(isolate, |
| 11624 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 11687 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 11625 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); | 11688 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12617 } | 12680 } |
| 12618 | 12681 |
| 12619 | 12682 |
| 12620 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, | 12683 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
| 12621 uint32_t index) { | 12684 uint32_t index) { |
| 12622 Isolate* isolate = GetIsolate(); | 12685 Isolate* isolate = GetIsolate(); |
| 12623 HandleScope scope(isolate); | 12686 HandleScope scope(isolate); |
| 12624 | 12687 |
| 12625 // Make sure that the top context does not change when doing | 12688 // Make sure that the top context does not change when doing |
| 12626 // callbacks or interceptor calls. | 12689 // callbacks or interceptor calls. |
| 12627 AssertNoContextChange ncc; | 12690 AssertNoContextChange ncc(isolate); |
| 12628 | 12691 |
| 12629 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate); | 12692 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate); |
| 12630 Handle<Object> this_handle(receiver, isolate); | 12693 Handle<Object> this_handle(receiver, isolate); |
| 12631 Handle<JSObject> holder_handle(this, isolate); | 12694 Handle<JSObject> holder_handle(this, isolate); |
| 12632 if (!interceptor->getter()->IsUndefined()) { | 12695 if (!interceptor->getter()->IsUndefined()) { |
| 12633 v8::IndexedPropertyGetterCallback getter = | 12696 v8::IndexedPropertyGetterCallback getter = |
| 12634 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); | 12697 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 12635 LOG(isolate, | 12698 LOG(isolate, |
| 12636 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); | 12699 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); |
| 12637 PropertyCallbackArguments | 12700 PropertyCallbackArguments |
| (...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13833 // for the next probe. | 13896 // for the next probe. |
| 13834 done = false; | 13897 done = false; |
| 13835 } | 13898 } |
| 13836 } | 13899 } |
| 13837 } | 13900 } |
| 13838 } | 13901 } |
| 13839 } | 13902 } |
| 13840 | 13903 |
| 13841 | 13904 |
| 13842 template<typename Shape, typename Key> | 13905 template<typename Shape, typename Key> |
| 13843 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 13906 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, |
| 13907 Key key, |
| 13908 PretenureFlag pretenure) { |
| 13844 int capacity = Capacity(); | 13909 int capacity = Capacity(); |
| 13845 int nof = NumberOfElements() + n; | 13910 int nof = NumberOfElements() + n; |
| 13846 int nod = NumberOfDeletedElements(); | 13911 int nod = NumberOfDeletedElements(); |
| 13847 // Return if: | 13912 // Return if: |
| 13848 // 50% is still free after adding n elements and | 13913 // 50% is still free after adding n elements and |
| 13849 // at most 50% of the free elements are deleted elements. | 13914 // at most 50% of the free elements are deleted elements. |
| 13850 if (nod <= (capacity - nof) >> 1) { | 13915 if (nod <= (capacity - nof) >> 1) { |
| 13851 int needed_free = nof >> 1; | 13916 int needed_free = nof >> 1; |
| 13852 if (nof + needed_free <= capacity) return this; | 13917 if (nof + needed_free <= capacity) return this; |
| 13853 } | 13918 } |
| 13854 | 13919 |
| 13855 const int kMinCapacityForPretenure = 256; | 13920 const int kMinCapacityForPretenure = 256; |
| 13856 bool pretenure = | 13921 bool should_pretenure = pretenure == TENURED || |
| 13857 (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this); | 13922 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); |
| 13858 Object* obj; | 13923 Object* obj; |
| 13859 { MaybeObject* maybe_obj = | 13924 { MaybeObject* maybe_obj = |
| 13860 Allocate(GetHeap(), | 13925 Allocate(GetHeap(), |
| 13861 nof * 2, | 13926 nof * 2, |
| 13862 USE_DEFAULT_MINIMUM_CAPACITY, | 13927 USE_DEFAULT_MINIMUM_CAPACITY, |
| 13863 pretenure ? TENURED : NOT_TENURED); | 13928 should_pretenure ? TENURED : NOT_TENURED); |
| 13864 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13929 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 13865 } | 13930 } |
| 13866 | 13931 |
| 13867 return Rehash(HashTable::cast(obj), key); | 13932 return Rehash(HashTable::cast(obj), key); |
| 13868 } | 13933 } |
| 13869 | 13934 |
| 13870 | 13935 |
| 13871 template<typename Shape, typename Key> | 13936 template<typename Shape, typename Key> |
| 13872 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 13937 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { |
| 13873 int capacity = Capacity(); | 13938 int capacity = Capacity(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13921 template class HashTable<StringTableShape, HashTableKey*>; | 13986 template class HashTable<StringTableShape, HashTableKey*>; |
| 13922 | 13987 |
| 13923 template class HashTable<CompilationCacheShape, HashTableKey*>; | 13988 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 13924 | 13989 |
| 13925 template class HashTable<MapCacheShape, HashTableKey*>; | 13990 template class HashTable<MapCacheShape, HashTableKey*>; |
| 13926 | 13991 |
| 13927 template class HashTable<ObjectHashTableShape<1>, Object*>; | 13992 template class HashTable<ObjectHashTableShape<1>, Object*>; |
| 13928 | 13993 |
| 13929 template class HashTable<ObjectHashTableShape<2>, Object*>; | 13994 template class HashTable<ObjectHashTableShape<2>, Object*>; |
| 13930 | 13995 |
| 13996 template class HashTable<WeakHashTableShape<2>, Object*>; |
| 13997 |
| 13931 template class Dictionary<NameDictionaryShape, Name*>; | 13998 template class Dictionary<NameDictionaryShape, Name*>; |
| 13932 | 13999 |
| 13933 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 14000 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; |
| 13934 | 14001 |
| 13935 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; | 14002 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; |
| 13936 | 14003 |
| 13937 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14004 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 13938 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14005 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 13939 | 14006 |
| 13940 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14007 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| (...skipping 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15563 } | 15630 } |
| 15564 | 15631 |
| 15565 | 15632 |
| 15566 void ObjectHashTable::RemoveEntry(int entry) { | 15633 void ObjectHashTable::RemoveEntry(int entry) { |
| 15567 set_the_hole(EntryToIndex(entry)); | 15634 set_the_hole(EntryToIndex(entry)); |
| 15568 set_the_hole(EntryToIndex(entry) + 1); | 15635 set_the_hole(EntryToIndex(entry) + 1); |
| 15569 ElementRemoved(); | 15636 ElementRemoved(); |
| 15570 } | 15637 } |
| 15571 | 15638 |
| 15572 | 15639 |
| 15640 Object* WeakHashTable::Lookup(Object* key) { |
| 15641 ASSERT(IsKey(key)); |
| 15642 int entry = FindEntry(key); |
| 15643 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| 15644 return get(EntryToValueIndex(entry)); |
| 15645 } |
| 15646 |
| 15647 |
| 15648 MaybeObject* WeakHashTable::Put(Object* key, Object* value) { |
| 15649 ASSERT(IsKey(key)); |
| 15650 int entry = FindEntry(key); |
| 15651 // Key is already in table, just overwrite value. |
| 15652 if (entry != kNotFound) { |
| 15653 set(EntryToValueIndex(entry), value); |
| 15654 return this; |
| 15655 } |
| 15656 |
| 15657 // Check whether the hash table should be extended. |
| 15658 Object* obj; |
| 15659 { MaybeObject* maybe_obj = EnsureCapacity(1, key, TENURED); |
| 15660 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15661 } |
| 15662 WeakHashTable* table = WeakHashTable::cast(obj); |
| 15663 table->AddEntry(table->FindInsertionEntry(Hash(key)), key, value); |
| 15664 return table; |
| 15665 } |
| 15666 |
| 15667 |
| 15668 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { |
| 15669 set(EntryToIndex(entry), key); |
| 15670 set(EntryToValueIndex(entry), value); |
| 15671 ElementAdded(); |
| 15672 } |
| 15673 |
| 15674 |
| 15573 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( | 15675 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( |
| 15574 DeclaredAccessorDescriptor* descriptor) | 15676 DeclaredAccessorDescriptor* descriptor) |
| 15575 : array_(descriptor->serialized_data()->GetDataStartAddress()), | 15677 : array_(descriptor->serialized_data()->GetDataStartAddress()), |
| 15576 length_(descriptor->serialized_data()->length()), | 15678 length_(descriptor->serialized_data()->length()), |
| 15577 offset_(0) { | 15679 offset_(0) { |
| 15578 } | 15680 } |
| 15579 | 15681 |
| 15580 | 15682 |
| 15581 const DeclaredAccessorDescriptorData* | 15683 const DeclaredAccessorDescriptorData* |
| 15582 DeclaredAccessorDescriptorIterator::Next() { | 15684 DeclaredAccessorDescriptorIterator::Next() { |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16119 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16221 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16120 static const char* error_messages_[] = { | 16222 static const char* error_messages_[] = { |
| 16121 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16223 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16122 }; | 16224 }; |
| 16123 #undef ERROR_MESSAGES_TEXTS | 16225 #undef ERROR_MESSAGES_TEXTS |
| 16124 return error_messages_[reason]; | 16226 return error_messages_[reason]; |
| 16125 } | 16227 } |
| 16126 | 16228 |
| 16127 | 16229 |
| 16128 } } // namespace v8::internal | 16230 } } // namespace v8::internal |
| OLD | NEW |