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

Side by Side Diff: runtime/vm/code_generator_x64.cc

Issue 9460012: StepOver, StepInto, StepOut (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698