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 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
780 __ LoadObject(RBX, function); | 780 __ LoadObject(RBX, function); |
781 __ pushq(RBX); | 781 __ pushq(RBX); |
782 GenerateCallRuntime(AstNode::kNoId, | 782 GenerateCallRuntime(AstNode::kNoId, |
783 0, | 783 0, |
784 kTraceFunctionExitRuntimeEntry); | 784 kTraceFunctionExitRuntimeEntry); |
785 __ popq(RAX); // Remove argument. | 785 __ popq(RAX); // Remove argument. |
786 __ popq(RAX); // Restore result. | 786 __ popq(RAX); // Restore result. |
787 } | 787 } |
788 __ LeaveFrame(); | 788 __ LeaveFrame(); |
789 __ ret(); | 789 __ ret(); |
790 // TODO(hausner): insert generation of of PcDescriptor::kReturn, | 790 |
791 // analogous to 32bit version. | 791 // Generate 8 bytes of NOPs so that the debugger can patch the |
792 // return pattern with a call to the debug stub. | |
793 __ nop(1); | |
794 __ nop(1); | |
795 __ nop(1); | |
796 __ nop(1); | |
797 __ nop(1); | |
798 __ nop(1); | |
799 __ nop(1); | |
800 __ nop(1); | |
regis
2012/02/24 23:32:37
Why not __ nop(8)?
Disassembly would be more compa
hausner
2012/02/27 22:03:57
It's simpler to recognize the code pattern when I
| |
801 AddCurrentDescriptor(PcDescriptors::kReturn, | |
802 node->id(), | |
803 node->token_index()); | |
804 | |
792 | 805 |
793 #ifdef DEBUG | 806 #ifdef DEBUG |
794 __ Bind(&wrong_stack); | 807 __ Bind(&wrong_stack); |
795 __ Stop("Exit stack size does not match the entry stack size."); | 808 __ Stop("Exit stack size does not match the entry stack size."); |
796 #endif // DEBUG. | 809 #endif // DEBUG. |
797 } | 810 } |
798 | 811 |
799 | 812 |
800 void CodeGenerator::VisitReturnNode(ReturnNode* node) { | 813 void CodeGenerator::VisitReturnNode(ReturnNode* node) { |
801 ASSERT(!IsResultNeeded(node)); | 814 ASSERT(!IsResultNeeded(node)); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
888 const Class& cls = Class::Handle(function.signature_class()); | 901 const Class& cls = Class::Handle(function.signature_class()); |
889 ASSERT(!cls.IsNull()); | 902 ASSERT(!cls.IsNull()); |
890 const bool requires_type_arguments = cls.HasTypeArguments(); | 903 const bool requires_type_arguments = cls.HasTypeArguments(); |
891 if (requires_type_arguments) { | 904 if (requires_type_arguments) { |
892 ASSERT(!function.IsImplicitStaticClosureFunction()); | 905 ASSERT(!function.IsImplicitStaticClosureFunction()); |
893 GenerateInstantiatorTypeArguments(node->token_index()); | 906 GenerateInstantiatorTypeArguments(node->token_index()); |
894 } | 907 } |
895 const Code& stub = Code::Handle( | 908 const Code& stub = Code::Handle( |
896 StubCode::GetAllocationStubForClosure(function)); | 909 StubCode::GetAllocationStubForClosure(function)); |
897 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | 910 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); |
898 GenerateCall(node->token_index(), &label); | 911 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
899 if (requires_type_arguments) { | 912 if (requires_type_arguments) { |
900 __ popq(RCX); // Pop type arguments. | 913 __ popq(RCX); // Pop type arguments. |
901 } | 914 } |
902 if (function.IsImplicitInstanceClosureFunction()) { | 915 if (function.IsImplicitInstanceClosureFunction()) { |
903 __ popq(RCX); // Pop receiver. | 916 __ popq(RCX); // Pop receiver. |
904 } | 917 } |
905 if (IsResultNeeded(node)) { | 918 if (IsResultNeeded(node)) { |
906 __ pushq(RAX); | 919 __ pushq(RAX); |
907 } | 920 } |
908 } | 921 } |
(...skipping 21 matching lines...) Expand all Loading... | |
930 CodeGeneratorState codegen_state(this); | 943 CodeGeneratorState codegen_state(this); |
931 LocalScope* scope = node_sequence->scope(); | 944 LocalScope* scope = node_sequence->scope(); |
932 const intptr_t num_context_variables = | 945 const intptr_t num_context_variables = |
933 (scope != NULL) ? scope->num_context_variables() : 0; | 946 (scope != NULL) ? scope->num_context_variables() : 0; |
934 if (num_context_variables > 0) { | 947 if (num_context_variables > 0) { |
935 // The loop local scope declares variables that are captured. | 948 // The loop local scope declares variables that are captured. |
936 // Allocate and chain a new context. | 949 // Allocate and chain a new context. |
937 __ movq(R10, Immediate(num_context_variables)); | 950 __ movq(R10, Immediate(num_context_variables)); |
938 const ExternalLabel label("alloc_context", | 951 const ExternalLabel label("alloc_context", |
939 StubCode::AllocateContextEntryPoint()); | 952 StubCode::AllocateContextEntryPoint()); |
940 GenerateCall(node_sequence->token_index(), &label); | 953 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther); |
941 | 954 |
942 // Chain the new context in RAX to its parent in CTX. | 955 // Chain the new context in RAX to its parent in CTX. |
943 __ StoreIntoObject(RAX, | 956 __ StoreIntoObject(RAX, |
944 FieldAddress(RAX, Context::parent_offset()), | 957 FieldAddress(RAX, Context::parent_offset()), |
945 CTX); | 958 CTX); |
946 // Set new context as current context. | 959 // Set new context as current context. |
947 __ movq(CTX, RAX); | 960 __ movq(CTX, RAX); |
948 state()->set_context_level(scope->context_level()); | 961 state()->set_context_level(scope->context_level()); |
949 | 962 |
950 // If this node_sequence is the body of the function being compiled, copy | 963 // If this node_sequence is the body of the function being compiled, copy |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1009 element->Visit(this); | 1022 element->Visit(this); |
1010 } | 1023 } |
1011 | 1024 |
1012 // Allocate the array. | 1025 // Allocate the array. |
1013 // R10 : Array length as Smi. | 1026 // R10 : Array length as Smi. |
1014 // RBX : element type for the array. | 1027 // RBX : element type for the array. |
1015 __ movq(R10, Immediate(Smi::RawValue(node->length()))); | 1028 __ movq(R10, Immediate(Smi::RawValue(node->length()))); |
1016 const AbstractTypeArguments& element_type = node->type_arguments(); | 1029 const AbstractTypeArguments& element_type = node->type_arguments(); |
1017 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); | 1030 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); |
1018 __ LoadObject(RBX, element_type); | 1031 __ LoadObject(RBX, element_type); |
1019 GenerateCall(node->token_index(), &StubCode::AllocateArrayLabel()); | 1032 GenerateCall(node->token_index(), |
1033 &StubCode::AllocateArrayLabel(), | |
1034 PcDescriptors::kOther); | |
1020 | 1035 |
1021 // Pop the element values from the stack into the array. | 1036 // Pop the element values from the stack into the array. |
1022 __ leaq(RCX, FieldAddress(RAX, Array::data_offset())); | 1037 __ leaq(RCX, FieldAddress(RAX, Array::data_offset())); |
1023 for (int i = node->length() - 1; i >= 0; i--) { | 1038 for (int i = node->length() - 1; i >= 0; i--) { |
1024 __ popq(Address(RCX, i * kWordSize)); | 1039 __ popq(Address(RCX, i * kWordSize)); |
1025 } | 1040 } |
1026 | 1041 |
1027 if (IsResultNeeded(node)) { | 1042 if (IsResultNeeded(node)) { |
1028 __ pushq(RAX); | 1043 __ pushq(RAX); |
1029 } | 1044 } |
(...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2213 } | 2228 } |
2214 | 2229 |
2215 // Could not concatenate at compile time, generate a call to | 2230 // Could not concatenate at compile time, generate a call to |
2216 // interpolation function. | 2231 // interpolation function. |
2217 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); | 2232 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); |
2218 interpol_arg->Add(node->values()); | 2233 interpol_arg->Add(node->values()); |
2219 node->values()->Visit(this); | 2234 node->values()->Visit(this); |
2220 __ LoadObject(RBX, interpol_func); | 2235 __ LoadObject(RBX, interpol_func); |
2221 __ LoadObject(R10, ArgumentsDescriptor(interpol_arg->length(), | 2236 __ LoadObject(R10, ArgumentsDescriptor(interpol_arg->length(), |
2222 interpol_arg->names())); | 2237 interpol_arg->names())); |
2223 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2238 GenerateCall(node->token_index(), |
2239 &StubCode::CallStaticFunctionLabel(), | |
2240 PcDescriptors::kOther); | |
2224 __ addq(RSP, Immediate(interpol_arg->length() * kWordSize)); | 2241 __ addq(RSP, Immediate(interpol_arg->length() * kWordSize)); |
2225 // Result is in RAX. | 2242 // Result is in RAX. |
2226 if (IsResultNeeded(node)) { | 2243 if (IsResultNeeded(node)) { |
2227 __ pushq(RAX); | 2244 __ pushq(RAX); |
2228 } | 2245 } |
2229 } | 2246 } |
2230 | 2247 |
2231 | 2248 |
2232 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { | 2249 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { |
2233 const int number_of_arguments = node->arguments()->length() + 1; | 2250 const int number_of_arguments = node->arguments()->length() + 1; |
(...skipping 16 matching lines...) Expand all Loading... | |
2250 __ pushq(RAX); | 2267 __ pushq(RAX); |
2251 } | 2268 } |
2252 } | 2269 } |
2253 | 2270 |
2254 | 2271 |
2255 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { | 2272 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { |
2256 node->arguments()->Visit(this); | 2273 node->arguments()->Visit(this); |
2257 __ LoadObject(RBX, node->function()); | 2274 __ LoadObject(RBX, node->function()); |
2258 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), | 2275 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), |
2259 node->arguments()->names())); | 2276 node->arguments()->names())); |
2260 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2277 GenerateCall(node->token_index(), |
2278 &StubCode::CallStaticFunctionLabel(), | |
2279 PcDescriptors::kFuncCall); | |
2261 __ addq(RSP, Immediate(node->arguments()->length() * kWordSize)); | 2280 __ addq(RSP, Immediate(node->arguments()->length() * kWordSize)); |
2262 // Result is in RAX. | 2281 // Result is in RAX. |
2263 if (IsResultNeeded(node)) { | 2282 if (IsResultNeeded(node)) { |
2264 __ pushq(RAX); | 2283 __ pushq(RAX); |
2265 } | 2284 } |
2266 } | 2285 } |
2267 | 2286 |
2268 | 2287 |
2269 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) { | 2288 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) { |
2270 // The spec states that the closure is evaluated before the arguments. | 2289 // The spec states that the closure is evaluated before the arguments. |
2271 // Preserve the current context, since it will be overridden by the closure | 2290 // Preserve the current context, since it will be overridden by the closure |
2272 // context during the call. | 2291 // context during the call. |
2273 __ pushq(CTX); | 2292 __ pushq(CTX); |
2274 // Compute the closure object and pass it as first argument to the stub. | 2293 // Compute the closure object and pass it as first argument to the stub. |
2275 node->closure()->Visit(this); | 2294 node->closure()->Visit(this); |
2276 // Now compute the arguments to the call. | 2295 // Now compute the arguments to the call. |
2277 node->arguments()->Visit(this); | 2296 node->arguments()->Visit(this); |
2278 // Set up the number of arguments (excluding the closure) to the ClosureCall | 2297 // Set up the number of arguments (excluding the closure) to the ClosureCall |
2279 // stub which will setup the closure context and jump to the entrypoint of the | 2298 // stub which will setup the closure context and jump to the entrypoint of the |
2280 // closure function (the function will be compiled if it has not already been | 2299 // closure function (the function will be compiled if it has not already been |
2281 // compiled). | 2300 // compiled). |
2282 // NOTE: The stub accesses the closure before the parameter list. | 2301 // NOTE: The stub accesses the closure before the parameter list. |
2283 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), | 2302 __ LoadObject(R10, ArgumentsDescriptor(node->arguments()->length(), |
2284 node->arguments()->names())); | 2303 node->arguments()->names())); |
2285 GenerateCall(node->token_index(), &StubCode::CallClosureFunctionLabel()); | 2304 GenerateCall(node->token_index(), |
2305 &StubCode::CallClosureFunctionLabel(), | |
2306 PcDescriptors::kOther); | |
2286 __ addq(RSP, Immediate((node->arguments()->length() + 1) * kWordSize)); | 2307 __ addq(RSP, Immediate((node->arguments()->length() + 1) * kWordSize)); |
2287 // Restore the context. | 2308 // Restore the context. |
2288 __ popq(CTX); | 2309 __ popq(CTX); |
2289 // Result is in RAX. | 2310 // Result is in RAX. |
2290 if (IsResultNeeded(node)) { | 2311 if (IsResultNeeded(node)) { |
2291 __ pushq(RAX); | 2312 __ pushq(RAX); |
2292 } | 2313 } |
2293 } | 2314 } |
2294 | 2315 |
2295 | 2316 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2420 const bool requires_type_arguments = true; // Always first arg to factory. | 2441 const bool requires_type_arguments = true; // Always first arg to factory. |
2421 GenerateTypeArguments(node, requires_type_arguments); | 2442 GenerateTypeArguments(node, requires_type_arguments); |
2422 // The top of stack is an instantiated AbstractTypeArguments object | 2443 // The top of stack is an instantiated AbstractTypeArguments object |
2423 // (or null). | 2444 // (or null). |
2424 int num_args = node->arguments()->length() + 1; // +1 to include type args. | 2445 int num_args = node->arguments()->length() + 1; // +1 to include type args. |
2425 node->arguments()->Visit(this); | 2446 node->arguments()->Visit(this); |
2426 // Call the factory. | 2447 // Call the factory. |
2427 __ LoadObject(RBX, node->constructor()); | 2448 __ LoadObject(RBX, node->constructor()); |
2428 __ LoadObject(R10, ArgumentsDescriptor(num_args, | 2449 __ LoadObject(R10, ArgumentsDescriptor(num_args, |
2429 node->arguments()->names())); | 2450 node->arguments()->names())); |
2430 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2451 GenerateCall(node->token_index(), |
2452 &StubCode::CallStaticFunctionLabel(), | |
2453 PcDescriptors::kFuncCall); | |
2431 // Factory constructor returns object in RAX. | 2454 // Factory constructor returns object in RAX. |
2432 __ addq(RSP, Immediate(num_args * kWordSize)); | 2455 __ addq(RSP, Immediate(num_args * kWordSize)); |
2433 if (IsResultNeeded(node)) { | 2456 if (IsResultNeeded(node)) { |
2434 __ pushq(RAX); | 2457 __ pushq(RAX); |
2435 } | 2458 } |
2436 return; | 2459 return; |
2437 } | 2460 } |
2438 | 2461 |
2439 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 2462 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
2440 const bool requires_type_arguments = cls.HasTypeArguments(); | 2463 const bool requires_type_arguments = cls.HasTypeArguments(); |
2441 GenerateTypeArguments(node, requires_type_arguments); | 2464 GenerateTypeArguments(node, requires_type_arguments); |
2442 | 2465 |
2443 // If cls is parameterized, the type arguments and the instantiator's | 2466 // If cls is parameterized, the type arguments and the instantiator's |
2444 // type arguments are on the stack. | 2467 // type arguments are on the stack. |
2445 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); | 2468 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); |
2446 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); | 2469 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); |
2447 GenerateCall(node->token_index(), &label); | 2470 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
2448 if (requires_type_arguments) { | 2471 if (requires_type_arguments) { |
2449 __ popq(RCX); // Pop type arguments. | 2472 __ popq(RCX); // Pop type arguments. |
2450 __ popq(RCX); // Pop instantiator type arguments. | 2473 __ popq(RCX); // Pop instantiator type arguments. |
2451 } | 2474 } |
2452 | 2475 |
2453 if (IsResultNeeded(node)) { | 2476 if (IsResultNeeded(node)) { |
2454 __ pushq(RAX); // Set up return value from allocate. | 2477 __ pushq(RAX); // Set up return value from allocate. |
2455 } | 2478 } |
2456 | 2479 |
2457 // First argument(this) for constructor call which follows. | 2480 // First argument(this) for constructor call which follows. |
2458 __ pushq(RAX); | 2481 __ pushq(RAX); |
2459 // Second argument is the implicit construction phase parameter. | 2482 // Second argument is the implicit construction phase parameter. |
2460 // Run both the constructor initializer list and the constructor body. | 2483 // Run both the constructor initializer list and the constructor body. |
2461 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); | 2484 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
2462 | 2485 |
2463 | 2486 |
2464 // Now setup rest of the arguments for the constructor call. | 2487 // Now setup rest of the arguments for the constructor call. |
2465 node->arguments()->Visit(this); | 2488 node->arguments()->Visit(this); |
2466 | 2489 |
2467 // Call the constructor. | 2490 // Call the constructor. |
2468 // +2 to include implicit receiver and phase arguments. | 2491 // +2 to include implicit receiver and phase arguments. |
2469 int num_args = node->arguments()->length() + 2; | 2492 int num_args = node->arguments()->length() + 2; |
2470 __ LoadObject(RBX, node->constructor()); | 2493 __ LoadObject(RBX, node->constructor()); |
2471 __ LoadObject(R10, ArgumentsDescriptor(num_args, node->arguments()->names())); | 2494 __ LoadObject(R10, ArgumentsDescriptor(num_args, node->arguments()->names())); |
2472 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 2495 GenerateCall(node->token_index(), |
2496 &StubCode::CallStaticFunctionLabel(), | |
2497 PcDescriptors::kFuncCall); | |
2473 // Constructors do not return any value. | 2498 // Constructors do not return any value. |
2474 | 2499 |
2475 // Pop out all the other arguments on the stack. | 2500 // Pop out all the other arguments on the stack. |
2476 __ addq(RSP, Immediate(num_args * kWordSize)); | 2501 __ addq(RSP, Immediate(num_args * kWordSize)); |
2477 } | 2502 } |
2478 | 2503 |
2479 | 2504 |
2480 // Expects receiver on stack, returns result in RAX.. | 2505 // Expects receiver on stack, returns result in RAX.. |
2481 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, | 2506 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, |
2482 intptr_t token_index, | 2507 intptr_t token_index, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2556 const Function& function = | 2581 const Function& function = |
2557 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name)); | 2582 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name)); |
2558 if (function.IsNull()) { | 2583 if (function.IsNull()) { |
2559 ErrorMsg(token_index, "Static getter does not exist: %s", | 2584 ErrorMsg(token_index, "Static getter does not exist: %s", |
2560 getter_name.ToCString()); | 2585 getter_name.ToCString()); |
2561 } | 2586 } |
2562 __ LoadObject(RBX, function); | 2587 __ LoadObject(RBX, function); |
2563 const int kNumberOfArguments = 0; | 2588 const int kNumberOfArguments = 0; |
2564 const Array& kNoArgumentNames = Array::Handle(); | 2589 const Array& kNoArgumentNames = Array::Handle(); |
2565 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); | 2590 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); |
2566 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); | 2591 GenerateCall(token_index, |
2592 &StubCode::CallStaticFunctionLabel(), | |
2593 PcDescriptors::kFuncCall); | |
2567 // No arguments were pushed, hence nothing to pop. | 2594 // No arguments were pushed, hence nothing to pop. |
2568 } | 2595 } |
2569 | 2596 |
2570 | 2597 |
2571 // Call to static getter. | 2598 // Call to static getter. |
2572 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) { | 2599 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) { |
2573 GenerateStaticGetterCall(node->token_index(), | 2600 GenerateStaticGetterCall(node->token_index(), |
2574 node->cls(), | 2601 node->cls(), |
2575 node->field_name()); | 2602 node->field_name()); |
2576 // Result is in RAX. | 2603 // Result is in RAX. |
2577 if (IsResultNeeded(node)) { | 2604 if (IsResultNeeded(node)) { |
2578 __ pushq(RAX); | 2605 __ pushq(RAX); |
2579 } | 2606 } |
2580 } | 2607 } |
2581 | 2608 |
2582 | 2609 |
2583 // Expects value on stack. | 2610 // Expects value on stack. |
2584 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index, | 2611 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index, |
2585 const Class& field_class, | 2612 const Class& field_class, |
2586 const String& field_name) { | 2613 const String& field_name) { |
2587 const String& setter_name = String::Handle(Field::SetterName(field_name)); | 2614 const String& setter_name = String::Handle(Field::SetterName(field_name)); |
2588 const Function& function = | 2615 const Function& function = |
2589 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name)); | 2616 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name)); |
2590 __ LoadObject(RBX, function); | 2617 __ LoadObject(RBX, function); |
2591 const int kNumberOfArguments = 1; // value. | 2618 const int kNumberOfArguments = 1; // value. |
2592 const Array& kNoArgumentNames = Array::Handle(); | 2619 const Array& kNoArgumentNames = Array::Handle(); |
2593 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); | 2620 __ LoadObject(R10, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); |
2594 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); | 2621 GenerateCall(token_index, |
2622 &StubCode::CallStaticFunctionLabel(), | |
2623 PcDescriptors::kFuncCall); | |
2595 __ addq(RSP, Immediate(kNumberOfArguments * kWordSize)); | 2624 __ addq(RSP, Immediate(kNumberOfArguments * kWordSize)); |
2596 } | 2625 } |
2597 | 2626 |
2598 | 2627 |
2599 // The call to static setter implements assignment to a static field. | 2628 // The call to static setter implements assignment to a static field. |
2600 // The result of the assignment is the value being stored. | 2629 // The result of the assignment is the value being stored. |
2601 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) { | 2630 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) { |
2602 node->value()->Visit(this); | 2631 node->value()->Visit(this); |
2603 if (IsResultNeeded(node)) { | 2632 if (IsResultNeeded(node)) { |
2604 // Preserve the original value when returning from setter. | 2633 // Preserve the original value when returning from setter. |
(...skipping 12 matching lines...) Expand all Loading... | |
2617 // Push the result place holder initialized to NULL. | 2646 // Push the result place holder initialized to NULL. |
2618 __ PushObject(Object::ZoneHandle()); | 2647 __ PushObject(Object::ZoneHandle()); |
2619 // Pass a pointer to the first argument in RAX. | 2648 // Pass a pointer to the first argument in RAX. |
2620 if (!node->has_optional_parameters()) { | 2649 if (!node->has_optional_parameters()) { |
2621 __ leaq(RAX, Address(RBP, (1 + node->argument_count()) * kWordSize)); | 2650 __ leaq(RAX, Address(RBP, (1 + node->argument_count()) * kWordSize)); |
2622 } else { | 2651 } else { |
2623 __ leaq(RAX, Address(RBP, -1 * kWordSize)); | 2652 __ leaq(RAX, Address(RBP, -1 * kWordSize)); |
2624 } | 2653 } |
2625 __ movq(RBX, Immediate(reinterpret_cast<uword>(node->native_c_function()))); | 2654 __ movq(RBX, Immediate(reinterpret_cast<uword>(node->native_c_function()))); |
2626 __ movq(R10, Immediate(node->argument_count())); | 2655 __ movq(R10, Immediate(node->argument_count())); |
2627 GenerateCall(node->token_index(), &StubCode::CallNativeCFunctionLabel()); | 2656 GenerateCall(node->token_index(), |
2657 &StubCode::CallNativeCFunctionLabel(), | |
2658 PcDescriptors::kOther); | |
2628 // Result is on the stack. | 2659 // Result is on the stack. |
2629 if (!IsResultNeeded(node)) { | 2660 if (!IsResultNeeded(node)) { |
2630 __ popq(RAX); | 2661 __ popq(RAX); |
2631 } | 2662 } |
2632 } | 2663 } |
2633 | 2664 |
2634 | 2665 |
2635 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { | 2666 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { |
2636 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2667 // NOTE: The implicit variables ':saved_context', ':exception_var' |
2637 // and ':stacktrace_var' can never be captured variables. | 2668 // and ':stacktrace_var' can never be captured variables. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2743 GenerateLoadVariable(CTX, node->context_var()); | 2774 GenerateLoadVariable(CTX, node->context_var()); |
2744 node->finally_block()->Visit(this); | 2775 node->finally_block()->Visit(this); |
2745 | 2776 |
2746 if (try_index >= 0) { | 2777 if (try_index >= 0) { |
2747 state()->set_try_index(try_index); | 2778 state()->set_try_index(try_index); |
2748 } | 2779 } |
2749 } | 2780 } |
2750 | 2781 |
2751 | 2782 |
2752 void CodeGenerator::GenerateCall(intptr_t token_index, | 2783 void CodeGenerator::GenerateCall(intptr_t token_index, |
2753 const ExternalLabel* ext_label) { | 2784 const ExternalLabel* ext_label, |
2785 PcDescriptors::Kind desc_kind) { | |
2754 __ call(ext_label); | 2786 __ call(ext_label); |
2755 AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kNoId, token_index); | 2787 AddCurrentDescriptor(desc_kind, AstNode::kNoId, token_index); |
2756 } | 2788 } |
2757 | 2789 |
2758 | 2790 |
2759 void CodeGenerator::GenerateCallRuntime(intptr_t node_id, | 2791 void CodeGenerator::GenerateCallRuntime(intptr_t node_id, |
2760 intptr_t token_index, | 2792 intptr_t token_index, |
2761 const RuntimeEntry& entry) { | 2793 const RuntimeEntry& entry) { |
2762 __ CallRuntimeFromDart(entry); | 2794 __ CallRuntimeFromDart(entry); |
2763 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); | 2795 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); |
2764 } | 2796 } |
2765 | 2797 |
(...skipping 25 matching lines...) Expand all Loading... | |
2791 const Error& error = Error::Handle( | 2823 const Error& error = Error::Handle( |
2792 Parser::FormatError(script, token_index, "Error", format, args)); | 2824 Parser::FormatError(script, token_index, "Error", format, args)); |
2793 va_end(args); | 2825 va_end(args); |
2794 Isolate::Current()->long_jump_base()->Jump(1, error); | 2826 Isolate::Current()->long_jump_base()->Jump(1, error); |
2795 UNREACHABLE(); | 2827 UNREACHABLE(); |
2796 } | 2828 } |
2797 | 2829 |
2798 } // namespace dart | 2830 } // namespace dart |
2799 | 2831 |
2800 #endif // defined TARGET_ARCH_X64 | 2832 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |