OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 __ LoadObject(RBX, function); | 692 __ LoadObject(RBX, function); |
693 __ pushq(RBX); | 693 __ pushq(RBX); |
694 GenerateCallRuntime(AstNode::kNoId, | 694 GenerateCallRuntime(AstNode::kNoId, |
695 0, | 695 0, |
696 kTraceFunctionExitRuntimeEntry); | 696 kTraceFunctionExitRuntimeEntry); |
697 __ popq(RAX); // Remove argument. | 697 __ popq(RAX); // Remove argument. |
698 __ popq(RAX); // Restore result. | 698 __ popq(RAX); // Restore result. |
699 } | 699 } |
700 __ LeaveFrame(); | 700 __ LeaveFrame(); |
701 __ ret(); | 701 __ ret(); |
702 // TODO(hausner): insert generation of of PcDescriptor::kReturn, | 702 |
703 // analogous to 32bit version. | 703 // Generate 8 bytes of NOPs so that the debugger can patch the |
| 704 // return pattern with a call to the debug stub. |
| 705 __ nop(1); |
| 706 __ nop(1); |
| 707 __ nop(1); |
| 708 __ nop(1); |
| 709 __ nop(1); |
| 710 __ nop(1); |
| 711 __ nop(1); |
| 712 __ nop(1); |
| 713 AddCurrentDescriptor(PcDescriptors::kReturn, |
| 714 node->id(), |
| 715 node->token_index()); |
| 716 |
704 | 717 |
705 #ifdef DEBUG | 718 #ifdef DEBUG |
706 __ Bind(&wrong_stack); | 719 __ Bind(&wrong_stack); |
707 __ Stop("Exit stack size does not match the entry stack size."); | 720 __ Stop("Exit stack size does not match the entry stack size."); |
708 #endif // DEBUG. | 721 #endif // DEBUG. |
709 } | 722 } |
710 | 723 |
711 | 724 |
712 void CodeGenerator::VisitReturnNode(ReturnNode* node) { | 725 void CodeGenerator::VisitReturnNode(ReturnNode* node) { |
713 ASSERT(!IsResultNeeded(node)); | 726 ASSERT(!IsResultNeeded(node)); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 const Class& cls = Class::Handle(function.signature_class()); | 813 const Class& cls = Class::Handle(function.signature_class()); |
801 ASSERT(!cls.IsNull()); | 814 ASSERT(!cls.IsNull()); |
802 const bool requires_type_arguments = cls.HasTypeArguments(); | 815 const bool requires_type_arguments = cls.HasTypeArguments(); |
803 if (requires_type_arguments) { | 816 if (requires_type_arguments) { |
804 ASSERT(!function.IsImplicitStaticClosureFunction()); | 817 ASSERT(!function.IsImplicitStaticClosureFunction()); |
805 GenerateInstantiatorTypeArguments(node->token_index()); | 818 GenerateInstantiatorTypeArguments(node->token_index()); |
806 } | 819 } |
807 const Code& stub = Code::Handle( | 820 const Code& stub = Code::Handle( |
808 StubCode::GetAllocationStubForClosure(function)); | 821 StubCode::GetAllocationStubForClosure(function)); |
809 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | 822 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); |
810 GenerateCall(node->token_index(), &label); | 823 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
811 if (requires_type_arguments) { | 824 if (requires_type_arguments) { |
812 __ popq(RCX); // Pop type arguments. | 825 __ popq(RCX); // Pop type arguments. |
813 } | 826 } |
814 if (function.IsImplicitInstanceClosureFunction()) { | 827 if (function.IsImplicitInstanceClosureFunction()) { |
815 __ popq(RCX); // Pop receiver. | 828 __ popq(RCX); // Pop receiver. |
816 } | 829 } |
817 if (IsResultNeeded(node)) { | 830 if (IsResultNeeded(node)) { |
818 __ pushq(RAX); | 831 __ pushq(RAX); |
819 } | 832 } |
820 } | 833 } |
(...skipping 20 matching lines...) Expand all Loading... |
841 CodeGeneratorState codegen_state(this); | 854 CodeGeneratorState codegen_state(this); |
842 LocalScope* scope = node_sequence->scope(); | 855 LocalScope* scope = node_sequence->scope(); |
843 const intptr_t num_context_variables = | 856 const intptr_t num_context_variables = |
844 (scope != NULL) ? scope->num_context_variables() : 0; | 857 (scope != NULL) ? scope->num_context_variables() : 0; |
845 if (num_context_variables > 0) { | 858 if (num_context_variables > 0) { |
846 // The loop local scope declares variables that are captured. | 859 // The loop local scope declares variables that are captured. |
847 // Allocate and chain a new context. | 860 // Allocate and chain a new context. |
848 __ movq(R10, Immediate(num_context_variables)); | 861 __ movq(R10, Immediate(num_context_variables)); |
849 const ExternalLabel label("alloc_context", | 862 const ExternalLabel label("alloc_context", |
850 StubCode::AllocateContextEntryPoint()); | 863 StubCode::AllocateContextEntryPoint()); |
851 GenerateCall(node_sequence->token_index(), &label); | 864 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); |
852 | 865 |
853 // Chain the new context in RAX to its parent in CTX. | 866 // Chain the new context in RAX to its parent in CTX. |
854 __ StoreIntoObject(RAX, | 867 __ StoreIntoObject(RAX, |
855 FieldAddress(RAX, Context::parent_offset()), | 868 FieldAddress(RAX, Context::parent_offset()), |
856 CTX); | 869 CTX); |
857 // Set new context as current context. | 870 // Set new context as current context. |
858 __ movq(CTX, RAX); | 871 __ movq(CTX, RAX); |
859 state()->set_context_level(scope->context_level()); | 872 state()->set_context_level(scope->context_level()); |
860 | 873 |
861 // If this node_sequence is the body of the function being compiled, copy | 874 // If this node_sequence is the body of the function being compiled, copy |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 element->Visit(this); | 935 element->Visit(this); |
923 } | 936 } |
924 | 937 |
925 // Allocate the array. | 938 // Allocate the array. |
926 // R10 : Array length as Smi. | 939 // R10 : Array length as Smi. |
927 // RBX : element type for the array. | 940 // RBX : element type for the array. |
928 __ movq(R10, Immediate(Smi::RawValue(node->length()))); | 941 __ movq(R10, Immediate(Smi::RawValue(node->length()))); |
929 const AbstractTypeArguments& element_type = node->type_arguments(); | 942 const AbstractTypeArguments& element_type = node->type_arguments(); |
930 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); | 943 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); |
931 __ LoadObject(RBX, element_type); | 944 __ LoadObject(RBX, element_type); |
932 GenerateCall(node->token_index(), &StubCode::AllocateArrayLabel()); | 945 GenerateCall(node->token_index(), |
| 946 &StubCode::AllocateArrayLabel(), |
| 947 PcDescriptors::kOther); |
933 | 948 |
934 // Pop the element values from the stack into the array. | 949 // Pop the element values from the stack into the array. |
935 __ leaq(RCX, FieldAddress(RAX, Array::data_offset())); | 950 __ leaq(RCX, FieldAddress(RAX, Array::data_offset())); |
936 for (int i = node->length() - 1; i >= 0; i--) { | 951 for (int i = node->length() - 1; i >= 0; i--) { |
937 __ popq(Address(RCX, i * kWordSize)); | 952 __ popq(Address(RCX, i * kWordSize)); |
938 } | 953 } |
939 | 954 |
940 if (IsResultNeeded(node)) { | 955 if (IsResultNeeded(node)) { |
941 __ pushq(RAX); | 956 __ pushq(RAX); |
942 } | 957 } |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2117 } | 2132 } |
2118 | 2133 |
2119 // Could not concatenate at compile time, generate a call to | 2134 // Could not concatenate at compile time, generate a call to |
2120 // interpolation function. | 2135 // interpolation function. |
2121 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); | 2136 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); |
2122 interpol_arg->Add(node->values()); | 2137 interpol_arg->Add(node->values()); |
2123 node->values()->Visit(this); | 2138 node->values()->Visit(this); |
2124 __ LoadObject(RBX, interpol_func); | 2139 __ LoadObject(RBX, interpol_func); |
2125 __ LoadObject(R10, ArgumentsDescriptor(interpol_arg->length(), | 2140 __ LoadObject(R10, ArgumentsDescriptor(interpol_arg->length(), |
2126 interpol_arg->names())); | 2141 interpol_arg->names())); |
2127 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2142 GenerateCall(node->token_index(), |
| 2143 &StubCode::CallStaticFunctionLabel(), |
| 2144 PcDescriptors::kOther); |
2128 __ addq(RSP, Immediate(interpol_arg->length() * kWordSize)); | 2145 __ addq(RSP, Immediate(interpol_arg->length() * kWordSize)); |
2129 // Result is in RAX. | 2146 // Result is in RAX. |
2130 if (IsResultNeeded(node)) { | 2147 if (IsResultNeeded(node)) { |
2131 __ pushq(RAX); | 2148 __ pushq(RAX); |
2132 } | 2149 } |
2133 } | 2150 } |
2134 | 2151 |
2135 | 2152 |
2136 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { | 2153 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { |
2137 const int number_of_arguments = node->arguments()->length() + 1; | 2154 const int number_of_arguments = node->arguments()->length() + 1; |
(...skipping 16 matching lines...) Expand all Loading... |
2154 __ pushq(RAX); | 2171 __ pushq(RAX); |
2155 } | 2172 } |
2156 } | 2173 } |
2157 | 2174 |
2158 | 2175 |
2159 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { | 2176 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { |
2160 node->arguments()->Visit(this); | 2177 node->arguments()->Visit(this); |
2161 __ LoadObject(RBX, node->function()); | 2178 __ LoadObject(RBX, node->function()); |
2162 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), | 2179 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), |
2163 node->arguments()->names())); | 2180 node->arguments()->names())); |
2164 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2181 GenerateCall(node->token_index(), |
| 2182 &StubCode::CallStaticFunctionLabel(), |
| 2183 PcDescriptors::kFuncCall); |
2165 __ addq(RSP, Immediate(node->arguments()->length() * kWordSize)); | 2184 __ addq(RSP, Immediate(node->arguments()->length() * kWordSize)); |
2166 // Result is in RAX. | 2185 // Result is in RAX. |
2167 if (IsResultNeeded(node)) { | 2186 if (IsResultNeeded(node)) { |
2168 __ pushq(RAX); | 2187 __ pushq(RAX); |
2169 } | 2188 } |
2170 } | 2189 } |
2171 | 2190 |
2172 | 2191 |
2173 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) { | 2192 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) { |
2174 // The spec states that the closure is evaluated before the arguments. | 2193 // The spec states that the closure is evaluated before the arguments. |
2175 // Preserve the current context, since it will be overridden by the closure | 2194 // Preserve the current context, since it will be overridden by the closure |
2176 // context during the call. | 2195 // context during the call. |
2177 __ pushq(CTX); | 2196 __ pushq(CTX); |
2178 // Compute the closure object and pass it as first argument to the stub. | 2197 // Compute the closure object and pass it as first argument to the stub. |
2179 node->closure()->Visit(this); | 2198 node->closure()->Visit(this); |
2180 // Now compute the arguments to the call. | 2199 // Now compute the arguments to the call. |
2181 node->arguments()->Visit(this); | 2200 node->arguments()->Visit(this); |
2182 // Set up the number of arguments (excluding the closure) to the ClosureCall | 2201 // Set up the number of arguments (excluding the closure) to the ClosureCall |
2183 // stub which will setup the closure context and jump to the entrypoint of the | 2202 // stub which will setup the closure context and jump to the entrypoint of the |
2184 // closure function (the function will be compiled if it has not already been | 2203 // closure function (the function will be compiled if it has not already been |
2185 // compiled). | 2204 // compiled). |
2186 // NOTE: The stub accesses the closure before the parameter list. | 2205 // NOTE: The stub accesses the closure before the parameter list. |
2187 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), | 2206 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), |
2188 node->arguments()->names())); | 2207 node->arguments()->names())); |
2189 GenerateCall(node->token_index(), &StubCode::CallClosureFunctionLabel()); | 2208 GenerateCall(node->token_index(), |
| 2209 &StubCode::CallClosureFunctionLabel(), |
| 2210 PcDescriptors::kOther); |
2190 __ addq(RSP, Immediate((node->arguments()->length() + 1) * kWordSize)); | 2211 __ addq(RSP, Immediate((node->arguments()->length() + 1) * kWordSize)); |
2191 // Restore the context. | 2212 // Restore the context. |
2192 __ popq(CTX); | 2213 __ popq(CTX); |
2193 // Result is in RAX. | 2214 // Result is in RAX. |
2194 if (IsResultNeeded(node)) { | 2215 if (IsResultNeeded(node)) { |
2195 __ pushq(RAX); | 2216 __ pushq(RAX); |
2196 } | 2217 } |
2197 } | 2218 } |
2198 | 2219 |
2199 | 2220 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 const bool requires_type_arguments = true; // Always first arg to factory. | 2345 const bool requires_type_arguments = true; // Always first arg to factory. |
2325 GenerateTypeArguments(node, requires_type_arguments); | 2346 GenerateTypeArguments(node, requires_type_arguments); |
2326 // The top of stack is an instantiated AbstractTypeArguments object | 2347 // The top of stack is an instantiated AbstractTypeArguments object |
2327 // (or null). | 2348 // (or null). |
2328 int num_args = node->arguments()->length() + 1; // +1 to include type args. | 2349 int num_args = node->arguments()->length() + 1; // +1 to include type args. |
2329 node->arguments()->Visit(this); | 2350 node->arguments()->Visit(this); |
2330 // Call the factory. | 2351 // Call the factory. |
2331 __ LoadObject(RBX, node->constructor()); | 2352 __ LoadObject(RBX, node->constructor()); |
2332 __ LoadObject(R10, ArgumentsDescriptor(num_args, | 2353 __ LoadObject(R10, ArgumentsDescriptor(num_args, |
2333 node->arguments()->names())); | 2354 node->arguments()->names())); |
2334 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2355 GenerateCall(node->token_index(), |
| 2356 &StubCode::CallStaticFunctionLabel(), |
| 2357 PcDescriptors::kFuncCall); |
2335 // Factory constructor returns object in RAX. | 2358 // Factory constructor returns object in RAX. |
2336 __ addq(RSP, Immediate(num_args * kWordSize)); | 2359 __ addq(RSP, Immediate(num_args * kWordSize)); |
2337 if (IsResultNeeded(node)) { | 2360 if (IsResultNeeded(node)) { |
2338 __ pushq(RAX); | 2361 __ pushq(RAX); |
2339 } | 2362 } |
2340 return; | 2363 return; |
2341 } | 2364 } |
2342 | 2365 |
2343 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 2366 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
2344 const bool requires_type_arguments = cls.HasTypeArguments(); | 2367 const bool requires_type_arguments = cls.HasTypeArguments(); |
2345 GenerateTypeArguments(node, requires_type_arguments); | 2368 GenerateTypeArguments(node, requires_type_arguments); |
2346 | 2369 |
2347 // If cls is parameterized, the type arguments and the instantiator's | 2370 // If cls is parameterized, the type arguments and the instantiator's |
2348 // type arguments are on the stack. | 2371 // type arguments are on the stack. |
2349 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); | 2372 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); |
2350 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); | 2373 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); |
2351 GenerateCall(node->token_index(), &label); | 2374 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
2352 if (requires_type_arguments) { | 2375 if (requires_type_arguments) { |
2353 __ popq(RCX); // Pop type arguments. | 2376 __ popq(RCX); // Pop type arguments. |
2354 __ popq(RCX); // Pop instantiator type arguments. | 2377 __ popq(RCX); // Pop instantiator type arguments. |
2355 } | 2378 } |
2356 | 2379 |
2357 if (IsResultNeeded(node)) { | 2380 if (IsResultNeeded(node)) { |
2358 __ pushq(RAX); // Set up return value from allocate. | 2381 __ pushq(RAX); // Set up return value from allocate. |
2359 } | 2382 } |
2360 | 2383 |
2361 // First argument(this) for constructor call which follows. | 2384 // First argument(this) for constructor call which follows. |
2362 __ pushq(RAX); | 2385 __ pushq(RAX); |
2363 // Second argument is the implicit construction phase parameter. | 2386 // Second argument is the implicit construction phase parameter. |
2364 // Run both the constructor initializer list and the constructor body. | 2387 // Run both the constructor initializer list and the constructor body. |
2365 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); | 2388 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
2366 | 2389 |
2367 | 2390 |
2368 // Now setup rest of the arguments for the constructor call. | 2391 // Now setup rest of the arguments for the constructor call. |
2369 node->arguments()->Visit(this); | 2392 node->arguments()->Visit(this); |
2370 | 2393 |
2371 // Call the constructor. | 2394 // Call the constructor. |
2372 // +2 to include implicit receiver and phase arguments. | 2395 // +2 to include implicit receiver and phase arguments. |
2373 int num_args = node->arguments()->length() + 2; | 2396 int num_args = node->arguments()->length() + 2; |
2374 __ LoadObject(RBX, node->constructor()); | 2397 __ LoadObject(RBX, node->constructor()); |
2375 __ LoadObject(R10, ArgumentsDescriptor(num_args, node->arguments()->names())); | 2398 __ LoadObject(R10, ArgumentsDescriptor(num_args, node->arguments()->names())); |
2376 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2399 GenerateCall(node->token_index(), |
| 2400 &StubCode::CallStaticFunctionLabel(), |
| 2401 PcDescriptors::kFuncCall); |
2377 // Constructors do not return any value. | 2402 // Constructors do not return any value. |
2378 | 2403 |
2379 // Pop out all the other arguments on the stack. | 2404 // Pop out all the other arguments on the stack. |
2380 __ addq(RSP, Immediate(num_args * kWordSize)); | 2405 __ addq(RSP, Immediate(num_args * kWordSize)); |
2381 } | 2406 } |
2382 | 2407 |
2383 | 2408 |
2384 // Expects receiver on stack, returns result in RAX.. | 2409 // Expects receiver on stack, returns result in RAX.. |
2385 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, | 2410 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, |
2386 intptr_t token_index, | 2411 intptr_t token_index, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2460 const Function& function = | 2485 const Function& function = |
2461 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name)); | 2486 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name)); |
2462 if (function.IsNull()) { | 2487 if (function.IsNull()) { |
2463 ErrorMsg(token_index, "Static getter does not exist: %s", | 2488 ErrorMsg(token_index, "Static getter does not exist: %s", |
2464 getter_name.ToCString()); | 2489 getter_name.ToCString()); |
2465 } | 2490 } |
2466 __ LoadObject(RBX, function); | 2491 __ LoadObject(RBX, function); |
2467 const int kNumberOfArguments = 0; | 2492 const int kNumberOfArguments = 0; |
2468 const Array& kNoArgumentNames = Array::Handle(); | 2493 const Array& kNoArgumentNames = Array::Handle(); |
2469 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); | 2494 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); |
2470 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); | 2495 GenerateCall(token_index, |
| 2496 &StubCode::CallStaticFunctionLabel(), |
| 2497 PcDescriptors::kFuncCall); |
2471 // No arguments were pushed, hence nothing to pop. | 2498 // No arguments were pushed, hence nothing to pop. |
2472 } | 2499 } |
2473 | 2500 |
2474 | 2501 |
2475 // Call to static getter. | 2502 // Call to static getter. |
2476 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) { | 2503 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) { |
2477 GenerateStaticGetterCall(node->token_index(), | 2504 GenerateStaticGetterCall(node->token_index(), |
2478 node->cls(), | 2505 node->cls(), |
2479 node->field_name()); | 2506 node->field_name()); |
2480 // Result is in RAX. | 2507 // Result is in RAX. |
2481 if (IsResultNeeded(node)) { | 2508 if (IsResultNeeded(node)) { |
2482 __ pushq(RAX); | 2509 __ pushq(RAX); |
2483 } | 2510 } |
2484 } | 2511 } |
2485 | 2512 |
2486 | 2513 |
2487 // Expects value on stack. | 2514 // Expects value on stack. |
2488 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index, | 2515 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index, |
2489 const Class& field_class, | 2516 const Class& field_class, |
2490 const String& field_name) { | 2517 const String& field_name) { |
2491 const String& setter_name = String::Handle(Field::SetterName(field_name)); | 2518 const String& setter_name = String::Handle(Field::SetterName(field_name)); |
2492 const Function& function = | 2519 const Function& function = |
2493 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name)); | 2520 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name)); |
2494 __ LoadObject(RBX, function); | 2521 __ LoadObject(RBX, function); |
2495 const int kNumberOfArguments = 1; // value. | 2522 const int kNumberOfArguments = 1; // value. |
2496 const Array& kNoArgumentNames = Array::Handle(); | 2523 const Array& kNoArgumentNames = Array::Handle(); |
2497 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); | 2524 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); |
2498 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); | 2525 GenerateCall(token_index, |
| 2526 &StubCode::CallStaticFunctionLabel(), |
| 2527 PcDescriptors::kFuncCall); |
2499 __ addq(RSP, Immediate(kNumberOfArguments * kWordSize)); | 2528 __ addq(RSP, Immediate(kNumberOfArguments * kWordSize)); |
2500 } | 2529 } |
2501 | 2530 |
2502 | 2531 |
2503 // The call to static setter implements assignment to a static field. | 2532 // The call to static setter implements assignment to a static field. |
2504 // The result of the assignment is the value being stored. | 2533 // The result of the assignment is the value being stored. |
2505 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) { | 2534 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) { |
2506 node->value()->Visit(this); | 2535 node->value()->Visit(this); |
2507 if (IsResultNeeded(node)) { | 2536 if (IsResultNeeded(node)) { |
2508 // Preserve the original value when returning from setter. | 2537 // Preserve the original value when returning from setter. |
(...skipping 12 matching lines...) Expand all Loading... |
2521 // Push the result place holder initialized to NULL. | 2550 // Push the result place holder initialized to NULL. |
2522 __ PushObject(Object::ZoneHandle()); | 2551 __ PushObject(Object::ZoneHandle()); |
2523 // Pass a pointer to the first argument in RAX. | 2552 // Pass a pointer to the first argument in RAX. |
2524 if (!node->has_optional_parameters()) { | 2553 if (!node->has_optional_parameters()) { |
2525 __ leaq(RAX, Address(RBP, (1 + node->argument_count()) * kWordSize)); | 2554 __ leaq(RAX, Address(RBP, (1 + node->argument_count()) * kWordSize)); |
2526 } else { | 2555 } else { |
2527 __ leaq(RAX, Address(RBP, -1 * kWordSize)); | 2556 __ leaq(RAX, Address(RBP, -1 * kWordSize)); |
2528 } | 2557 } |
2529 __ movq(RBX, Immediate(reinterpret_cast<uword>(node->native_c_function()))); | 2558 __ movq(RBX, Immediate(reinterpret_cast<uword>(node->native_c_function()))); |
2530 __ movq(R10, Immediate(node->argument_count())); | 2559 __ movq(R10, Immediate(node->argument_count())); |
2531 GenerateCall(node->token_index(), &StubCode::CallNativeCFunctionLabel()); | 2560 GenerateCall(node->token_index(), |
| 2561 &StubCode::CallNativeCFunctionLabel(), |
| 2562 PcDescriptors::kOther); |
2532 // Result is on the stack. | 2563 // Result is on the stack. |
2533 if (!IsResultNeeded(node)) { | 2564 if (!IsResultNeeded(node)) { |
2534 __ popq(RAX); | 2565 __ popq(RAX); |
2535 } | 2566 } |
2536 } | 2567 } |
2537 | 2568 |
2538 | 2569 |
2539 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { | 2570 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { |
2540 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2571 // NOTE: The implicit variables ':saved_context', ':exception_var' |
2541 // and ':stacktrace_var' can never be captured variables. | 2572 // and ':stacktrace_var' can never be captured variables. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2647 GenerateLoadVariable(CTX, node->context_var()); | 2678 GenerateLoadVariable(CTX, node->context_var()); |
2648 node->finally_block()->Visit(this); | 2679 node->finally_block()->Visit(this); |
2649 | 2680 |
2650 if (try_index >= 0) { | 2681 if (try_index >= 0) { |
2651 state()->set_try_index(try_index); | 2682 state()->set_try_index(try_index); |
2652 } | 2683 } |
2653 } | 2684 } |
2654 | 2685 |
2655 | 2686 |
2656 void CodeGenerator::GenerateCall(intptr_t token_index, | 2687 void CodeGenerator::GenerateCall(intptr_t token_index, |
2657 const ExternalLabel* ext_label) { | 2688 const ExternalLabel* ext_label, |
| 2689 PcDescriptors::Kind desc_kind) { |
2658 __ call(ext_label); | 2690 __ call(ext_label); |
2659 AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kNoId, token_index); | 2691 AddCurrentDescriptor(desc_kind, AstNode::kNoId, token_index); |
2660 } | 2692 } |
2661 | 2693 |
2662 | 2694 |
2663 void CodeGenerator::GenerateCallRuntime(intptr_t node_id, | 2695 void CodeGenerator::GenerateCallRuntime(intptr_t node_id, |
2664 intptr_t token_index, | 2696 intptr_t token_index, |
2665 const RuntimeEntry& entry) { | 2697 const RuntimeEntry& entry) { |
2666 __ CallRuntimeFromDart(entry); | 2698 __ CallRuntimeFromDart(entry); |
2667 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); | 2699 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); |
2668 } | 2700 } |
2669 | 2701 |
(...skipping 25 matching lines...) Expand all Loading... |
2695 const Error& error = Error::Handle( | 2727 const Error& error = Error::Handle( |
2696 Parser::FormatError(script, token_index, "Error", format, args)); | 2728 Parser::FormatError(script, token_index, "Error", format, args)); |
2697 va_end(args); | 2729 va_end(args); |
2698 Isolate::Current()->long_jump_base()->Jump(1, error); | 2730 Isolate::Current()->long_jump_base()->Jump(1, error); |
2699 UNREACHABLE(); | 2731 UNREACHABLE(); |
2700 } | 2732 } |
2701 | 2733 |
2702 } // namespace dart | 2734 } // namespace dart |
2703 | 2735 |
2704 #endif // defined TARGET_ARCH_X64 | 2736 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |