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

Side by Side Diff: src/builtins.cc

Issue 1200053002: Also check for access checks and indexed interceptors before allowing fast moving of elements (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 177
178 178
179 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, 179 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index,
180 FixedDoubleArray* src, int src_index, int len) { 180 FixedDoubleArray* src, int src_index, int len) {
181 if (len == 0) return; 181 if (len == 0) return;
182 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, 182 MemMove(dst->data_start() + dst_index, src->data_start() + src_index,
183 len * kDoubleSize); 183 len * kDoubleSize);
184 } 184 }
185 185
186 186
187 static bool ArrayPrototypeHasNoElements(Heap* heap, PrototypeIterator* iter) { 187 static bool ArrayPrototypeHasNoElements(PrototypeIterator* iter) {
188 DisallowHeapAllocation no_gc; 188 DisallowHeapAllocation no_gc;
189 for (; !iter->IsAtEnd(); iter->Advance()) { 189 for (; !iter->IsAtEnd(); iter->Advance()) {
190 if (iter->GetCurrent()->IsJSProxy()) return false; 190 if (iter->GetCurrent()->IsJSProxy()) return false;
191 if (JSObject::cast(iter->GetCurrent())->elements() != 191 JSObject* current = JSObject::cast(iter->GetCurrent());
192 heap->empty_fixed_array()) { 192 if (current->IsAccessCheckNeeded()) return false;
193 return false; 193 if (current->HasIndexedInterceptor()) return false;
194 } 194 if (current->elements()->length() != 0) return false;
195 } 195 }
196 return true; 196 return true;
197 } 197 }
198 198
199 199
200 static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, 200 static inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate,
201 JSArray* receiver) { 201 JSArray* receiver) {
202 DisallowHeapAllocation no_gc; 202 DisallowHeapAllocation no_gc;
203 Isolate* isolate = heap->isolate();
204 if (!isolate->IsFastArrayConstructorPrototypeChainIntact()) {
205 return false;
206 }
207
208 // If the array prototype chain is intact (and free of elements), and if the 203 // If the array prototype chain is intact (and free of elements), and if the
209 // receiver's prototype is the array prototype, then we are done. 204 // receiver's prototype is the array prototype, then we are done.
210 Object* prototype = receiver->map()->prototype(); 205 Object* prototype = receiver->map()->prototype();
211 if (prototype->IsJSArray() && 206 if (prototype->IsJSArray() &&
212 isolate->is_initial_array_prototype(JSArray::cast(prototype))) { 207 isolate->is_initial_array_prototype(JSArray::cast(prototype)) &&
208 isolate->IsFastArrayConstructorPrototypeChainIntact()) {
213 return true; 209 return true;
214 } 210 }
215 211
216 // Slow case. 212 // Slow case.
217 PrototypeIterator iter(isolate, receiver); 213 PrototypeIterator iter(isolate, receiver);
218 return ArrayPrototypeHasNoElements(heap, &iter); 214 return ArrayPrototypeHasNoElements(&iter);
219 } 215 }
220 216
221 217
222 // Returns empty handle if not applicable. 218 // Returns empty handle if not applicable.
223 MUST_USE_RESULT 219 MUST_USE_RESULT
224 static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements( 220 static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
225 Isolate* isolate, 221 Isolate* isolate,
226 Handle<Object> receiver, 222 Handle<Object> receiver,
227 Arguments* args, 223 Arguments* args,
228 int first_added_arg) { 224 int first_added_arg) {
229 if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>(); 225 if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>();
230 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 226 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
231 // If there may be elements accessors in the prototype chain, the fast path 227 // If there may be elements accessors in the prototype chain, the fast path
232 // cannot be used if there arguments to add to the array. 228 // cannot be used if there arguments to add to the array.
233 Heap* heap = isolate->heap(); 229 Heap* heap = isolate->heap();
234 if (args != NULL && !IsJSArrayFastElementMovingAllowed(heap, *array)) { 230 if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) {
235 return MaybeHandle<FixedArrayBase>(); 231 return MaybeHandle<FixedArrayBase>();
236 } 232 }
237 if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>(); 233 if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>();
238 if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>(); 234 if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>();
239 Handle<FixedArrayBase> elms(array->elements(), isolate); 235 Handle<FixedArrayBase> elms(array->elements(), isolate);
240 Map* map = elms->map(); 236 Map* map = elms->map();
241 if (map == heap->fixed_array_map()) { 237 if (map == heap->fixed_array_map()) {
242 if (args == NULL || array->HasFastObjectElements()) return elms; 238 if (args == NULL || array->HasFastObjectElements()) return elms;
243 } else if (map == heap->fixed_cow_array_map()) { 239 } else if (map == heap->fixed_cow_array_map()) {
244 elms = JSObject::EnsureWritableFastElements(array); 240 elms = JSObject::EnsureWritableFastElements(array);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 452
457 453
458 BUILTIN(ArrayShift) { 454 BUILTIN(ArrayShift) {
459 HandleScope scope(isolate); 455 HandleScope scope(isolate);
460 Heap* heap = isolate->heap(); 456 Heap* heap = isolate->heap();
461 Handle<Object> receiver = args.receiver(); 457 Handle<Object> receiver = args.receiver();
462 MaybeHandle<FixedArrayBase> maybe_elms_obj = 458 MaybeHandle<FixedArrayBase> maybe_elms_obj =
463 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); 459 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
464 Handle<FixedArrayBase> elms_obj; 460 Handle<FixedArrayBase> elms_obj;
465 if (!maybe_elms_obj.ToHandle(&elms_obj) || 461 if (!maybe_elms_obj.ToHandle(&elms_obj) ||
466 !IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(*receiver))) { 462 !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
467 return CallJsBuiltin(isolate, "$arrayShift", args); 463 return CallJsBuiltin(isolate, "$arrayShift", args);
468 } 464 }
469 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 465 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
470 DCHECK(!array->map()->is_observed()); 466 DCHECK(!array->map()->is_observed());
471 467
472 int len = Smi::cast(array->length())->value(); 468 int len = Smi::cast(array->length())->value();
473 if (len == 0) return heap->undefined_value(); 469 if (len == 0) return heap->undefined_value();
474 470
475 if (JSArray::HasReadOnlyLength(array)) { 471 if (JSArray::HasReadOnlyLength(array)) {
476 return CallJsBuiltin(isolate, "$arrayShift", args); 472 return CallJsBuiltin(isolate, "$arrayShift", args);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 555 }
560 556
561 // Set the length. 557 // Set the length.
562 array->set_length(Smi::FromInt(new_length)); 558 array->set_length(Smi::FromInt(new_length));
563 return Smi::FromInt(new_length); 559 return Smi::FromInt(new_length);
564 } 560 }
565 561
566 562
567 BUILTIN(ArraySlice) { 563 BUILTIN(ArraySlice) {
568 HandleScope scope(isolate); 564 HandleScope scope(isolate);
569 Heap* heap = isolate->heap();
570 Handle<Object> receiver = args.receiver(); 565 Handle<Object> receiver = args.receiver();
571 int len = -1; 566 int len = -1;
572 int relative_start = 0; 567 int relative_start = 0;
573 int relative_end = 0; 568 int relative_end = 0;
574 { 569 {
575 DisallowHeapAllocation no_gc; 570 DisallowHeapAllocation no_gc;
576 if (receiver->IsJSArray()) { 571 if (receiver->IsJSArray()) {
577 JSArray* array = JSArray::cast(*receiver); 572 JSArray* array = JSArray::cast(*receiver);
578 if (!IsJSArrayFastElementMovingAllowed(heap, array)) { 573 if (!IsJSArrayFastElementMovingAllowed(isolate, array)) {
579 AllowHeapAllocation allow_allocation; 574 AllowHeapAllocation allow_allocation;
580 return CallJsBuiltin(isolate, "$arraySlice", args); 575 return CallJsBuiltin(isolate, "$arraySlice", args);
581 } 576 }
582 577
583 if (!array->HasFastElements()) { 578 if (!array->HasFastElements()) {
584 AllowHeapAllocation allow_allocation; 579 AllowHeapAllocation allow_allocation;
585 return CallJsBuiltin(isolate, "$arraySlice", args); 580 return CallJsBuiltin(isolate, "$arraySlice", args);
586 } 581 }
587 582
588 len = Smi::cast(array->length())->value(); 583 len = Smi::cast(array->length())->value();
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 922
928 BUILTIN(ArrayConcat) { 923 BUILTIN(ArrayConcat) {
929 HandleScope scope(isolate); 924 HandleScope scope(isolate);
930 925
931 int n_arguments = args.length(); 926 int n_arguments = args.length();
932 int result_len = 0; 927 int result_len = 0;
933 ElementsKind elements_kind = GetInitialFastElementsKind(); 928 ElementsKind elements_kind = GetInitialFastElementsKind();
934 bool has_double = false; 929 bool has_double = false;
935 { 930 {
936 DisallowHeapAllocation no_gc; 931 DisallowHeapAllocation no_gc;
937 Heap* heap = isolate->heap();
938 Context* native_context = isolate->context()->native_context(); 932 Context* native_context = isolate->context()->native_context();
939 Object* array_proto = native_context->array_function()->prototype(); 933 Object* array_proto = native_context->array_function()->prototype();
940 PrototypeIterator iter(isolate, array_proto, 934 PrototypeIterator iter(isolate, array_proto,
941 PrototypeIterator::START_AT_RECEIVER); 935 PrototypeIterator::START_AT_RECEIVER);
942 if (!ArrayPrototypeHasNoElements(heap, &iter)) { 936 if (!ArrayPrototypeHasNoElements(&iter)) {
943 AllowHeapAllocation allow_allocation; 937 AllowHeapAllocation allow_allocation;
944 return CallJsBuiltin(isolate, "$arrayConcat", args); 938 return CallJsBuiltin(isolate, "$arrayConcat", args);
945 } 939 }
946 940
947 // Iterate through all the arguments performing checks 941 // Iterate through all the arguments performing checks
948 // and calculating total length. 942 // and calculating total length.
949 bool is_holey = false; 943 bool is_holey = false;
950 for (int i = 0; i < n_arguments; i++) { 944 for (int i = 0; i < n_arguments; i++) {
951 Object* arg = args[i]; 945 Object* arg = args[i];
952 PrototypeIterator iter(isolate, arg); 946 PrototypeIterator iter(isolate, arg);
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1645 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1652 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1646 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1653 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1647 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1654 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1648 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1655 #undef DEFINE_BUILTIN_ACCESSOR_C 1649 #undef DEFINE_BUILTIN_ACCESSOR_C
1656 #undef DEFINE_BUILTIN_ACCESSOR_A 1650 #undef DEFINE_BUILTIN_ACCESSOR_A
1657 1651
1658 1652
1659 } // namespace internal 1653 } // namespace internal
1660 } // namespace v8 1654 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698