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

Side by Side Diff: src/x64/builtins-x64.cc

Issue 1335193002: [builtins] Simplify String constructor code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Jaro's comments. Created 5 years, 3 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 | « src/runtime/runtime-object.cc ('k') | src/x64/macro-assembler-x64.h » ('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 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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 1305
1306 1306
1307 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 1307 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1308 // ----------- S t a t e ------------- 1308 // ----------- S t a t e -------------
1309 // -- rax : number of arguments 1309 // -- rax : number of arguments
1310 // -- rdi : constructor function 1310 // -- rdi : constructor function
1311 // -- rsp[0] : return address 1311 // -- rsp[0] : return address
1312 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1312 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1313 // -- rsp[(argc + 1) * 8] : receiver 1313 // -- rsp[(argc + 1) * 8] : receiver
1314 // ----------------------------------- 1314 // -----------------------------------
1315 Counters* counters = masm->isolate()->counters();
1316 __ IncrementCounter(counters->string_ctor_calls(), 1);
1317 1315
1318 if (FLAG_debug_code) { 1316 // 1. Load the first argument into rbx and get rid of the rest (including the
1319 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, rcx); 1317 // receiver).
1320 __ cmpp(rdi, rcx); 1318 {
1321 __ Assert(equal, kUnexpectedStringFunction); 1319 StackArgumentsAccessor args(rsp, rax);
1320 Label no_arguments, done;
1321 __ testp(rax, rax);
1322 __ j(zero, &no_arguments, Label::kNear);
1323 __ movp(rbx, args.GetArgumentOperand(1));
1324 __ jmp(&done, Label::kNear);
1325 __ bind(&no_arguments);
1326 __ LoadRoot(rbx, Heap::kempty_stringRootIndex);
1327 __ bind(&done);
1328 __ PopReturnAddressTo(rcx);
1329 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1330 __ PushReturnAddressFrom(rcx);
1322 } 1331 }
1323 1332
1324 // Load the first argument into rax and get rid of the rest 1333 // 2. Make sure rbx is a string.
1325 // (including the receiver). 1334 {
1326 StackArgumentsAccessor args(rsp, rax); 1335 Label convert, done_convert;
1327 Label no_arguments; 1336 __ JumpIfSmi(rbx, &convert, Label::kNear);
1328 __ testp(rax, rax); 1337 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rdx);
1329 __ j(zero, &no_arguments); 1338 __ j(below, &done_convert);
1330 __ movp(rbx, args.GetArgumentOperand(1)); 1339 __ bind(&convert);
1331 __ PopReturnAddressTo(rcx); 1340 {
1332 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); 1341 FrameScope scope(masm, StackFrame::INTERNAL);
1333 __ PushReturnAddressFrom(rcx); 1342 ToStringStub stub(masm->isolate());
1334 __ movp(rax, rbx); 1343 __ Push(rdi);
1344 __ Move(rax, rbx);
1345 __ CallStub(&stub);
1346 __ Move(rbx, rax);
1347 __ Pop(rdi);
1348 }
1349 __ bind(&done_convert);
1350 }
1335 1351
1336 // Lookup the argument in the number to string cache. 1352 // 3. Allocate a JSValue wrapper for the string.
1337 Label not_cached, argument_is_string; 1353 {
1338 __ LookupNumberStringCache(rax, // Input. 1354 // ----------- S t a t e -------------
1339 rbx, // Result. 1355 // -- rbx : the first argument
1340 rcx, // Scratch 1. 1356 // -- rdi : constructor function
1341 rdx, // Scratch 2. 1357 // -----------------------------------
1342 &not_cached);
1343 __ IncrementCounter(counters->string_ctor_cached_number(), 1);
1344 __ bind(&argument_is_string);
1345 1358
1346 // ----------- S t a t e ------------- 1359 Label allocate, done_allocate;
1347 // -- rbx : argument converted to string 1360 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &allocate, TAG_OBJECT);
1348 // -- rdi : constructor function 1361 __ bind(&done_allocate);
1349 // -- rsp[0] : return address
1350 // -----------------------------------
1351 1362
1352 // Allocate a JSValue and put the tagged pointer into rax. 1363 // Initialize the JSValue in rax.
1353 Label gc_required; 1364 __ LoadGlobalFunctionInitialMap(rdi, rcx);
1354 __ Allocate(JSValue::kSize, 1365 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx);
1355 rax, // Result. 1366 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
1356 rcx, // New allocation top (we ignore it). 1367 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx);
1357 no_reg, 1368 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx);
1358 &gc_required, 1369 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx);
1359 TAG_OBJECT); 1370 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
1371 __ Ret();
1360 1372
1361 // Set the map. 1373 // Fallback to the runtime to allocate in new space.
1362 __ LoadGlobalFunctionInitialMap(rdi, rcx); 1374 __ bind(&allocate);
1363 if (FLAG_debug_code) { 1375 {
1364 __ cmpb(FieldOperand(rcx, Map::kInstanceSizeOffset), 1376 FrameScope scope(masm, StackFrame::INTERNAL);
1365 Immediate(JSValue::kSize >> kPointerSizeLog2)); 1377 __ Push(rbx);
1366 __ Assert(equal, kUnexpectedStringWrapperInstanceSize); 1378 __ Push(rdi);
1367 __ cmpb(FieldOperand(rcx, Map::kUnusedPropertyFieldsOffset), Immediate(0)); 1379 __ Push(Smi::FromInt(JSValue::kSize));
1368 __ Assert(equal, kUnexpectedUnusedPropertiesOfStringWrapper); 1380 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1381 __ Pop(rdi);
1382 __ Pop(rbx);
1383 }
1384 __ jmp(&done_allocate);
1369 } 1385 }
1370 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx);
1371
1372 // Set properties and elements.
1373 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
1374 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx);
1375 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx);
1376
1377 // Set the value.
1378 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx);
1379
1380 // Ensure the object is fully initialized.
1381 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
1382
1383 // We're done. Return.
1384 __ ret(0);
1385
1386 // The argument was not found in the number to string cache. Check
1387 // if it's a string already before calling the conversion builtin.
1388 Label convert_argument;
1389 __ bind(&not_cached);
1390 STATIC_ASSERT(kSmiTag == 0);
1391 __ JumpIfSmi(rax, &convert_argument);
1392 Condition is_string = masm->IsObjectStringType(rax, rbx, rcx);
1393 __ j(NegateCondition(is_string), &convert_argument);
1394 __ movp(rbx, rax);
1395 __ IncrementCounter(counters->string_ctor_string_value(), 1);
1396 __ jmp(&argument_is_string);
1397
1398 // Invoke the conversion builtin and put the result into rbx.
1399 __ bind(&convert_argument);
1400 __ IncrementCounter(counters->string_ctor_conversions(), 1);
1401 {
1402 FrameScope scope(masm, StackFrame::INTERNAL);
1403 __ Push(rdi); // Preserve the function.
1404 ToStringStub stub(masm->isolate());
1405 __ CallStub(&stub);
1406 __ Pop(rdi);
1407 }
1408 __ movp(rbx, rax);
1409 __ jmp(&argument_is_string);
1410
1411 // Load the empty string into rbx, remove the receiver from the
1412 // stack, and jump back to the case where the argument is a string.
1413 __ bind(&no_arguments);
1414 __ LoadRoot(rbx, Heap::kempty_stringRootIndex);
1415 __ PopReturnAddressTo(rcx);
1416 __ leap(rsp, Operand(rsp, kPointerSize));
1417 __ PushReturnAddressFrom(rcx);
1418 __ jmp(&argument_is_string);
1419
1420 // At this point the argument is already a string. Call runtime to
1421 // create a string wrapper.
1422 __ bind(&gc_required);
1423 __ IncrementCounter(counters->string_ctor_gc_required(), 1);
1424 {
1425 FrameScope scope(masm, StackFrame::INTERNAL);
1426 __ Push(rbx);
1427 __ CallRuntime(Runtime::kNewStringWrapper, 1);
1428 }
1429 __ ret(0);
1430 } 1386 }
1431 1387
1432 1388
1433 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, 1389 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
1434 Label* stack_overflow) { 1390 Label* stack_overflow) {
1435 // ----------- S t a t e ------------- 1391 // ----------- S t a t e -------------
1436 // -- rax : actual number of arguments 1392 // -- rax : actual number of arguments
1437 // -- rbx : expected number of arguments 1393 // -- rbx : expected number of arguments
1438 // -- rdi: function (passed through to callee) 1394 // -- rdi: function (passed through to callee)
1439 // ----------------------------------- 1395 // -----------------------------------
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 __ ret(0); 1774 __ ret(0);
1819 } 1775 }
1820 1776
1821 1777
1822 #undef __ 1778 #undef __
1823 1779
1824 } // namespace internal 1780 } // namespace internal
1825 } // namespace v8 1781 } // namespace v8
1826 1782
1827 #endif // V8_TARGET_ARCH_X64 1783 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/runtime/runtime-object.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698