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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 17162002: Version 3.19.17. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/test-api.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 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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 STATIC_ASSERT(kFastApiCallArguments == 6); 484 STATIC_ASSERT(kFastApiCallArguments == 6);
485 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 485 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
486 486
487 // Function address is a foreign pointer outside V8's heap. 487 // Function address is a foreign pointer outside V8's heap.
488 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 488 Address function_address = v8::ToCData<Address>(api_call_info->callback());
489 bool returns_handle = 489 bool returns_handle =
490 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); 490 !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
491 491
492 #if defined(__MINGW64__) 492 #if defined(__MINGW64__)
493 Register arguments_arg = rcx; 493 Register arguments_arg = rcx;
494 Register callback_arg = rdx;
495 #elif defined(_WIN64) 494 #elif defined(_WIN64)
496 // Win64 uses first register--rcx--for returned value. 495 // Win64 uses first register--rcx--for returned value.
497 Register arguments_arg = returns_handle ? rdx : rcx; 496 Register arguments_arg = returns_handle ? rdx : rcx;
498 Register callback_arg = returns_handle ? r8 : rdx;
499 #else 497 #else
500 Register arguments_arg = rdi; 498 Register arguments_arg = rdi;
501 Register callback_arg = rsi;
502 #endif 499 #endif
503 500
504 // Allocate the v8::Arguments structure in the arguments' space since 501 // Allocate the v8::Arguments structure in the arguments' space since
505 // it's not controlled by GC. 502 // it's not controlled by GC.
506 const int kApiStackSpace = 4; 503 const int kApiStackSpace = 4;
507 504
508 __ PrepareCallApiFunction(kApiStackSpace, returns_handle); 505 __ PrepareCallApiFunction(kApiStackSpace, returns_handle);
509 506
510 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. 507 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
511 __ addq(rbx, Immediate(argc * kPointerSize)); 508 __ addq(rbx, Immediate(argc * kPointerSize));
512 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. 509 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_.
513 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. 510 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_.
514 // v8::Arguments::is_construct_call_. 511 // v8::Arguments::is_construct_call_.
515 __ Set(StackSpaceOperand(3), 0); 512 __ Set(StackSpaceOperand(3), 0);
516 513
517 // v8::InvocationCallback's argument. 514 // v8::InvocationCallback's argument.
518 __ lea(arguments_arg, StackSpaceOperand(0)); 515 __ lea(arguments_arg, StackSpaceOperand(0));
519 516
520 Address thunk_address = returns_handle
521 ? FUNCTION_ADDR(&InvokeInvocationCallback)
522 : FUNCTION_ADDR(&InvokeFunctionCallback);
523
524 __ CallApiFunctionAndReturn(function_address, 517 __ CallApiFunctionAndReturn(function_address,
525 thunk_address,
526 callback_arg,
527 argc + kFastApiCallArguments + 1, 518 argc + kFastApiCallArguments + 1,
528 returns_handle, 519 returns_handle,
529 kFastApiCallArguments + 1); 520 kFastApiCallArguments + 1);
530 } 521 }
531 522
532 523
533 class CallInterceptorCompiler BASE_EMBEDDED { 524 class CallInterceptorCompiler BASE_EMBEDDED {
534 public: 525 public:
535 CallInterceptorCompiler(StubCompiler* stub_compiler, 526 CallInterceptorCompiler(StubCompiler* stub_compiler,
536 const ParameterCount& arguments, 527 const ParameterCount& arguments,
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 miss_restore_name); 810 miss_restore_name);
820 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 811 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
821 GenerateDictionaryNegativeLookup( 812 GenerateDictionaryNegativeLookup(
822 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); 813 masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
823 } 814 }
824 } 815 }
825 } 816 }
826 817
827 Register storage_reg = name_reg; 818 Register storage_reg = name_reg;
828 819
829 if (details.type() == CONSTANT_FUNCTION) { 820 if (FLAG_track_fields && representation.IsSmi()) {
830 Handle<HeapObject> constant(
831 HeapObject::cast(descriptors->GetValue(descriptor)));
832 __ LoadHeapObject(scratch1, constant);
833 __ cmpq(value_reg, scratch1);
834 __ j(not_equal, miss_restore_name);
835 } else if (FLAG_track_fields && representation.IsSmi()) {
836 __ JumpIfNotSmi(value_reg, miss_restore_name); 821 __ JumpIfNotSmi(value_reg, miss_restore_name);
837 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 822 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
838 __ JumpIfSmi(value_reg, miss_restore_name); 823 __ JumpIfSmi(value_reg, miss_restore_name);
839 } else if (FLAG_track_double_fields && representation.IsDouble()) { 824 } else if (FLAG_track_double_fields && representation.IsDouble()) {
840 Label do_store, heap_number; 825 Label do_store, heap_number;
841 __ AllocateHeapNumber(storage_reg, scratch1, slow); 826 __ AllocateHeapNumber(storage_reg, scratch1, slow);
842 827
843 __ JumpIfNotSmi(value_reg, &heap_number); 828 __ JumpIfNotSmi(value_reg, &heap_number);
844 __ SmiToInteger32(scratch1, value_reg); 829 __ SmiToInteger32(scratch1, value_reg);
845 __ cvtlsi2sd(xmm0, scratch1); 830 __ cvtlsi2sd(xmm0, scratch1);
846 __ jmp(&do_store); 831 __ jmp(&do_store);
847 832
848 __ bind(&heap_number); 833 __ bind(&heap_number);
849 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 834 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
850 miss_restore_name, DONT_DO_SMI_CHECK); 835 miss_restore_name, DONT_DO_SMI_CHECK);
851 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 836 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
852 837
853 __ bind(&do_store); 838 __ bind(&do_store);
854 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 839 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
855 } 840 }
856 841
857 // Stub never generated for non-global objects that require access 842 // Stub never generated for non-global objects that require access
858 // checks. 843 // checks.
859 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 844 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
860 845
861 // Perform map transition for the receiver if necessary. 846 // Perform map transition for the receiver if necessary.
862 if (details.type() == FIELD && 847 if (object->map()->unused_property_fields() == 0) {
863 object->map()->unused_property_fields() == 0) {
864 // The properties must be extended before we can store the value. 848 // The properties must be extended before we can store the value.
865 // We jump to a runtime call that extends the properties array. 849 // We jump to a runtime call that extends the properties array.
866 __ pop(scratch1); // Return address. 850 __ pop(scratch1); // Return address.
867 __ push(receiver_reg); 851 __ push(receiver_reg);
868 __ Push(transition); 852 __ Push(transition);
869 __ push(value_reg); 853 __ push(value_reg);
870 __ push(scratch1); 854 __ push(scratch1);
871 __ TailCallExternalReference( 855 __ TailCallExternalReference(
872 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 856 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
873 masm->isolate()), 857 masm->isolate()),
874 3, 858 3,
875 1); 859 1);
876 return; 860 return;
877 } 861 }
878 862
879 // Update the map of the object. 863 // Update the map of the object.
880 __ Move(scratch1, transition); 864 __ Move(scratch1, transition);
881 __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 865 __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
882 866
883 // Update the write barrier for the map field. 867 // Update the write barrier for the map field.
884 __ RecordWriteField(receiver_reg, 868 __ RecordWriteField(receiver_reg,
885 HeapObject::kMapOffset, 869 HeapObject::kMapOffset,
886 scratch1, 870 scratch1,
887 scratch2, 871 scratch2,
888 kDontSaveFPRegs, 872 kDontSaveFPRegs,
889 OMIT_REMEMBERED_SET, 873 OMIT_REMEMBERED_SET,
890 OMIT_SMI_CHECK); 874 OMIT_SMI_CHECK);
891 875
892 if (details.type() == CONSTANT_FUNCTION) return;
893
894 int index = transition->instance_descriptors()->GetFieldIndex( 876 int index = transition->instance_descriptors()->GetFieldIndex(
895 transition->LastAdded()); 877 transition->LastAdded());
896 878
897 // Adjust for the number of properties stored in the object. Even in the 879 // Adjust for the number of properties stored in the object. Even in the
898 // face of a transition we can use the old map here because the size of the 880 // face of a transition we can use the old map here because the size of the
899 // object and the number of in-object properties is not going to change. 881 // object and the number of in-object properties is not going to change.
900 index -= object->map()->inobject_properties(); 882 index -= object->map()->inobject_properties();
901 883
902 // TODO(verwaest): Share this code as a code stub. 884 // TODO(verwaest): Share this code as a code stub.
903 SmiCheck smi_check = representation.IsTagged() 885 SmiCheck smi_check = representation.IsTagged()
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 __ PushAddress(ExternalReference::isolate_address(isolate())); 1311 __ PushAddress(ExternalReference::isolate_address(isolate()));
1330 __ push(name()); // name 1312 __ push(name()); // name
1331 // Save a pointer to where we pushed the arguments pointer. This will be 1313 // Save a pointer to where we pushed the arguments pointer. This will be
1332 // passed as the const ExecutableAccessorInfo& to the C++ callback. 1314 // passed as the const ExecutableAccessorInfo& to the C++ callback.
1333 1315
1334 Address getter_address = v8::ToCData<Address>(callback->getter()); 1316 Address getter_address = v8::ToCData<Address>(callback->getter());
1335 bool returns_handle = 1317 bool returns_handle =
1336 !CallbackTable::ReturnsVoid(isolate(), getter_address); 1318 !CallbackTable::ReturnsVoid(isolate(), getter_address);
1337 1319
1338 #if defined(__MINGW64__) 1320 #if defined(__MINGW64__)
1339 Register getter_arg = r8;
1340 Register accessor_info_arg = rdx; 1321 Register accessor_info_arg = rdx;
1341 Register name_arg = rcx; 1322 Register name_arg = rcx;
1342 #elif defined(_WIN64) 1323 #elif defined(_WIN64)
1343 // Win64 uses first register--rcx--for returned value. 1324 // Win64 uses first register--rcx--for returned value.
1344 Register getter_arg = returns_handle ? r9 : r8;
1345 Register accessor_info_arg = returns_handle ? r8 : rdx; 1325 Register accessor_info_arg = returns_handle ? r8 : rdx;
1346 Register name_arg = returns_handle ? rdx : rcx; 1326 Register name_arg = returns_handle ? rdx : rcx;
1347 #else 1327 #else
1348 Register getter_arg = rdx;
1349 Register accessor_info_arg = rsi; 1328 Register accessor_info_arg = rsi;
1350 Register name_arg = rdi; 1329 Register name_arg = rdi;
1351 #endif 1330 #endif
1352 1331
1353 ASSERT(!name_arg.is(scratch2())); 1332 ASSERT(!name_arg.is(scratch2()));
1354 __ movq(name_arg, rsp); 1333 __ movq(name_arg, rsp);
1355 __ push(scratch2()); // Restore return address. 1334 __ push(scratch2()); // Restore return address.
1356 1335
1357 // v8::Arguments::values_ and handler for name. 1336 // v8::Arguments::values_ and handler for name.
1358 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1; 1337 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
1359 1338
1360 // Allocate v8::AccessorInfo in non-GCed stack space. 1339 // Allocate v8::AccessorInfo in non-GCed stack space.
1361 const int kArgStackSpace = 1; 1340 const int kArgStackSpace = 1;
1362 1341
1363 __ PrepareCallApiFunction(kArgStackSpace, returns_handle); 1342 __ PrepareCallApiFunction(kArgStackSpace, returns_handle);
1364 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 1343 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
1365 __ lea(rax, Operand(name_arg, 6 * kPointerSize)); 1344 __ lea(rax, Operand(name_arg, 6 * kPointerSize));
1366 1345
1367 // v8::AccessorInfo::args_. 1346 // v8::AccessorInfo::args_.
1368 __ movq(StackSpaceOperand(0), rax); 1347 __ movq(StackSpaceOperand(0), rax);
1369 1348
1370 // The context register (rsi) has been saved in PrepareCallApiFunction and 1349 // The context register (rsi) has been saved in PrepareCallApiFunction and
1371 // could be used to pass arguments. 1350 // could be used to pass arguments.
1372 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1351 __ lea(accessor_info_arg, StackSpaceOperand(0));
1373 1352
1374 Address thunk_address = returns_handle
1375 ? FUNCTION_ADDR(&InvokeAccessorGetter)
1376 : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
1377
1378 __ CallApiFunctionAndReturn(getter_address, 1353 __ CallApiFunctionAndReturn(getter_address,
1379 thunk_address,
1380 getter_arg,
1381 kStackSpace, 1354 kStackSpace,
1382 returns_handle, 1355 returns_handle,
1383 5); 1356 5);
1384 } 1357 }
1385 1358
1386 1359
1387 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { 1360 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) {
1388 // Return the constant value. 1361 // Return the constant value.
1389 __ LoadHeapObject(rax, value); 1362 __ LoadHeapObject(rax, value);
1390 __ ret(0); 1363 __ ret(0);
(...skipping 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after
3513 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3486 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3514 } 3487 }
3515 } 3488 }
3516 3489
3517 3490
3518 #undef __ 3491 #undef __
3519 3492
3520 } } // namespace v8::internal 3493 } } // namespace v8::internal
3521 3494
3522 #endif // V8_TARGET_ARCH_X64 3495 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698