Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: src/objects.cc

Issue 7607031: Update gc branch to bleeding_edge revision 8862. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Fix bug in weak-map merge Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "arguments.h" 31 #include "arguments.h"
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "debug.h" 34 #include "debug.h"
35 #include "deoptimizer.h" 35 #include "deoptimizer.h"
36 #include "elements.h"
36 #include "execution.h" 37 #include "execution.h"
37 #include "full-codegen.h" 38 #include "full-codegen.h"
38 #include "hydrogen.h" 39 #include "hydrogen.h"
39 #include "objects-inl.h" 40 #include "objects-inl.h"
40 #include "objects-visiting.h" 41 #include "objects-visiting.h"
41 #include "objects-visiting-inl.h" 42 #include "objects-visiting-inl.h"
42 #include "macro-assembler.h" 43 #include "macro-assembler.h"
43 #include "mark-compact.h" 44 #include "mark-compact.h"
44 #include "safepoint-table.h" 45 #include "safepoint-table.h"
45 #include "scanner-base.h" 46 #include "scanner-base.h"
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 case CONSTANT_TRANSITION: 598 case CONSTANT_TRANSITION:
598 case NULL_DESCRIPTOR: 599 case NULL_DESCRIPTOR:
599 break; 600 break;
600 } 601 }
601 UNREACHABLE(); 602 UNREACHABLE();
602 return NULL; 603 return NULL;
603 } 604 }
604 605
605 606
606 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { 607 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
607 Object* holder = NULL; 608 Heap* heap = IsSmi()
608 if (IsSmi()) { 609 ? Isolate::Current()->heap()
609 Context* global_context = Isolate::Current()->context()->global_context(); 610 : HeapObject::cast(this)->GetHeap();
610 holder = global_context->number_function()->instance_prototype(); 611 Object* holder = this;
611 } else {
612 HeapObject* heap_object = HeapObject::cast(this);
613 612
614 if (heap_object->IsJSObject()) { 613 // Iterate up the prototype chain until an element is found or the null
615 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); 614 // prototype is encountered.
615 for (holder = this;
616 holder != heap->null_value();
617 holder = holder->GetPrototype()) {
618 if (holder->IsSmi()) {
619 Context* global_context = Isolate::Current()->context()->global_context();
620 holder = global_context->number_function()->instance_prototype();
621 } else {
622 HeapObject* heap_object = HeapObject::cast(holder);
623 if (!heap_object->IsJSObject()) {
624 Isolate* isolate = heap->isolate();
625 Context* global_context = isolate->context()->global_context();
626 if (heap_object->IsString()) {
627 holder = global_context->string_function()->instance_prototype();
628 } else if (heap_object->IsHeapNumber()) {
629 holder = global_context->number_function()->instance_prototype();
630 } else if (heap_object->IsBoolean()) {
631 holder = global_context->boolean_function()->instance_prototype();
632 } else if (heap_object->IsJSProxy()) {
633 return heap->undefined_value(); // For now...
634 } else {
635 // Undefined and null have no indexed properties.
636 ASSERT(heap_object->IsUndefined() || heap_object->IsNull());
637 return heap->undefined_value();
638 }
639 }
616 } 640 }
617 Heap* heap = heap_object->GetHeap();
618 Isolate* isolate = heap->isolate();
619 641
620 Context* global_context = isolate->context()->global_context(); 642 // Inline the case for JSObjects. Doing so significantly improves the
621 if (heap_object->IsString()) { 643 // performance of fetching elements where checking the prototype chain is
622 holder = global_context->string_function()->instance_prototype(); 644 // necessary.
623 } else if (heap_object->IsHeapNumber()) { 645 JSObject* js_object = JSObject::cast(holder);
624 holder = global_context->number_function()->instance_prototype(); 646
625 } else if (heap_object->IsBoolean()) { 647 // Check access rights if needed.
626 holder = global_context->boolean_function()->instance_prototype(); 648 if (js_object->IsAccessCheckNeeded()) {
627 } else if (heap_object->IsJSProxy()) { 649 Isolate* isolate = heap->isolate();
628 return heap->undefined_value(); // For now... 650 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
629 } else { 651 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
630 // Undefined and null have no indexed properties. 652 return heap->undefined_value();
631 ASSERT(heap_object->IsUndefined() || heap_object->IsNull()); 653 }
632 return heap->undefined_value(); 654 }
655
656 if (js_object->HasIndexedInterceptor()) {
657 return js_object->GetElementWithInterceptor(receiver, index);
658 }
659
660 if (js_object->elements() != heap->empty_fixed_array()) {
661 MaybeObject* result = js_object->GetElementsAccessor()->GetWithReceiver(
662 js_object,
663 receiver,
664 index);
665 if (result != heap->the_hole_value()) return result;
633 } 666 }
634 } 667 }
635 668
636 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); 669 return heap->undefined_value();
637 } 670 }
638 671
639 672
640 Object* Object::GetPrototype() { 673 Object* Object::GetPrototype() {
641 if (IsSmi()) { 674 if (IsSmi()) {
642 Heap* heap = Isolate::Current()->heap(); 675 Heap* heap = Isolate::Current()->heap();
643 Context* context = heap->isolate()->context()->global_context(); 676 Context* context = heap->isolate()->context()->global_context();
644 return context->number_function()->instance_prototype(); 677 return context->number_function()->instance_prototype();
645 } 678 }
646 679
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 } 997 }
965 998
966 999
967 void JSObject::JSObjectShortPrint(StringStream* accumulator) { 1000 void JSObject::JSObjectShortPrint(StringStream* accumulator) {
968 switch (map()->instance_type()) { 1001 switch (map()->instance_type()) {
969 case JS_ARRAY_TYPE: { 1002 case JS_ARRAY_TYPE: {
970 double length = JSArray::cast(this)->length()->Number(); 1003 double length = JSArray::cast(this)->length()->Number();
971 accumulator->Add("<JS array[%u]>", static_cast<uint32_t>(length)); 1004 accumulator->Add("<JS array[%u]>", static_cast<uint32_t>(length));
972 break; 1005 break;
973 } 1006 }
1007 case JS_WEAK_MAP_TYPE: {
1008 int elements = JSWeakMap::cast(this)->table()->NumberOfElements();
1009 accumulator->Add("<JS WeakMap[%d]>", elements);
1010 break;
1011 }
974 case JS_REGEXP_TYPE: { 1012 case JS_REGEXP_TYPE: {
975 accumulator->Add("<JS RegExp>"); 1013 accumulator->Add("<JS RegExp>");
976 break; 1014 break;
977 } 1015 }
978 case JS_FUNCTION_TYPE: { 1016 case JS_FUNCTION_TYPE: {
979 Object* fun_name = JSFunction::cast(this)->shared()->name(); 1017 Object* fun_name = JSFunction::cast(this)->shared()->name();
980 bool printed = false; 1018 bool printed = false;
981 if (fun_name->IsString()) { 1019 if (fun_name->IsString()) {
982 String* str = String::cast(fun_name); 1020 String* str = String::cast(fun_name);
983 if (str->length() > 0) { 1021 if (str->length() > 0) {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 switch (type) { 1235 switch (type) {
1198 case FIXED_ARRAY_TYPE: 1236 case FIXED_ARRAY_TYPE:
1199 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); 1237 FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1200 break; 1238 break;
1201 case FIXED_DOUBLE_ARRAY_TYPE: 1239 case FIXED_DOUBLE_ARRAY_TYPE:
1202 break; 1240 break;
1203 case JS_OBJECT_TYPE: 1241 case JS_OBJECT_TYPE:
1204 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 1242 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1205 case JS_VALUE_TYPE: 1243 case JS_VALUE_TYPE:
1206 case JS_ARRAY_TYPE: 1244 case JS_ARRAY_TYPE:
1245 case JS_WEAK_MAP_TYPE:
1207 case JS_REGEXP_TYPE: 1246 case JS_REGEXP_TYPE:
1208 case JS_GLOBAL_PROXY_TYPE: 1247 case JS_GLOBAL_PROXY_TYPE:
1209 case JS_GLOBAL_OBJECT_TYPE: 1248 case JS_GLOBAL_OBJECT_TYPE:
1210 case JS_BUILTINS_OBJECT_TYPE: 1249 case JS_BUILTINS_OBJECT_TYPE:
1211 case JS_MESSAGE_OBJECT_TYPE: 1250 case JS_MESSAGE_OBJECT_TYPE:
1212 JSObject::BodyDescriptor::IterateBody(this, object_size, v); 1251 JSObject::BodyDescriptor::IterateBody(this, object_size, v);
1213 break; 1252 break;
1214 case JS_FUNCTION_TYPE: 1253 case JS_FUNCTION_TYPE:
1215 reinterpret_cast<JSFunction*>(this) 1254 reinterpret_cast<JSFunction*>(this)
1216 ->JSFunctionIterateBody(object_size, v); 1255 ->JSFunctionIterateBody(object_size, v);
(...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after
2934 if (has_double_elements) { 2973 if (has_double_elements) {
2935 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); 2974 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
2936 if (double_array->is_the_hole(i)) { 2975 if (double_array->is_the_hole(i)) {
2937 value = GetIsolate()->heap()->the_hole_value(); 2976 value = GetIsolate()->heap()->the_hole_value();
2938 } else { 2977 } else {
2939 // Objects must be allocated in the old object space, since the 2978 // Objects must be allocated in the old object space, since the
2940 // overall number of HeapNumbers needed for the conversion might 2979 // overall number of HeapNumbers needed for the conversion might
2941 // exceed the capacity of new space, and we would fail repeatedly 2980 // exceed the capacity of new space, and we would fail repeatedly
2942 // trying to convert the FixedDoubleArray. 2981 // trying to convert the FixedDoubleArray.
2943 MaybeObject* maybe_value_object = 2982 MaybeObject* maybe_value_object =
2944 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED); 2983 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
2945 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2984 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
2946 } 2985 }
2947 } else { 2986 } else {
2948 ASSERT(old_map->has_fast_elements()); 2987 ASSERT(old_map->has_fast_elements());
2949 value = FixedArray::cast(array)->get(i); 2988 value = FixedArray::cast(array)->get(i);
2950 } 2989 }
2951 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2990 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2952 if (!value->IsTheHole()) { 2991 if (!value->IsTheHole()) {
2953 Object* result; 2992 Object* result;
2954 MaybeObject* maybe_result = 2993 MaybeObject* maybe_result =
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
3113 return *v8::Utils::OpenHandle(*result); 3152 return *v8::Utils::OpenHandle(*result);
3114 } 3153 }
3115 } 3154 }
3116 MaybeObject* raw_result = 3155 MaybeObject* raw_result =
3117 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); 3156 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
3118 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 3157 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3119 return raw_result; 3158 return raw_result;
3120 } 3159 }
3121 3160
3122 3161
3123 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index,
3124 DeleteMode mode) {
3125 ASSERT(!HasExternalArrayElements());
3126 switch (GetElementsKind()) {
3127 case FAST_ELEMENTS: {
3128 Object* obj;
3129 { MaybeObject* maybe_obj = EnsureWritableFastElements();
3130 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3131 }
3132 uint32_t length = IsJSArray() ?
3133 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
3134 static_cast<uint32_t>(FixedArray::cast(elements())->length());
3135 if (index < length) {
3136 FixedArray::cast(elements())->set_the_hole(index);
3137 }
3138 break;
3139 }
3140 case DICTIONARY_ELEMENTS: {
3141 NumberDictionary* dictionary = element_dictionary();
3142 int entry = dictionary->FindEntry(index);
3143 if (entry != NumberDictionary::kNotFound) {
3144 Object* deleted = dictionary->DeleteProperty(entry, mode);
3145 if (deleted == GetHeap()->true_value()) {
3146 MaybeObject* maybe_elements = dictionary->Shrink(index);
3147 FixedArray* new_elements = NULL;
3148 if (!maybe_elements->To(&new_elements)) {
3149 return maybe_elements;
3150 }
3151 set_elements(new_elements);
3152 }
3153 return deleted;
3154 }
3155 break;
3156 }
3157 default:
3158 UNREACHABLE();
3159 break;
3160 }
3161 return GetHeap()->true_value();
3162 }
3163
3164
3165 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { 3162 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
3166 Isolate* isolate = GetIsolate(); 3163 Isolate* isolate = GetIsolate();
3167 Heap* heap = isolate->heap(); 3164 Heap* heap = isolate->heap();
3168 // Make sure that the top context does not change when doing 3165 // Make sure that the top context does not change when doing
3169 // callbacks or interceptor calls. 3166 // callbacks or interceptor calls.
3170 AssertNoContextChange ncc; 3167 AssertNoContextChange ncc;
3171 HandleScope scope(isolate); 3168 HandleScope scope(isolate);
3172 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 3169 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
3173 if (interceptor->deleter()->IsUndefined()) return heap->false_value(); 3170 if (interceptor->deleter()->IsUndefined()) return heap->false_value();
3174 v8::IndexedPropertyDeleter deleter = 3171 v8::IndexedPropertyDeleter deleter =
3175 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); 3172 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter());
3176 Handle<JSObject> this_handle(this); 3173 Handle<JSObject> this_handle(this);
3177 LOG(isolate, 3174 LOG(isolate,
3178 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); 3175 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index));
3179 CustomArguments args(isolate, interceptor->data(), this, this); 3176 CustomArguments args(isolate, interceptor->data(), this, this);
3180 v8::AccessorInfo info(args.end()); 3177 v8::AccessorInfo info(args.end());
3181 v8::Handle<v8::Boolean> result; 3178 v8::Handle<v8::Boolean> result;
3182 { 3179 {
3183 // Leaving JavaScript. 3180 // Leaving JavaScript.
3184 VMState state(isolate, EXTERNAL); 3181 VMState state(isolate, EXTERNAL);
3185 result = deleter(index, info); 3182 result = deleter(index, info);
3186 } 3183 }
3187 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 3184 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3188 if (!result.IsEmpty()) { 3185 if (!result.IsEmpty()) {
3189 ASSERT(result->IsBoolean()); 3186 ASSERT(result->IsBoolean());
3190 return *v8::Utils::OpenHandle(*result); 3187 return *v8::Utils::OpenHandle(*result);
3191 } 3188 }
3192 MaybeObject* raw_result = 3189 MaybeObject* raw_result = GetElementsAccessor()->Delete(*this_handle,
3193 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); 3190 index,
3191 NORMAL_DELETION);
3194 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 3192 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3195 return raw_result; 3193 return raw_result;
3196 } 3194 }
3197 3195
3198 3196
3199 MaybeObject* JSObject::DeleteFastElement(uint32_t index) {
3200 ASSERT(HasFastElements() || HasFastArgumentsElements());
3201 Heap* heap = GetHeap();
3202 FixedArray* backing_store = FixedArray::cast(elements());
3203 if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
3204 backing_store = FixedArray::cast(backing_store->get(1));
3205 } else {
3206 Object* writable;
3207 MaybeObject* maybe = EnsureWritableFastElements();
3208 if (!maybe->ToObject(&writable)) return maybe;
3209 backing_store = FixedArray::cast(writable);
3210 }
3211 uint32_t length = static_cast<uint32_t>(
3212 IsJSArray()
3213 ? Smi::cast(JSArray::cast(this)->length())->value()
3214 : backing_store->length());
3215 if (index < length) {
3216 backing_store->set_the_hole(index);
3217 // If an old space backing store is larger than a certain size and
3218 // has too few used values, normalize it.
3219 // To avoid doing the check on every delete we require at least
3220 // one adjacent hole to the value being deleted.
3221 Object* hole = heap->the_hole_value();
3222 const int kMinLengthForSparsenessCheck = 64;
3223 if (backing_store->length() >= kMinLengthForSparsenessCheck &&
3224 !heap->InNewSpace(backing_store) &&
3225 ((index > 0 && backing_store->get(index - 1) == hole) ||
3226 (index + 1 < length && backing_store->get(index + 1) == hole))) {
3227 int num_used = 0;
3228 for (int i = 0; i < backing_store->length(); ++i) {
3229 if (backing_store->get(i) != hole) ++num_used;
3230 // Bail out early if more than 1/4 is used.
3231 if (4 * num_used > backing_store->length()) break;
3232 }
3233 if (4 * num_used <= backing_store->length()) {
3234 MaybeObject* result = NormalizeElements();
3235 if (result->IsFailure()) return result;
3236 }
3237 }
3238 }
3239 return heap->true_value();
3240 }
3241
3242
3243 MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index,
3244 DeleteMode mode) {
3245 Isolate* isolate = GetIsolate();
3246 Heap* heap = isolate->heap();
3247 FixedArray* backing_store = FixedArray::cast(elements());
3248 bool is_arguments =
3249 (GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
3250 if (is_arguments) {
3251 backing_store = FixedArray::cast(backing_store->get(1));
3252 }
3253 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
3254 int entry = dictionary->FindEntry(index);
3255 if (entry != NumberDictionary::kNotFound) {
3256 Object* result = dictionary->DeleteProperty(entry, mode);
3257 if (result == heap->true_value()) {
3258 MaybeObject* maybe_elements = dictionary->Shrink(index);
3259 FixedArray* new_elements = NULL;
3260 if (!maybe_elements->To(&new_elements)) {
3261 return maybe_elements;
3262 }
3263 if (is_arguments) {
3264 FixedArray::cast(elements())->set(1, new_elements);
3265 } else {
3266 set_elements(new_elements);
3267 }
3268 }
3269 if (mode == STRICT_DELETION && result == heap->false_value()) {
3270 // In strict mode, attempting to delete a non-configurable property
3271 // throws an exception.
3272 HandleScope scope(isolate);
3273 Handle<Object> holder(this);
3274 Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
3275 Handle<Object> args[2] = { name, holder };
3276 Handle<Object> error =
3277 isolate->factory()->NewTypeError("strict_delete_property",
3278 HandleVector(args, 2));
3279 return isolate->Throw(*error);
3280 }
3281 }
3282 return heap->true_value();
3283 }
3284
3285
3286 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { 3197 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
3287 Isolate* isolate = GetIsolate(); 3198 Isolate* isolate = GetIsolate();
3288 // Check access rights if needed. 3199 // Check access rights if needed.
3289 if (IsAccessCheckNeeded() && 3200 if (IsAccessCheckNeeded() &&
3290 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { 3201 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
3291 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 3202 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
3292 return isolate->heap()->false_value(); 3203 return isolate->heap()->false_value();
3293 } 3204 }
3294 3205
3295 if (IsJSGlobalProxy()) { 3206 if (IsJSGlobalProxy()) {
3296 Object* proto = GetPrototype(); 3207 Object* proto = GetPrototype();
3297 if (proto->IsNull()) return isolate->heap()->false_value(); 3208 if (proto->IsNull()) return isolate->heap()->false_value();
3298 ASSERT(proto->IsJSGlobalObject()); 3209 ASSERT(proto->IsJSGlobalObject());
3299 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); 3210 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
3300 } 3211 }
3301 3212
3302 if (HasIndexedInterceptor()) { 3213 if (HasIndexedInterceptor()) {
3303 // Skip interceptor if forcing deletion. 3214 // Skip interceptor if forcing deletion.
3304 return (mode == FORCE_DELETION) 3215 if (mode != FORCE_DELETION) {
3305 ? DeleteElementPostInterceptor(index, FORCE_DELETION) 3216 return DeleteElementWithInterceptor(index);
3306 : DeleteElementWithInterceptor(index); 3217 }
3218 mode = JSReceiver::FORCE_DELETION;
3307 } 3219 }
3308 3220
3309 switch (GetElementsKind()) { 3221 return GetElementsAccessor()->Delete(this, index, mode);
3310 case FAST_ELEMENTS:
3311 return DeleteFastElement(index);
3312
3313 case DICTIONARY_ELEMENTS:
3314 return DeleteDictionaryElement(index, mode);
3315
3316 case FAST_DOUBLE_ELEMENTS: {
3317 int length = IsJSArray()
3318 ? Smi::cast(JSArray::cast(this)->length())->value()
3319 : FixedDoubleArray::cast(elements())->length();
3320 if (index < static_cast<uint32_t>(length)) {
3321 FixedDoubleArray::cast(elements())->set_the_hole(index);
3322 }
3323 break;
3324 }
3325 case EXTERNAL_PIXEL_ELEMENTS:
3326 case EXTERNAL_BYTE_ELEMENTS:
3327 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3328 case EXTERNAL_SHORT_ELEMENTS:
3329 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3330 case EXTERNAL_INT_ELEMENTS:
3331 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3332 case EXTERNAL_FLOAT_ELEMENTS:
3333 case EXTERNAL_DOUBLE_ELEMENTS:
3334 // Pixel and external array elements cannot be deleted. Just
3335 // silently ignore here.
3336 break;
3337
3338 case NON_STRICT_ARGUMENTS_ELEMENTS: {
3339 FixedArray* parameter_map = FixedArray::cast(elements());
3340 uint32_t length = parameter_map->length();
3341 Object* probe =
3342 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
3343 if (probe != NULL && !probe->IsTheHole()) {
3344 // TODO(kmillikin): We could check if this was the last aliased
3345 // parameter, and revert to normal elements in that case. That
3346 // would enable GC of the context.
3347 parameter_map->set_the_hole(index + 2);
3348 } else {
3349 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
3350 if (arguments->IsDictionary()) {
3351 return DeleteDictionaryElement(index, mode);
3352 } else {
3353 return DeleteFastElement(index);
3354 }
3355 }
3356 break;
3357 }
3358 }
3359 return isolate->heap()->true_value();
3360 } 3222 }
3361 3223
3362 3224
3363 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) { 3225 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
3364 if (IsJSProxy()) { 3226 if (IsJSProxy()) {
3365 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); 3227 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
3366 } else { 3228 } else {
3367 return JSObject::cast(this)->DeleteProperty(name, mode); 3229 return JSObject::cast(this)->DeleteProperty(name, mode);
3368 } 3230 }
3369 } 3231 }
(...skipping 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after
4910 // We cannot optimize if 'this' is empty, as other may have holes 4772 // We cannot optimize if 'this' is empty, as other may have holes
4911 // or non keys. 4773 // or non keys.
4912 if (len1 == 0) return this; 4774 if (len1 == 0) return this;
4913 4775
4914 // Compute how many elements are not in this. 4776 // Compute how many elements are not in this.
4915 int extra = 0; 4777 int extra = 0;
4916 Heap* heap = GetHeap(); 4778 Heap* heap = GetHeap();
4917 Object* obj; 4779 Object* obj;
4918 for (int y = 0; y < len1; y++) { 4780 for (int y = 0; y < len1; y++) {
4919 if (!other->is_the_hole(y)) { 4781 if (!other->is_the_hole(y)) {
4920 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); 4782 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get_scalar(y));
4921 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 4783 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4922 if (!HasKey(this, obj)) extra++; 4784 if (!HasKey(this, obj)) extra++;
4923 } 4785 }
4924 } 4786 }
4925 4787
4926 if (extra == 0) return this; 4788 if (extra == 0) return this;
4927 4789
4928 // Allocate the result 4790 // Allocate the result
4929 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); 4791 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra);
4930 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 4792 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4931 } 4793 }
4932 // Fill in the content 4794 // Fill in the content
4933 FixedArray* result = FixedArray::cast(obj); 4795 FixedArray* result = FixedArray::cast(obj);
4934 { 4796 {
4935 // Limit the scope of the AssertNoAllocation 4797 // Limit the scope of the AssertNoAllocation
4936 AssertNoAllocation no_gc; 4798 AssertNoAllocation no_gc;
4937 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 4799 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
4938 for (int i = 0; i < len0; i++) { 4800 for (int i = 0; i < len0; i++) {
4939 Object* e = get(i); 4801 Object* e = get(i);
4940 ASSERT(e->IsString() || e->IsNumber()); 4802 ASSERT(e->IsString() || e->IsNumber());
4941 result->set(i, e, mode); 4803 result->set(i, e, mode);
4942 } 4804 }
4943 } 4805 }
4944 4806
4945 // Fill in the extra keys. 4807 // Fill in the extra keys.
4946 int index = 0; 4808 int index = 0;
4947 for (int y = 0; y < len1; y++) { 4809 for (int y = 0; y < len1; y++) {
4948 if (!other->is_the_hole(y)) { 4810 if (!other->is_the_hole(y)) {
4949 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); 4811 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get_scalar(y));
4950 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 4812 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4951 if (!HasKey(this, obj)) { 4813 if (!HasKey(this, obj)) {
4952 result->set(len0 + index, obj); 4814 result->set(len0 + index, obj);
4953 index++; 4815 index++;
4954 } 4816 }
4955 } 4817 }
4956 } 4818 }
4957 ASSERT(extra == index); 4819 ASSERT(extra == index);
4958 return result; 4820 return result;
4959 } 4821 }
(...skipping 2262 matching lines...) Expand 10 before | Expand all | Expand 10 after
7222 #ifdef ENABLE_DISASSEMBLER 7084 #ifdef ENABLE_DISASSEMBLER
7223 7085
7224 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) { 7086 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
7225 disasm::NameConverter converter; 7087 disasm::NameConverter converter;
7226 int deopt_count = DeoptCount(); 7088 int deopt_count = DeoptCount();
7227 PrintF(out, "Deoptimization Input Data (deopt points = %d)\n", deopt_count); 7089 PrintF(out, "Deoptimization Input Data (deopt points = %d)\n", deopt_count);
7228 if (0 == deopt_count) return; 7090 if (0 == deopt_count) return;
7229 7091
7230 PrintF(out, "%6s %6s %6s %12s\n", "index", "ast id", "argc", "commands"); 7092 PrintF(out, "%6s %6s %6s %12s\n", "index", "ast id", "argc", "commands");
7231 for (int i = 0; i < deopt_count; i++) { 7093 for (int i = 0; i < deopt_count; i++) {
7232 int command_count = 0;
7233 PrintF(out, "%6d %6d %6d", 7094 PrintF(out, "%6d %6d %6d",
7234 i, AstId(i)->value(), ArgumentsStackHeight(i)->value()); 7095 i, AstId(i)->value(), ArgumentsStackHeight(i)->value());
7096
7097 if (!FLAG_print_code_verbose) continue;
7098 // Print details of the frame translation.
7235 int translation_index = TranslationIndex(i)->value(); 7099 int translation_index = TranslationIndex(i)->value();
7236 TranslationIterator iterator(TranslationByteArray(), translation_index); 7100 TranslationIterator iterator(TranslationByteArray(), translation_index);
7237 Translation::Opcode opcode = 7101 Translation::Opcode opcode =
7238 static_cast<Translation::Opcode>(iterator.Next()); 7102 static_cast<Translation::Opcode>(iterator.Next());
7239 ASSERT(Translation::BEGIN == opcode); 7103 ASSERT(Translation::BEGIN == opcode);
7240 int frame_count = iterator.Next(); 7104 int frame_count = iterator.Next();
7241 if (FLAG_print_code_verbose) { 7105 PrintF(out, " %s {count=%d}\n", Translation::StringFor(opcode),
7242 PrintF(out, " %s {count=%d}\n", Translation::StringFor(opcode), 7106 frame_count);
7243 frame_count);
7244 }
7245 7107
7246 for (int i = 0; i < frame_count; ++i) { 7108 while (iterator.HasNext() &&
7247 opcode = static_cast<Translation::Opcode>(iterator.Next()); 7109 Translation::BEGIN !=
7248 ASSERT(Translation::FRAME == opcode); 7110 (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
7249 int ast_id = iterator.Next(); 7111 PrintF(out, "%24s %s ", "", Translation::StringFor(opcode));
7250 int function_id = iterator.Next();
7251 JSFunction* function =
7252 JSFunction::cast(LiteralArray()->get(function_id));
7253 unsigned height = iterator.Next();
7254 if (FLAG_print_code_verbose) {
7255 PrintF(out, "%24s %s {ast_id=%d, function=",
7256 "", Translation::StringFor(opcode), ast_id);
7257 function->PrintName(out);
7258 PrintF(out, ", height=%u}\n", height);
7259 }
7260 7112
7261 // Size of translation is height plus all incoming arguments including 7113 switch (opcode) {
7262 // receiver. 7114 case Translation::BEGIN:
7263 int size = height + function->shared()->formal_parameter_count() + 1; 7115 UNREACHABLE();
7264 command_count += size; 7116 break;
7265 for (int j = 0; j < size; ++j) { 7117
7266 opcode = static_cast<Translation::Opcode>(iterator.Next()); 7118 case Translation::FRAME: {
7267 if (FLAG_print_code_verbose) { 7119 int ast_id = iterator.Next();
7268 PrintF(out, "%24s %s ", "", Translation::StringFor(opcode)); 7120 int function_id = iterator.Next();
7121 JSFunction* function =
7122 JSFunction::cast(LiteralArray()->get(function_id));
7123 unsigned height = iterator.Next();
7124 PrintF(out, "{ast_id=%d, \nfunction=", ast_id);
7125 function->PrintName(out);
7126 PrintF(out, ", height=%u}", height);
7127 break;
7269 } 7128 }
7270 7129
7271 if (opcode == Translation::DUPLICATE) { 7130 case Translation::DUPLICATE:
7272 opcode = static_cast<Translation::Opcode>(iterator.Next()); 7131 break;
7273 if (FLAG_print_code_verbose) { 7132
7274 PrintF(out, "%s ", Translation::StringFor(opcode)); 7133 case Translation::REGISTER: {
7275 } 7134 int reg_code = iterator.Next();
7276 --j; // Two commands share the same frame index. 7135 PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code));
7136 break;
7277 } 7137 }
7278 7138
7279 switch (opcode) { 7139 case Translation::INT32_REGISTER: {
7280 case Translation::BEGIN: 7140 int reg_code = iterator.Next();
7281 case Translation::FRAME: 7141 PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code));
7282 case Translation::DUPLICATE: 7142 break;
7283 UNREACHABLE(); 7143 }
7284 break;
7285 7144
7286 case Translation::REGISTER: { 7145 case Translation::DOUBLE_REGISTER: {
7287 int reg_code = iterator.Next(); 7146 int reg_code = iterator.Next();
7288 if (FLAG_print_code_verbose) { 7147 PrintF(out, "{input=%s}",
7289 PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code)); 7148 DoubleRegister::AllocationIndexToString(reg_code));
7290 } 7149 break;
7291 break; 7150 }
7292 }
7293 7151
7294 case Translation::INT32_REGISTER: { 7152 case Translation::STACK_SLOT: {
7295 int reg_code = iterator.Next(); 7153 int input_slot_index = iterator.Next();
7296 if (FLAG_print_code_verbose) { 7154 PrintF(out, "{input=%d}", input_slot_index);
7297 PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code)); 7155 break;
7298 } 7156 }
7299 break;
7300 }
7301 7157
7302 case Translation::DOUBLE_REGISTER: { 7158 case Translation::INT32_STACK_SLOT: {
7303 int reg_code = iterator.Next(); 7159 int input_slot_index = iterator.Next();
7304 if (FLAG_print_code_verbose) { 7160 PrintF(out, "{input=%d}", input_slot_index);
7305 PrintF(out, "{input=%s}", 7161 break;
7306 DoubleRegister::AllocationIndexToString(reg_code)); 7162 }
7307 }
7308 break;
7309 }
7310 7163
7311 case Translation::STACK_SLOT: { 7164 case Translation::DOUBLE_STACK_SLOT: {
7312 int input_slot_index = iterator.Next(); 7165 int input_slot_index = iterator.Next();
7313 if (FLAG_print_code_verbose) { 7166 PrintF(out, "{input=%d}", input_slot_index);
7314 PrintF(out, "{input=%d}", input_slot_index); 7167 break;
7315 } 7168 }
7316 break;
7317 }
7318 7169
7319 case Translation::INT32_STACK_SLOT: { 7170 case Translation::LITERAL: {
7320 int input_slot_index = iterator.Next(); 7171 unsigned literal_index = iterator.Next();
7321 if (FLAG_print_code_verbose) { 7172 PrintF(out, "{literal_id=%u}", literal_index);
7322 PrintF(out, "{input=%d}", input_slot_index); 7173 break;
7323 } 7174 }
7324 break;
7325 }
7326 7175
7327 case Translation::DOUBLE_STACK_SLOT: { 7176 case Translation::ARGUMENTS_OBJECT:
7328 int input_slot_index = iterator.Next(); 7177 break;
7329 if (FLAG_print_code_verbose) {
7330 PrintF(out, "{input=%d}", input_slot_index);
7331 }
7332 break;
7333 }
7334
7335 case Translation::LITERAL: {
7336 unsigned literal_index = iterator.Next();
7337 if (FLAG_print_code_verbose) {
7338 PrintF(out, "{literal_id=%u}", literal_index);
7339 }
7340 break;
7341 }
7342
7343 case Translation::ARGUMENTS_OBJECT:
7344 break;
7345 }
7346 if (FLAG_print_code_verbose) PrintF(out, "\n");
7347 } 7178 }
7179 PrintF(out, "\n");
7348 } 7180 }
7349 if (!FLAG_print_code_verbose) PrintF(out, " %12d\n", command_count);
7350 } 7181 }
7351 } 7182 }
7352 7183
7353 7184
7354 void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) { 7185 void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) {
7355 PrintF(out, "Deoptimization Output Data (deopt points = %d)\n", 7186 PrintF(out, "Deoptimization Output Data (deopt points = %d)\n",
7356 this->DeoptPoints()); 7187 this->DeoptPoints());
7357 if (this->DeoptPoints() == 0) return; 7188 if (this->DeoptPoints() == 0) return;
7358 7189
7359 PrintF("%6s %8s %s\n", "ast id", "pc", "state"); 7190 PrintF("%6s %8s %s\n", "ast id", "pc", "state");
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
7616 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); 7447 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
7617 // Fill out the new array with this content and array holes. 7448 // Fill out the new array with this content and array holes.
7618 for (uint32_t i = 0; i < old_length; i++) { 7449 for (uint32_t i = 0; i < old_length; i++) {
7619 if (!old_elements->is_the_hole(i)) { 7450 if (!old_elements->is_the_hole(i)) {
7620 Object* obj; 7451 Object* obj;
7621 // Objects must be allocated in the old object space, since the 7452 // Objects must be allocated in the old object space, since the
7622 // overall number of HeapNumbers needed for the conversion might 7453 // overall number of HeapNumbers needed for the conversion might
7623 // exceed the capacity of new space, and we would fail repeatedly 7454 // exceed the capacity of new space, and we would fail repeatedly
7624 // trying to convert the FixedDoubleArray. 7455 // trying to convert the FixedDoubleArray.
7625 MaybeObject* maybe_value_object = 7456 MaybeObject* maybe_value_object =
7626 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); 7457 GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i),
7458 TENURED);
7627 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; 7459 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object;
7628 // Force write barrier. It's not worth trying to exploit 7460 // Force write barrier. It's not worth trying to exploit
7629 // elems->GetWriteBarrierMode(), since it requires an 7461 // elems->GetWriteBarrierMode(), since it requires an
7630 // AssertNoAllocation stack object that would have to be positioned 7462 // AssertNoAllocation stack object that would have to be positioned
7631 // after the HeapNumber allocation anyway. 7463 // after the HeapNumber allocation anyway.
7632 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); 7464 new_elements->set(i, obj, UPDATE_WRITE_BARRIER);
7633 } 7465 }
7634 } 7466 }
7635 set_map(new_map); 7467 set_map(new_map);
7636 set_elements(new_elements); 7468 set_elements(new_elements);
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after
8959 { MaybeObject* maybe_len = 8791 { MaybeObject* maybe_len =
8960 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); 8792 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1);
8961 if (!maybe_len->ToObject(&len)) return maybe_len; 8793 if (!maybe_len->ToObject(&len)) return maybe_len;
8962 } 8794 }
8963 set_length(len); 8795 set_length(len);
8964 } 8796 }
8965 return value; 8797 return value;
8966 } 8798 }
8967 8799
8968 8800
8969 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver,
8970 uint32_t index) {
8971 // Get element works for both JSObject and JSArray since
8972 // JSArray::length cannot change.
8973 switch (GetElementsKind()) {
8974 case FAST_ELEMENTS: {
8975 FixedArray* elms = FixedArray::cast(elements());
8976 if (index < static_cast<uint32_t>(elms->length())) {
8977 Object* value = elms->get(index);
8978 if (!value->IsTheHole()) return value;
8979 }
8980 break;
8981 }
8982 case FAST_DOUBLE_ELEMENTS: {
8983 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
8984 if (index < static_cast<uint32_t>(elms->length())) {
8985 if (!elms->is_the_hole(index)) {
8986 return GetHeap()->NumberFromDouble(elms->get(index));
8987 }
8988 }
8989 break;
8990 }
8991 case EXTERNAL_PIXEL_ELEMENTS:
8992 case EXTERNAL_BYTE_ELEMENTS:
8993 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
8994 case EXTERNAL_SHORT_ELEMENTS:
8995 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
8996 case EXTERNAL_INT_ELEMENTS:
8997 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
8998 case EXTERNAL_FLOAT_ELEMENTS:
8999 case EXTERNAL_DOUBLE_ELEMENTS: {
9000 MaybeObject* maybe_value = GetExternalElement(index);
9001 Object* value;
9002 if (!maybe_value->ToObject(&value)) return maybe_value;
9003 if (!value->IsUndefined()) return value;
9004 break;
9005 }
9006 case DICTIONARY_ELEMENTS: {
9007 NumberDictionary* dictionary = element_dictionary();
9008 int entry = dictionary->FindEntry(index);
9009 if (entry != NumberDictionary::kNotFound) {
9010 Object* element = dictionary->ValueAt(entry);
9011 PropertyDetails details = dictionary->DetailsAt(entry);
9012 if (details.type() == CALLBACKS) {
9013 return GetElementWithCallback(receiver,
9014 element,
9015 index,
9016 this);
9017 }
9018 return element;
9019 }
9020 break;
9021 }
9022 case NON_STRICT_ARGUMENTS_ELEMENTS:
9023 UNIMPLEMENTED();
9024 break;
9025 }
9026
9027 // Continue searching via the prototype chain.
9028 Object* pt = GetPrototype();
9029 if (pt->IsNull()) return GetHeap()->undefined_value();
9030 return pt->GetElementWithReceiver(receiver, index);
9031 }
9032
9033
9034 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, 8801 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver,
9035 uint32_t index) { 8802 uint32_t index) {
9036 Isolate* isolate = GetIsolate(); 8803 Isolate* isolate = GetIsolate();
9037 // Make sure that the top context does not change when doing 8804 // Make sure that the top context does not change when doing
9038 // callbacks or interceptor calls. 8805 // callbacks or interceptor calls.
9039 AssertNoContextChange ncc; 8806 AssertNoContextChange ncc;
9040 HandleScope scope(isolate); 8807 HandleScope scope(isolate);
9041 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate); 8808 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate);
9042 Handle<Object> this_handle(receiver, isolate); 8809 Handle<Object> this_handle(receiver, isolate);
9043 Handle<JSObject> holder_handle(this, isolate); 8810 Handle<JSObject> holder_handle(this, isolate);
9044 if (!interceptor->getter()->IsUndefined()) { 8811 if (!interceptor->getter()->IsUndefined()) {
9045 v8::IndexedPropertyGetter getter = 8812 v8::IndexedPropertyGetter getter =
9046 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); 8813 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
9047 LOG(isolate, 8814 LOG(isolate,
9048 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); 8815 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index));
9049 CustomArguments args(isolate, interceptor->data(), receiver, this); 8816 CustomArguments args(isolate, interceptor->data(), receiver, this);
9050 v8::AccessorInfo info(args.end()); 8817 v8::AccessorInfo info(args.end());
9051 v8::Handle<v8::Value> result; 8818 v8::Handle<v8::Value> result;
9052 { 8819 {
9053 // Leaving JavaScript. 8820 // Leaving JavaScript.
9054 VMState state(isolate, EXTERNAL); 8821 VMState state(isolate, EXTERNAL);
9055 result = getter(index, info); 8822 result = getter(index, info);
9056 } 8823 }
9057 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 8824 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
9058 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); 8825 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
9059 } 8826 }
9060 8827
9061 MaybeObject* raw_result = 8828 Heap* heap = holder_handle->GetHeap();
9062 holder_handle->GetElementPostInterceptor(*this_handle, index); 8829 ElementsAccessor* handler = holder_handle->GetElementsAccessor();
8830 MaybeObject* raw_result = handler->GetWithReceiver(*holder_handle,
8831 *this_handle,
8832 index);
8833 if (raw_result != heap->the_hole_value()) return raw_result;
8834
9063 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 8835 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
9064 return raw_result; 8836
8837 Object* pt = holder_handle->GetPrototype();
8838 if (pt == heap->null_value()) return heap->undefined_value();
8839 return pt->GetElementWithReceiver(*this_handle, index);
9065 } 8840 }
9066 8841
9067 8842
9068 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver,
9069 uint32_t index) {
9070 // Check access rights if needed.
9071 if (IsAccessCheckNeeded()) {
9072 Heap* heap = GetHeap();
9073 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) {
9074 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET);
9075 return heap->undefined_value();
9076 }
9077 }
9078
9079 if (HasIndexedInterceptor()) {
9080 return GetElementWithInterceptor(receiver, index);
9081 }
9082
9083 // Get element works for both JSObject and JSArray since
9084 // JSArray::length cannot change.
9085 switch (GetElementsKind()) {
9086 case FAST_ELEMENTS: {
9087 FixedArray* elms = FixedArray::cast(elements());
9088 if (index < static_cast<uint32_t>(elms->length())) {
9089 Object* value = elms->get(index);
9090 if (!value->IsTheHole()) return value;
9091 }
9092 break;
9093 }
9094 case FAST_DOUBLE_ELEMENTS: {
9095 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
9096 if (index < static_cast<uint32_t>(elms->length())) {
9097 if (!elms->is_the_hole(index)) {
9098 double double_value = elms->get(index);
9099 return GetHeap()->NumberFromDouble(double_value);
9100 }
9101 }
9102 break;
9103 }
9104 case EXTERNAL_PIXEL_ELEMENTS:
9105 case EXTERNAL_BYTE_ELEMENTS:
9106 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
9107 case EXTERNAL_SHORT_ELEMENTS:
9108 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9109 case EXTERNAL_INT_ELEMENTS:
9110 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9111 case EXTERNAL_FLOAT_ELEMENTS:
9112 case EXTERNAL_DOUBLE_ELEMENTS: {
9113 MaybeObject* maybe_value = GetExternalElement(index);
9114 Object* value;
9115 if (!maybe_value->ToObject(&value)) return maybe_value;
9116 if (!value->IsUndefined()) return value;
9117 break;
9118 }
9119 case DICTIONARY_ELEMENTS: {
9120 NumberDictionary* dictionary = element_dictionary();
9121 int entry = dictionary->FindEntry(index);
9122 if (entry != NumberDictionary::kNotFound) {
9123 Object* element = dictionary->ValueAt(entry);
9124 PropertyDetails details = dictionary->DetailsAt(entry);
9125 if (details.type() == CALLBACKS) {
9126 return GetElementWithCallback(receiver,
9127 element,
9128 index,
9129 this);
9130 }
9131 return element;
9132 }
9133 break;
9134 }
9135 case NON_STRICT_ARGUMENTS_ELEMENTS: {
9136 FixedArray* parameter_map = FixedArray::cast(elements());
9137 uint32_t length = parameter_map->length();
9138 Object* probe =
9139 (index < length - 2) ? parameter_map->get(index + 2) : NULL;
9140 if (probe != NULL && !probe->IsTheHole()) {
9141 Context* context = Context::cast(parameter_map->get(0));
9142 int context_index = Smi::cast(probe)->value();
9143 ASSERT(!context->get(context_index)->IsTheHole());
9144 return context->get(context_index);
9145 } else {
9146 // Object is not mapped, defer to the arguments.
9147 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
9148 if (arguments->IsDictionary()) {
9149 NumberDictionary* dictionary = NumberDictionary::cast(arguments);
9150 int entry = dictionary->FindEntry(index);
9151 if (entry != NumberDictionary::kNotFound) {
9152 Object* element = dictionary->ValueAt(entry);
9153 PropertyDetails details = dictionary->DetailsAt(entry);
9154 if (details.type() == CALLBACKS) {
9155 return GetElementWithCallback(receiver,
9156 element,
9157 index,
9158 this);
9159 }
9160 return element;
9161 }
9162 } else if (index < static_cast<uint32_t>(arguments->length())) {
9163 Object* value = arguments->get(index);
9164 if (!value->IsTheHole()) return value;
9165 }
9166 }
9167 break;
9168 }
9169 }
9170
9171 Object* pt = GetPrototype();
9172 Heap* heap = GetHeap();
9173 if (pt == heap->null_value()) return heap->undefined_value();
9174 return pt->GetElementWithReceiver(receiver, index);
9175 }
9176
9177
9178 MaybeObject* JSObject::GetExternalElement(uint32_t index) {
9179 // Get element works for both JSObject and JSArray since
9180 // JSArray::length cannot change.
9181 switch (GetElementsKind()) {
9182 case EXTERNAL_PIXEL_ELEMENTS: {
9183 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
9184 if (index < static_cast<uint32_t>(pixels->length())) {
9185 uint8_t value = pixels->get(index);
9186 return Smi::FromInt(value);
9187 }
9188 break;
9189 }
9190 case EXTERNAL_BYTE_ELEMENTS: {
9191 ExternalByteArray* array = ExternalByteArray::cast(elements());
9192 if (index < static_cast<uint32_t>(array->length())) {
9193 int8_t value = array->get(index);
9194 return Smi::FromInt(value);
9195 }
9196 break;
9197 }
9198 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
9199 ExternalUnsignedByteArray* array =
9200 ExternalUnsignedByteArray::cast(elements());
9201 if (index < static_cast<uint32_t>(array->length())) {
9202 uint8_t value = array->get(index);
9203 return Smi::FromInt(value);
9204 }
9205 break;
9206 }
9207 case EXTERNAL_SHORT_ELEMENTS: {
9208 ExternalShortArray* array = ExternalShortArray::cast(elements());
9209 if (index < static_cast<uint32_t>(array->length())) {
9210 int16_t value = array->get(index);
9211 return Smi::FromInt(value);
9212 }
9213 break;
9214 }
9215 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
9216 ExternalUnsignedShortArray* array =
9217 ExternalUnsignedShortArray::cast(elements());
9218 if (index < static_cast<uint32_t>(array->length())) {
9219 uint16_t value = array->get(index);
9220 return Smi::FromInt(value);
9221 }
9222 break;
9223 }
9224 case EXTERNAL_INT_ELEMENTS: {
9225 ExternalIntArray* array = ExternalIntArray::cast(elements());
9226 if (index < static_cast<uint32_t>(array->length())) {
9227 int32_t value = array->get(index);
9228 return GetHeap()->NumberFromInt32(value);
9229 }
9230 break;
9231 }
9232 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
9233 ExternalUnsignedIntArray* array =
9234 ExternalUnsignedIntArray::cast(elements());
9235 if (index < static_cast<uint32_t>(array->length())) {
9236 uint32_t value = array->get(index);
9237 return GetHeap()->NumberFromUint32(value);
9238 }
9239 break;
9240 }
9241 case EXTERNAL_FLOAT_ELEMENTS: {
9242 ExternalFloatArray* array = ExternalFloatArray::cast(elements());
9243 if (index < static_cast<uint32_t>(array->length())) {
9244 float value = array->get(index);
9245 return GetHeap()->AllocateHeapNumber(value);
9246 }
9247 break;
9248 }
9249 case EXTERNAL_DOUBLE_ELEMENTS: {
9250 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements());
9251 if (index < static_cast<uint32_t>(array->length())) {
9252 double value = array->get(index);
9253 return GetHeap()->AllocateHeapNumber(value);
9254 }
9255 break;
9256 }
9257 case FAST_DOUBLE_ELEMENTS:
9258 case FAST_ELEMENTS:
9259 case DICTIONARY_ELEMENTS:
9260 UNREACHABLE();
9261 break;
9262 case NON_STRICT_ARGUMENTS_ELEMENTS:
9263 UNIMPLEMENTED();
9264 break;
9265 }
9266 return GetHeap()->undefined_value();
9267 }
9268
9269
9270 bool JSObject::HasDenseElements() { 8843 bool JSObject::HasDenseElements() {
9271 int capacity = 0; 8844 int capacity = 0;
9272 int used = 0; 8845 int used = 0;
9273 GetElementsCapacityAndUsage(&capacity, &used); 8846 GetElementsCapacityAndUsage(&capacity, &used);
9274 return (capacity == 0) || (used > (capacity / 2)); 8847 return (capacity == 0) || (used > (capacity / 2));
9275 } 8848 }
9276 8849
9277 8850
9278 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { 8851 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
9279 *capacity = 0; 8852 *capacity = 0;
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
9770 // mirrors. 9343 // mirrors.
9771 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { 9344 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) {
9772 ASSERT(storage->length() >= (NumberOfLocalProperties(NONE) - index)); 9345 ASSERT(storage->length() >= (NumberOfLocalProperties(NONE) - index));
9773 if (HasFastProperties()) { 9346 if (HasFastProperties()) {
9774 DescriptorArray* descs = map()->instance_descriptors(); 9347 DescriptorArray* descs = map()->instance_descriptors();
9775 for (int i = 0; i < descs->number_of_descriptors(); i++) { 9348 for (int i = 0; i < descs->number_of_descriptors(); i++) {
9776 if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i)); 9349 if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i));
9777 } 9350 }
9778 ASSERT(storage->length() >= index); 9351 ASSERT(storage->length() >= index);
9779 } else { 9352 } else {
9780 property_dictionary()->CopyKeysTo(storage, StringDictionary::UNSORTED); 9353 property_dictionary()->CopyKeysTo(storage,
9354 index,
9355 StringDictionary::UNSORTED);
9781 } 9356 }
9782 } 9357 }
9783 9358
9784 9359
9785 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { 9360 int JSObject::NumberOfLocalElements(PropertyAttributes filter) {
9786 return GetLocalElementKeys(NULL, filter); 9361 return GetLocalElementKeys(NULL, filter);
9787 } 9362 }
9788 9363
9789 9364
9790 int JSObject::NumberOfEnumElements() { 9365 int JSObject::NumberOfEnumElements() {
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
10519 int, JSObject::DeleteMode); 10094 int, JSObject::DeleteMode);
10520 10095
10521 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( 10096 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink(
10522 String*); 10097 String*);
10523 10098
10524 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink( 10099 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink(
10525 uint32_t); 10100 uint32_t);
10526 10101
10527 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( 10102 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo(
10528 FixedArray*, 10103 FixedArray*,
10104 int,
10529 Dictionary<StringDictionaryShape, String*>::SortMode); 10105 Dictionary<StringDictionaryShape, String*>::SortMode);
10530 10106
10531 template int 10107 template int
10532 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( 10108 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
10533 PropertyAttributes); 10109 PropertyAttributes);
10534 10110
10535 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( 10111 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add(
10536 String*, Object*, PropertyDetails); 10112 String*, Object*, PropertyDetails);
10537 10113
10538 template MaybeObject* 10114 template MaybeObject*
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
10693 Object* new_array; 10269 Object* new_array;
10694 { MaybeObject* maybe_new_array = 10270 { MaybeObject* maybe_new_array =
10695 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); 10271 heap->AllocateFixedArray(dict->NumberOfElements(), tenure);
10696 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 10272 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array;
10697 } 10273 }
10698 FixedArray* fast_elements = FixedArray::cast(new_array); 10274 FixedArray* fast_elements = FixedArray::cast(new_array);
10699 dict->CopyValuesTo(fast_elements); 10275 dict->CopyValuesTo(fast_elements);
10700 10276
10701 set_map(new_map); 10277 set_map(new_map);
10702 set_elements(fast_elements); 10278 set_elements(fast_elements);
10703 } else { 10279 } else if (!HasFastDoubleElements()) {
10704 Object* obj; 10280 Object* obj;
10705 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 10281 { MaybeObject* maybe_obj = EnsureWritableFastElements();
10706 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10282 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10707 } 10283 }
10708 } 10284 }
10709 ASSERT(HasFastElements()); 10285 ASSERT(HasFastElements() || HasFastDoubleElements());
10710 10286
10711 // Collect holes at the end, undefined before that and the rest at the 10287 // Collect holes at the end, undefined before that and the rest at the
10712 // start, and return the number of non-hole, non-undefined values. 10288 // start, and return the number of non-hole, non-undefined values.
10713 10289
10714 FixedArray* elements = FixedArray::cast(this->elements()); 10290 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements());
10715 uint32_t elements_length = static_cast<uint32_t>(elements->length()); 10291 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
10716 if (limit > elements_length) { 10292 if (limit > elements_length) {
10717 limit = elements_length ; 10293 limit = elements_length ;
10718 } 10294 }
10719 if (limit == 0) { 10295 if (limit == 0) {
10720 return Smi::FromInt(0); 10296 return Smi::FromInt(0);
10721 } 10297 }
10722 10298
10723 HeapNumber* result_double = NULL; 10299 HeapNumber* result_double = NULL;
10724 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 10300 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
10725 // Pessimistically allocate space for return value before 10301 // Pessimistically allocate space for return value before
10726 // we start mutating the array. 10302 // we start mutating the array.
10727 Object* new_double; 10303 Object* new_double;
10728 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); 10304 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
10729 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; 10305 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
10730 } 10306 }
10731 result_double = HeapNumber::cast(new_double); 10307 result_double = HeapNumber::cast(new_double);
10732 } 10308 }
10733 10309
10734 AssertNoAllocation no_alloc; 10310 uint32_t result = 0;
10311 if (elements_base->map() == heap->fixed_double_array_map()) {
10312 FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base);
10313 // Split elements into defined and the_hole, in that order.
10314 unsigned int holes = limit;
10315 // Assume most arrays contain no holes and undefined values, so minimize the
10316 // number of stores of non-undefined, non-the-hole values.
10317 for (unsigned int i = 0; i < holes; i++) {
10318 if (elements->is_the_hole(i)) {
10319 holes--;
10320 } else {
10321 continue;
10322 }
10323 // Position i needs to be filled.
10324 while (holes > i) {
10325 if (elements->is_the_hole(holes)) {
10326 holes--;
10327 } else {
10328 elements->set(i, elements->get_scalar(holes));
10329 break;
10330 }
10331 }
10332 }
10333 result = holes;
10334 while (holes < limit) {
10335 elements->set_the_hole(holes);
10336 holes++;
10337 }
10338 } else {
10339 FixedArray* elements = FixedArray::cast(elements_base);
10340 AssertNoAllocation no_alloc;
10735 10341
10736 // Split elements into defined, undefined and the_hole, in that order. 10342 // Split elements into defined, undefined and the_hole, in that order. Only
10737 // Only count locations for undefined and the hole, and fill them afterwards. 10343 // count locations for undefined and the hole, and fill them afterwards.
10738 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); 10344 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
10739 unsigned int undefs = limit; 10345 unsigned int undefs = limit;
10740 unsigned int holes = limit; 10346 unsigned int holes = limit;
10741 // Assume most arrays contain no holes and undefined values, so minimize the 10347 // Assume most arrays contain no holes and undefined values, so minimize the
10742 // number of stores of non-undefined, non-the-hole values. 10348 // number of stores of non-undefined, non-the-hole values.
10743 for (unsigned int i = 0; i < undefs; i++) { 10349 for (unsigned int i = 0; i < undefs; i++) {
10744 Object* current = elements->get(i); 10350 Object* current = elements->get(i);
10745 if (current->IsTheHole()) {
10746 holes--;
10747 undefs--;
10748 } else if (current->IsUndefined()) {
10749 undefs--;
10750 } else {
10751 continue;
10752 }
10753 // Position i needs to be filled.
10754 while (undefs > i) {
10755 current = elements->get(undefs);
10756 if (current->IsTheHole()) { 10351 if (current->IsTheHole()) {
10757 holes--; 10352 holes--;
10758 undefs--; 10353 undefs--;
10759 } else if (current->IsUndefined()) { 10354 } else if (current->IsUndefined()) {
10760 undefs--; 10355 undefs--;
10761 } else { 10356 } else {
10762 elements->set(i, current, write_barrier); 10357 continue;
10763 break; 10358 }
10359 // Position i needs to be filled.
10360 while (undefs > i) {
10361 current = elements->get(undefs);
10362 if (current->IsTheHole()) {
10363 holes--;
10364 undefs--;
10365 } else if (current->IsUndefined()) {
10366 undefs--;
10367 } else {
10368 elements->set(i, current, write_barrier);
10369 break;
10370 }
10764 } 10371 }
10765 } 10372 }
10766 } 10373 result = undefs;
10767 uint32_t result = undefs; 10374 while (undefs < holes) {
10768 while (undefs < holes) { 10375 elements->set_undefined(undefs);
10769 elements->set_undefined(undefs); 10376 undefs++;
10770 undefs++; 10377 }
10771 } 10378 while (holes < limit) {
10772 while (holes < limit) { 10379 elements->set_the_hole(holes);
10773 elements->set_the_hole(holes); 10380 holes++;
10774 holes++; 10381 }
10775 } 10382 }
10776 10383
10777 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 10384 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
10778 return Smi::FromInt(static_cast<int>(result)); 10385 return Smi::FromInt(static_cast<int>(result));
10779 } 10386 }
10780 ASSERT_NE(NULL, result_double); 10387 ASSERT_NE(NULL, result_double);
10781 result_double->set_value(static_cast<double>(result)); 10388 result_double->set_value(static_cast<double>(result));
10782 return result_double; 10389 return result_double;
10783 } 10390 }
10784 10391
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after
11617 } 11224 }
11618 } 11225 }
11619 storage->SortPairs(sort_array, sort_array->length()); 11226 storage->SortPairs(sort_array, sort_array->length());
11620 ASSERT(storage->length() >= index); 11227 ASSERT(storage->length() >= index);
11621 } 11228 }
11622 11229
11623 11230
11624 template<typename Shape, typename Key> 11231 template<typename Shape, typename Key>
11625 void Dictionary<Shape, Key>::CopyKeysTo( 11232 void Dictionary<Shape, Key>::CopyKeysTo(
11626 FixedArray* storage, 11233 FixedArray* storage,
11234 int index,
11627 typename Dictionary<Shape, Key>::SortMode sort_mode) { 11235 typename Dictionary<Shape, Key>::SortMode sort_mode) {
11628 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( 11236 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(
11629 static_cast<PropertyAttributes>(NONE))); 11237 static_cast<PropertyAttributes>(NONE)));
11630 int capacity = HashTable<Shape, Key>::Capacity(); 11238 int capacity = HashTable<Shape, Key>::Capacity();
11631 int index = 0;
11632 for (int i = 0; i < capacity; i++) { 11239 for (int i = 0; i < capacity; i++) {
11633 Object* k = HashTable<Shape, Key>::KeyAt(i); 11240 Object* k = HashTable<Shape, Key>::KeyAt(i);
11634 if (HashTable<Shape, Key>::IsKey(k)) { 11241 if (HashTable<Shape, Key>::IsKey(k)) {
11635 PropertyDetails details = DetailsAt(i); 11242 PropertyDetails details = DetailsAt(i);
11636 if (details.IsDeleted()) continue; 11243 if (details.IsDeleted()) continue;
11637 storage->set(index++, k); 11244 storage->set(index++, k);
11638 } 11245 }
11639 } 11246 }
11640 if (sort_mode == Dictionary<Shape, Key>::SORTED) { 11247 if (sort_mode == Dictionary<Shape, Key>::SORTED) {
11641 storage->SortPairs(storage, index); 11248 storage->SortPairs(storage, index);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
11842 } 11449 }
11843 11450
11844 11451
11845 void ObjectHashTable::AddEntry(int entry, JSObject* key, Object* value) { 11452 void ObjectHashTable::AddEntry(int entry, JSObject* key, Object* value) {
11846 set(EntryToIndex(entry), key); 11453 set(EntryToIndex(entry), key);
11847 set(EntryToIndex(entry) + 1, value); 11454 set(EntryToIndex(entry) + 1, value);
11848 ElementAdded(); 11455 ElementAdded();
11849 } 11456 }
11850 11457
11851 11458
11852 void ObjectHashTable::RemoveEntry(int entry) { 11459 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) {
11853 Object* null_value = GetHeap()->null_value(); 11460 set_null(heap, EntryToIndex(entry));
11854 set(EntryToIndex(entry), null_value); 11461 set_null(heap, EntryToIndex(entry) + 1);
11855 set(EntryToIndex(entry) + 1, null_value);
11856 ElementRemoved(); 11462 ElementRemoved();
11857 } 11463 }
11858 11464
11859 11465
11860 #ifdef ENABLE_DEBUGGER_SUPPORT 11466 #ifdef ENABLE_DEBUGGER_SUPPORT
11861 // Check if there is a break point at this code position. 11467 // Check if there is a break point at this code position.
11862 bool DebugInfo::HasBreakPoint(int code_position) { 11468 bool DebugInfo::HasBreakPoint(int code_position) {
11863 // Get the break point info object for this code position. 11469 // Get the break point info object for this code position.
11864 Object* break_point_info = GetBreakPointInfo(code_position); 11470 Object* break_point_info = GetBreakPointInfo(code_position);
11865 11471
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
12076 new_array->set(old_array->length(), *break_point_object); 11682 new_array->set(old_array->length(), *break_point_object);
12077 break_point_info->set_break_point_objects(*new_array); 11683 break_point_info->set_break_point_objects(*new_array);
12078 } 11684 }
12079 11685
12080 11686
12081 bool BreakPointInfo::HasBreakPointObject( 11687 bool BreakPointInfo::HasBreakPointObject(
12082 Handle<BreakPointInfo> break_point_info, 11688 Handle<BreakPointInfo> break_point_info,
12083 Handle<Object> break_point_object) { 11689 Handle<Object> break_point_object) {
12084 // No break point. 11690 // No break point.
12085 if (break_point_info->break_point_objects()->IsUndefined()) return false; 11691 if (break_point_info->break_point_objects()->IsUndefined()) return false;
12086 // Single beak point. 11692 // Single break point.
12087 if (!break_point_info->break_point_objects()->IsFixedArray()) { 11693 if (!break_point_info->break_point_objects()->IsFixedArray()) {
12088 return break_point_info->break_point_objects() == *break_point_object; 11694 return break_point_info->break_point_objects() == *break_point_object;
12089 } 11695 }
12090 // Multiple break points. 11696 // Multiple break points.
12091 FixedArray* array = FixedArray::cast(break_point_info->break_point_objects()); 11697 FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
12092 for (int i = 0; i < array->length(); i++) { 11698 for (int i = 0; i < array->length(); i++) {
12093 if (array->get(i) == *break_point_object) { 11699 if (array->get(i) == *break_point_object) {
12094 return true; 11700 return true;
12095 } 11701 }
12096 } 11702 }
12097 return false; 11703 return false;
12098 } 11704 }
12099 11705
12100 11706
12101 // Get the number of break points. 11707 // Get the number of break points.
12102 int BreakPointInfo::GetBreakPointCount() { 11708 int BreakPointInfo::GetBreakPointCount() {
12103 // No break point. 11709 // No break point.
12104 if (break_point_objects()->IsUndefined()) return 0; 11710 if (break_point_objects()->IsUndefined()) return 0;
12105 // Single beak point. 11711 // Single break point.
12106 if (!break_point_objects()->IsFixedArray()) return 1; 11712 if (!break_point_objects()->IsFixedArray()) return 1;
12107 // Multiple break points. 11713 // Multiple break points.
12108 return FixedArray::cast(break_point_objects())->length(); 11714 return FixedArray::cast(break_point_objects())->length();
12109 } 11715 }
12110 #endif 11716 #endif
12111 11717
12112 11718
12113 } } // namespace v8::internal 11719 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698