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

Side by Side Diff: src/builtins.cc

Issue 1409123003: [runtime] Avoid @@isConcatSpreadable lookup for fast path Array.prototype.concat (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: simplifications Created 5 years, 1 month 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 | src/crankshaft/arm/lithium-codegen-arm.cc » ('j') | src/isolate.h » ('J')
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/builtins.h" 5 #include "src/builtins.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 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 visitor->visit(index, element); 1165 visitor->visit(index, element);
1166 } 1166 }
1167 break; 1167 break;
1168 } 1168 }
1169 } 1169 }
1170 visitor->increase_index_offset(length); 1170 visitor->increase_index_offset(length);
1171 return true; 1171 return true;
1172 } 1172 }
1173 1173
1174 1174
1175 bool HasConcatSpreadableModifier(Isolate* isolate, Handle<JSArray> obj) {
1176 if (!FLAG_harmony_concat_spreadable) return false;
1177 Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
1178 Maybe<bool> maybe =
1179 JSReceiver::HasProperty(Handle<JSReceiver>::cast(obj), key);
1180 if (!maybe.IsJust()) return false;
1181 return maybe.FromJust();
1182 }
1183
1184
1185 bool IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) { 1175 bool IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) {
1186 HandleScope handle_scope(isolate); 1176 HandleScope handle_scope(isolate);
1187 if (!obj->IsSpecObject()) return false; 1177 if (!obj->IsSpecObject()) return false;
1188 if (FLAG_harmony_concat_spreadable) { 1178 if (FLAG_harmony_concat_spreadable) {
1189 Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol()); 1179 Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
1190 Handle<Object> value; 1180 Handle<Object> value;
1191 MaybeHandle<Object> maybeValue = 1181 MaybeHandle<Object> maybeValue =
1192 i::Runtime::GetObjectProperty(isolate, obj, key); 1182 i::Runtime::GetObjectProperty(isolate, obj, key);
1193 if (maybeValue.ToHandle(&value) && !value->IsUndefined()) { 1183 if (maybeValue.ToHandle(&value) && !value->IsUndefined()) {
1194 return value->BooleanValue(); 1184 return value->BooleanValue();
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 } 1363 }
1374 1364
1375 if (visitor.exceeds_array_limit()) { 1365 if (visitor.exceeds_array_limit()) {
1376 THROW_NEW_ERROR_RETURN_FAILURE( 1366 THROW_NEW_ERROR_RETURN_FAILURE(
1377 isolate, NewRangeError(MessageTemplate::kInvalidArrayLength)); 1367 isolate, NewRangeError(MessageTemplate::kInvalidArrayLength));
1378 } 1368 }
1379 return *visitor.ToArray(); 1369 return *visitor.ToArray();
1380 } 1370 }
1381 1371
1382 1372
1373 bool FastArrayIsConcatSpreadable(Isolate* isolate, Handle<JSArray> obj) {
1374 if (!FLAG_harmony_concat_spreadable) return true;
1375 int nof = obj->map()->NumberOfOwnDescriptors();
1376 // If there is only the 'length' property we are fine.
1377 if (nof == 1) return true;
1378 // In the other case do a full property lookup of @@isConcatSpreadable.
1379 return IsConcatSpreadable(isolate, obj);
1380 }
1381
1382
1383 MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) { 1383 MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
1384 // TODO(cbruni): check for @@isConcatSpreadable set on the array/object
1385 // prototype
1384 if (!isolate->IsFastArrayConstructorPrototypeChainIntact()) { 1386 if (!isolate->IsFastArrayConstructorPrototypeChainIntact()) {
1385 return MaybeHandle<JSArray>(); 1387 return MaybeHandle<JSArray>();
1386 } 1388 }
1389 if (isolate->IsArrayIsConcatSpreadableSet()) return MaybeHandle<JSArray>();
1387 int n_arguments = args->length(); 1390 int n_arguments = args->length();
1388 int result_len = 0; 1391 int result_len = 0;
1389 { 1392 {
1390 DisallowHeapAllocation no_gc; 1393 DisallowHeapAllocation no_gc;
1391 Object* array_proto = isolate->array_function()->prototype(); 1394 Object* array_proto = isolate->array_function()->prototype();
1392 // Iterate through all the arguments performing checks 1395 // Iterate through all the arguments performing checks
1393 // and calculating total length. 1396 // and calculating total length.
1394 for (int i = 0; i < n_arguments; i++) { 1397 for (int i = 0; i < n_arguments; i++) {
1395 Object* arg = (*args)[i]; 1398 Object* arg = (*args)[i];
1396 if (!arg->IsJSArray()) return MaybeHandle<JSArray>(); 1399 if (!arg->IsJSArray()) return MaybeHandle<JSArray>();
1397 Handle<JSArray> array(JSArray::cast(arg), isolate); 1400 Handle<JSArray> array(JSArray::cast(arg), isolate);
1398 if (!array->HasFastElements()) return MaybeHandle<JSArray>(); 1401 if (!array->HasFastElements()) return MaybeHandle<JSArray>();
1399 PrototypeIterator iter(isolate, arg); 1402 PrototypeIterator iter(isolate, arg);
1400 if (iter.GetCurrent() != array_proto) return MaybeHandle<JSArray>(); 1403 if (iter.GetCurrent() != array_proto) return MaybeHandle<JSArray>();
1401 if (HasConcatSpreadableModifier(isolate, array)) { 1404 bool is_concat_spreadable = FastArrayIsConcatSpreadable(isolate, array);
1405 if (!is_concat_spreadable || isolate->has_pending_exception()) {
1402 return MaybeHandle<JSArray>(); 1406 return MaybeHandle<JSArray>();
1403 } 1407 }
1404 int len = Smi::cast(array->length())->value(); 1408 int len = Smi::cast(array->length())->value();
1405 1409
1406 // We shouldn't overflow when adding another len. 1410 // We shouldn't overflow when adding another len.
1407 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); 1411 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
1408 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); 1412 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
1409 USE(kHalfOfMaxInt); 1413 USE(kHalfOfMaxInt);
1410 result_len += len; 1414 result_len += len;
1411 DCHECK(result_len >= 0); 1415 DCHECK(result_len >= 0);
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 2269 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
2266 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 2270 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
2267 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 2271 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
2268 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 2272 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
2269 #undef DEFINE_BUILTIN_ACCESSOR_C 2273 #undef DEFINE_BUILTIN_ACCESSOR_C
2270 #undef DEFINE_BUILTIN_ACCESSOR_A 2274 #undef DEFINE_BUILTIN_ACCESSOR_A
2271 2275
2272 2276
2273 } // namespace internal 2277 } // namespace internal
2274 } // namespace v8 2278 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/crankshaft/arm/lithium-codegen-arm.cc » ('j') | src/isolate.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698