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

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

Issue 9491005: Port string construct stub to x64. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 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 | « 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 // 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 ParameterCount expected(0); 323 ParameterCount expected(0);
324 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, 324 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET,
325 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 325 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
326 } else { 326 } else {
327 ParameterCount actual(rax); 327 ParameterCount actual(rax);
328 __ InvokeFunction(rdi, actual, CALL_FUNCTION, 328 __ InvokeFunction(rdi, actual, CALL_FUNCTION,
329 NullCallWrapper(), CALL_AS_METHOD); 329 NullCallWrapper(), CALL_AS_METHOD);
330 } 330 }
331 331
332 // Store offset of return address for deoptimizer. 332 // Store offset of return address for deoptimizer.
333 // TODO(849): Once Generate_StringConstructCode doesn't reuse this 333 if (!is_api_function && !count_constructions) {
334 // generator, we can drop the third condition below!
335 if (!is_api_function && !count_constructions &&
336 masm->isolate()->heap()->construct_stub_deopt_pc_offset() == 0) {
337 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 334 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
338 } 335 }
339 336
340 // Restore context from the frame. 337 // Restore context from the frame.
341 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 338 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
342 339
343 // If the result is an object (in the ECMA sense), we should get rid 340 // If the result is an object (in the ECMA sense), we should get rid
344 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 341 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
345 // on page 74. 342 // on page 74.
346 Label use_receiver, exit; 343 Label use_receiver, exit;
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 // Jump to the generic construct code in case the specialized code cannot 1425 // Jump to the generic construct code in case the specialized code cannot
1429 // handle the construction. 1426 // handle the construction.
1430 __ bind(&generic_constructor); 1427 __ bind(&generic_constructor);
1431 Handle<Code> generic_construct_stub = 1428 Handle<Code> generic_construct_stub =
1432 masm->isolate()->builtins()->JSConstructStubGeneric(); 1429 masm->isolate()->builtins()->JSConstructStubGeneric();
1433 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 1430 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
1434 } 1431 }
1435 1432
1436 1433
1437 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 1434 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1438 // TODO(849): implement custom construct stub. 1435 // ----------- S t a t e -------------
1439 // Generate a copy of the generic stub for now. 1436 // -- rax : number of arguments
1440 Generate_JSConstructStubGeneric(masm); 1437 // -- rdi : constructor function
1438 // -- rsp[0] : return address
1439 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1440 // -- rsp[(argc + 1) * 8] : receiver
1441 // -----------------------------------
1442 Counters* counters = masm->isolate()->counters();
1443 __ IncrementCounter(counters->string_ctor_calls(), 1);
1444
1445 if (FLAG_debug_code) {
1446 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, rcx);
1447 __ cmpq(rdi, rcx);
1448 __ Assert(equal, "Unexpected String function");
1449 }
1450
1451 // Load the first argument into rax and get rid of the rest
1452 // (including the receiver).
1453 Label no_arguments;
1454 __ testq(rax, rax);
1455 __ j(zero, &no_arguments);
1456 __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
1457 __ pop(rcx);
1458 __ lea(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1459 __ push(rcx);
1460 __ movq(rax, rbx);
1461
1462 // Lookup the argument in the number to string cache.
1463 Label not_cached, argument_is_string;
1464 NumberToStringStub::GenerateLookupNumberStringCache(
1465 masm,
1466 rax, // Input.
1467 rbx, // Result.
1468 rcx, // Scratch 1.
1469 rdx, // Scratch 2.
1470 false, // Input is known to be smi?
1471 &not_cached);
1472 __ IncrementCounter(counters->string_ctor_cached_number(), 1);
1473 __ bind(&argument_is_string);
1474
1475 // ----------- S t a t e -------------
1476 // -- rbx : argument converted to string
1477 // -- rdi : constructor function
1478 // -- rsp[0] : return address
1479 // -----------------------------------
1480
1481 // Allocate a JSValue and put the tagged pointer into rax.
1482 Label gc_required;
1483 __ AllocateInNewSpace(JSValue::kSize,
1484 rax, // Result.
1485 rcx, // New allocation top (we ignore it).
1486 no_reg,
1487 &gc_required,
1488 TAG_OBJECT);
1489
1490 // Set the map.
1491 __ LoadGlobalFunctionInitialMap(rdi, rcx);
1492 if (FLAG_debug_code) {
1493 __ cmpb(FieldOperand(rcx, Map::kInstanceSizeOffset),
1494 Immediate(JSValue::kSize >> kPointerSizeLog2));
1495 __ Assert(equal, "Unexpected string wrapper instance size");
1496 __ cmpb(FieldOperand(rcx, Map::kUnusedPropertyFieldsOffset), Immediate(0));
1497 __ Assert(equal, "Unexpected unused properties of string wrapper");
1498 }
1499 __ movq(FieldOperand(rax, HeapObject::kMapOffset), rcx);
1500
1501 // Set properties and elements.
1502 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
1503 __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rcx);
1504 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
1505
1506 // Set the value.
1507 __ movq(FieldOperand(rax, JSValue::kValueOffset), rbx);
1508
1509 // Ensure the object is fully initialized.
1510 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
1511
1512 // We're done. Return.
1513 __ ret(0);
1514
1515 // The argument was not found in the number to string cache. Check
1516 // if it's a string already before calling the conversion builtin.
1517 Label convert_argument;
1518 __ bind(&not_cached);
1519 STATIC_ASSERT(kSmiTag == 0);
1520 __ JumpIfSmi(rax, &convert_argument);
1521 Condition is_string = masm->IsObjectStringType(rax, rbx, rcx);
1522 __ j(NegateCondition(is_string), &convert_argument);
1523 __ movq(rbx, rax);
1524 __ IncrementCounter(counters->string_ctor_string_value(), 1);
1525 __ jmp(&argument_is_string);
1526
1527 // Invoke the conversion builtin and put the result into rbx.
1528 __ bind(&convert_argument);
1529 __ IncrementCounter(counters->string_ctor_conversions(), 1);
1530 {
1531 FrameScope scope(masm, StackFrame::INTERNAL);
1532 __ push(rdi); // Preserve the function.
1533 __ push(rax);
1534 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
1535 __ pop(rdi);
1536 }
1537 __ movq(rbx, rax);
1538 __ jmp(&argument_is_string);
1539
1540 // Load the empty string into rbx, remove the receiver from the
1541 // stack, and jump back to the case where the argument is a string.
1542 __ bind(&no_arguments);
1543 __ LoadRoot(rbx, Heap::kEmptyStringRootIndex);
1544 __ pop(rcx);
1545 __ lea(rsp, Operand(rsp, kPointerSize));
1546 __ push(rcx);
1547 __ jmp(&argument_is_string);
1548
1549 // At this point the argument is already a string. Call runtime to
1550 // create a string wrapper.
1551 __ bind(&gc_required);
1552 __ IncrementCounter(counters->string_ctor_gc_required(), 1);
1553 {
1554 FrameScope scope(masm, StackFrame::INTERNAL);
1555 __ push(rbx);
1556 __ CallRuntime(Runtime::kNewStringWrapper, 1);
1557 }
1558 __ ret(0);
1441 } 1559 }
1442 1560
1443 1561
1444 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1562 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1445 __ push(rbp); 1563 __ push(rbp);
1446 __ movq(rbp, rsp); 1564 __ movq(rbp, rsp);
1447 1565
1448 // Store the arguments adaptor context sentinel. 1566 // Store the arguments adaptor context sentinel.
1449 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 1567 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1450 1568
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1736 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1619 generator.Generate(); 1737 generator.Generate();
1620 } 1738 }
1621 1739
1622 1740
1623 #undef __ 1741 #undef __
1624 1742
1625 } } // namespace v8::internal 1743 } } // namespace v8::internal
1626 1744
1627 #endif // V8_TARGET_ARCH_X64 1745 #endif // V8_TARGET_ARCH_X64
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