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

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

Issue 10014006: Try/catch in graph builder. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 13 matching lines...) Expand all
24 24
25 FlowGraphCompiler::FlowGraphCompiler( 25 FlowGraphCompiler::FlowGraphCompiler(
26 Assembler* assembler, 26 Assembler* assembler,
27 const ParsedFunction& parsed_function, 27 const ParsedFunction& parsed_function,
28 const GrowableArray<BlockEntryInstr*>& block_order) 28 const GrowableArray<BlockEntryInstr*>& block_order)
29 : FlowGraphVisitor(block_order), 29 : FlowGraphVisitor(block_order),
30 assembler_(assembler), 30 assembler_(assembler),
31 parsed_function_(parsed_function), 31 parsed_function_(parsed_function),
32 block_info_(block_order.length()), 32 block_info_(block_order.length()),
33 current_block_(NULL), 33 current_block_(NULL),
34 pc_descriptors_list_(new DescriptorList()) { 34 pc_descriptors_list_(new DescriptorList()),
35 exception_handlers_list_(new ExceptionHandlerList()) {
35 for (int i = 0; i < block_order.length(); ++i) { 36 for (int i = 0; i < block_order.length(); ++i) {
36 block_info_.Add(new BlockInfo()); 37 block_info_.Add(new BlockInfo());
37 } 38 }
38 } 39 }
39 40
40 41
41 FlowGraphCompiler::~FlowGraphCompiler() { 42 FlowGraphCompiler::~FlowGraphCompiler() {
42 // BlockInfos are zone-allocated, so their destructors are not called. 43 // BlockInfos are zone-allocated, so their destructors are not called.
43 // Verify the labels explicitly here. 44 // Verify the labels explicitly here.
44 for (int i = 0; i < block_info_.length(); ++i) { 45 for (int i = 0; i < block_info_.length(); ++i) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 static bool VerifyValues(Value* v1, Value* v2) { 133 static bool VerifyValues(Value* v1, Value* v2) {
133 if (v1->IsTemp() && v2->IsTemp()) { 134 if (v1->IsTemp() && v2->IsTemp()) {
134 return (v1->AsTemp()->index() + 1) == v2->AsTemp()->index(); 135 return (v1->AsTemp()->index() + 1) == v2->AsTemp()->index();
135 } 136 }
136 return true; 137 return true;
137 } 138 }
138 139
139 140
140 void FlowGraphCompiler::EmitInstanceCall(intptr_t node_id, 141 void FlowGraphCompiler::EmitInstanceCall(intptr_t node_id,
141 intptr_t token_index, 142 intptr_t token_index,
143 intptr_t try_index,
142 const String& function_name, 144 const String& function_name,
143 intptr_t argument_count, 145 intptr_t argument_count,
144 const Array& argument_names, 146 const Array& argument_names,
145 intptr_t checked_argument_count) { 147 intptr_t checked_argument_count) {
146 ICData& ic_data = 148 ICData& ic_data =
147 ICData::ZoneHandle(ICData::New(parsed_function_.function(), 149 ICData::ZoneHandle(ICData::New(parsed_function_.function(),
148 function_name, 150 function_name,
149 node_id, 151 node_id,
150 checked_argument_count)); 152 checked_argument_count));
151 const Array& arguments_descriptor = 153 const Array& arguments_descriptor =
152 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); 154 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
153 __ LoadObject(RBX, ic_data); 155 __ LoadObject(RBX, ic_data);
154 __ LoadObject(R10, arguments_descriptor); 156 __ LoadObject(R10, arguments_descriptor);
155 157
156 uword label_address = 0; 158 uword label_address = 0;
157 switch (checked_argument_count) { 159 switch (checked_argument_count) {
158 case 1: 160 case 1:
159 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); 161 label_address = StubCode::OneArgCheckInlineCacheEntryPoint();
160 break; 162 break;
161 case 2: 163 case 2:
162 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); 164 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint();
163 break; 165 break;
164 default: 166 default:
165 UNIMPLEMENTED(); 167 UNIMPLEMENTED();
166 } 168 }
167 ExternalLabel target_label("InlineCache", label_address); 169 ExternalLabel target_label("InlineCache", label_address);
168 __ call(&target_label); 170 __ call(&target_label);
169 AddCurrentDescriptor(PcDescriptors::kIcCall, node_id, token_index); 171 AddCurrentDescriptor(PcDescriptors::kIcCall, node_id, token_index, try_index);
170 __ addq(RSP, Immediate(argument_count * kWordSize)); 172 __ addq(RSP, Immediate(argument_count * kWordSize));
171 } 173 }
172 174
173 175
174 void FlowGraphCompiler::EmitStaticCall(intptr_t token_index, 176 void FlowGraphCompiler::EmitStaticCall(intptr_t token_index,
177 intptr_t try_index,
175 const Function& function, 178 const Function& function,
176 intptr_t argument_count, 179 intptr_t argument_count,
177 const Array& argument_names) { 180 const Array& argument_names) {
178 const Array& arguments_descriptor = 181 const Array& arguments_descriptor =
179 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); 182 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
180 __ LoadObject(RBX, function); 183 __ LoadObject(RBX, function);
181 __ LoadObject(R10, arguments_descriptor); 184 __ LoadObject(R10, arguments_descriptor);
182 185
183 GenerateCall(token_index, 186 GenerateCall(token_index,
187 try_index,
184 &StubCode::CallStaticFunctionLabel(), 188 &StubCode::CallStaticFunctionLabel(),
185 PcDescriptors::kFuncCall); 189 PcDescriptors::kFuncCall);
186 __ addq(RSP, Immediate(argument_count * kWordSize)); 190 __ addq(RSP, Immediate(argument_count * kWordSize));
187 } 191 }
188 192
189 193
190 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) { 194 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) {
191 __ movq(RAX, CTX); 195 __ movq(RAX, CTX);
192 } 196 }
193 197
194 198
195 void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) { 199 void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) {
196 LoadValue(CTX, comp->value()); 200 LoadValue(CTX, comp->value());
197 } 201 }
198 202
199 203
200 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) { 204 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) {
201 ASSERT(comp->context()->IsTemp()); 205 ASSERT(comp->context()->IsTemp());
202 ASSERT(VerifyCallComputation(comp)); 206 ASSERT(VerifyCallComputation(comp));
203 // The arguments to the stub include the closure. The arguments 207 // The arguments to the stub include the closure. The arguments
204 // descriptor describes the closure's arguments (and so does not include 208 // descriptor describes the closure's arguments (and so does not include
205 // the closure). 209 // the closure).
206 int argument_count = comp->ArgumentCount(); 210 int argument_count = comp->ArgumentCount();
207 const Array& arguments_descriptor = 211 const Array& arguments_descriptor =
208 CodeGenerator::ArgumentsDescriptor(argument_count - 1, 212 CodeGenerator::ArgumentsDescriptor(argument_count - 1,
209 comp->argument_names()); 213 comp->argument_names());
210 __ LoadObject(R10, arguments_descriptor); 214 __ LoadObject(R10, arguments_descriptor);
211 215
212 GenerateCall(comp->token_index(), 216 GenerateCall(comp->token_index(),
217 comp->try_index(),
213 &StubCode::CallClosureFunctionLabel(), 218 &StubCode::CallClosureFunctionLabel(),
214 PcDescriptors::kOther); 219 PcDescriptors::kOther);
215 __ addq(RSP, Immediate(argument_count * kWordSize)); 220 __ addq(RSP, Immediate(argument_count * kWordSize));
216 __ popq(CTX); 221 __ popq(CTX);
217 } 222 }
218 223
219 224
220 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { 225 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) {
221 ASSERT(VerifyCallComputation(comp)); 226 ASSERT(VerifyCallComputation(comp));
222 EmitInstanceCall(comp->node_id(), 227 EmitInstanceCall(comp->node_id(),
223 comp->token_index(), 228 comp->token_index(),
229 comp->try_index(),
224 comp->function_name(), 230 comp->function_name(),
225 comp->ArgumentCount(), 231 comp->ArgumentCount(),
226 comp->argument_names(), 232 comp->argument_names(),
227 comp->checked_argument_count()); 233 comp->checked_argument_count());
228 } 234 }
229 235
230 236
231 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { 237 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) {
232 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 238 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
233 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 239 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
(...skipping 10 matching lines...) Expand all
244 __ jmp(&done, Assembler::kNearJump); 250 __ jmp(&done, Assembler::kNearJump);
245 __ Bind(&load_true); 251 __ Bind(&load_true);
246 __ LoadObject(RAX, bool_true); 252 __ LoadObject(RAX, bool_true);
247 __ Bind(&done); 253 __ Bind(&done);
248 } 254 }
249 255
250 256
251 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) { 257 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) {
252 ASSERT(VerifyCallComputation(comp)); 258 ASSERT(VerifyCallComputation(comp));
253 EmitStaticCall(comp->token_index(), 259 EmitStaticCall(comp->token_index(),
260 comp->try_index(),
254 comp->function(), 261 comp->function(),
255 comp->ArgumentCount(), 262 comp->ArgumentCount(),
256 comp->argument_names()); 263 comp->argument_names());
257 } 264 }
258 265
259 266
260 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { 267 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) {
261 if (comp->local().is_captured()) { 268 if (comp->local().is_captured()) {
262 // The variable lives in the context. 269 // The variable lives in the context.
263 intptr_t delta = comp->context_level() - 270 intptr_t delta = comp->context_level() -
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 __ PushObject(Object::ZoneHandle()); 314 __ PushObject(Object::ZoneHandle());
308 // Pass a pointer to the first argument in RAX. 315 // Pass a pointer to the first argument in RAX.
309 if (!comp->has_optional_parameters()) { 316 if (!comp->has_optional_parameters()) {
310 __ leaq(RAX, Address(RBP, (1 + comp->argument_count()) * kWordSize)); 317 __ leaq(RAX, Address(RBP, (1 + comp->argument_count()) * kWordSize));
311 } else { 318 } else {
312 __ leaq(RAX, Address(RBP, -1 * kWordSize)); 319 __ leaq(RAX, Address(RBP, -1 * kWordSize));
313 } 320 }
314 __ movq(RBX, Immediate(reinterpret_cast<uword>(comp->native_c_function()))); 321 __ movq(RBX, Immediate(reinterpret_cast<uword>(comp->native_c_function())));
315 __ movq(R10, Immediate(comp->argument_count())); 322 __ movq(R10, Immediate(comp->argument_count()));
316 GenerateCall(comp->token_index(), 323 GenerateCall(comp->token_index(),
324 comp->try_index(),
317 &StubCode::CallNativeCFunctionLabel(), 325 &StubCode::CallNativeCFunctionLabel(),
318 PcDescriptors::kOther); 326 PcDescriptors::kOther);
319 __ popq(RAX); 327 __ popq(RAX);
320 } 328 }
321 329
322 330
323 void FlowGraphCompiler::VisitLoadInstanceField(LoadInstanceFieldComp* comp) { 331 void FlowGraphCompiler::VisitLoadInstanceField(LoadInstanceFieldComp* comp) {
324 LoadValue(RAX, comp->instance()); 332 LoadValue(RAX, comp->instance());
325 __ movq(RAX, FieldAddress(RAX, comp->field().Offset())); 333 __ movq(RAX, FieldAddress(RAX, comp->field().Offset()));
326 } 334 }
(...skipping 28 matching lines...) Expand all
355 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 363 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
356 364
357 // Insert a copy of the third (last) argument under the arguments. 365 // Insert a copy of the third (last) argument under the arguments.
358 __ popq(RAX); // Value. 366 __ popq(RAX); // Value.
359 __ popq(RBX); // Index. 367 __ popq(RBX); // Index.
360 __ popq(RCX); // Receiver. 368 __ popq(RCX); // Receiver.
361 __ pushq(RAX); 369 __ pushq(RAX);
362 __ pushq(RCX); 370 __ pushq(RCX);
363 __ pushq(RBX); 371 __ pushq(RBX);
364 __ pushq(RAX); 372 __ pushq(RAX);
365 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 3, 373 EmitInstanceCall(comp->node_id(),
366 Array::ZoneHandle(), 1); 374 comp->token_index(),
375 comp->try_index(),
376 function_name,
377 3,
378 Array::ZoneHandle(),
379 1);
367 __ popq(RAX); 380 __ popq(RAX);
368 } 381 }
369 382
370 383
371 void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) { 384 void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) {
372 // Preserve the second argument under the arguments as the result of the 385 // Preserve the second argument under the arguments as the result of the
373 // computation, then call the setter. 386 // computation, then call the setter.
374 const String& function_name = 387 const String& function_name =
375 String::ZoneHandle(Field::SetterSymbol(comp->field_name())); 388 String::ZoneHandle(Field::SetterSymbol(comp->field_name()));
376 389
377 // Insert a copy of the second (last) argument under the arguments. 390 // Insert a copy of the second (last) argument under the arguments.
378 __ popq(RAX); // Value. 391 __ popq(RAX); // Value.
379 __ popq(RBX); // Receiver. 392 __ popq(RBX); // Receiver.
380 __ pushq(RAX); 393 __ pushq(RAX);
381 __ pushq(RBX); 394 __ pushq(RBX);
382 __ pushq(RAX); 395 __ pushq(RAX);
383 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2, 396 EmitInstanceCall(comp->node_id(),
384 Array::ZoneHandle(), 1); 397 comp->token_index(),
398 comp->try_index(),
399 function_name,
400 2,
401 Array::ZoneHandle(),
402 1);
385 __ popq(RAX); 403 __ popq(RAX);
386 } 404 }
387 405
388 406
389 void FlowGraphCompiler::VisitStaticSetter(StaticSetterComp* comp) { 407 void FlowGraphCompiler::VisitStaticSetter(StaticSetterComp* comp) {
390 // Preserve the argument as the result of the computation, 408 // Preserve the argument as the result of the computation,
391 // then call the setter. 409 // then call the setter.
392 410
393 // Duplicate the argument. 411 // Duplicate the argument.
394 __ movq(RAX, Address(RSP, 0)); 412 __ movq(RAX, Address(RSP, 0));
395 __ pushq(RAX); 413 __ pushq(RAX);
396 EmitStaticCall(comp->token_index(), comp->setter_function(), 1, 414 EmitStaticCall(comp->token_index(),
415 comp->try_index(),
416 comp->setter_function(),
417 1,
397 Array::ZoneHandle()); 418 Array::ZoneHandle());
398 __ popq(RAX); 419 __ popq(RAX);
399 } 420 }
400 421
401 422
402 void FlowGraphCompiler::VisitBooleanNegate(BooleanNegateComp* comp) { 423 void FlowGraphCompiler::VisitBooleanNegate(BooleanNegateComp* comp) {
403 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 424 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
404 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 425 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
405 Label done; 426 Label done;
406 LoadValue(RDX, comp->value()); 427 LoadValue(RDX, comp->value());
(...skipping 25 matching lines...) Expand all
432 // - NULL -> return false. 453 // - NULL -> return false.
433 // - Smi -> compile time subtype check (only if dst class is not parameterized). 454 // - Smi -> compile time subtype check (only if dst class is not parameterized).
434 // - Class equality (only if class is not parameterized). 455 // - Class equality (only if class is not parameterized).
435 // Inputs: 456 // Inputs:
436 // - RAX: object. 457 // - RAX: object.
437 // Destroys RCX. 458 // Destroys RCX.
438 // Returns: 459 // Returns:
439 // - true or false in RAX. 460 // - true or false in RAX.
440 void FlowGraphCompiler::GenerateInstanceOf(intptr_t node_id, 461 void FlowGraphCompiler::GenerateInstanceOf(intptr_t node_id,
441 intptr_t token_index, 462 intptr_t token_index,
463 intptr_t try_index,
442 const AbstractType& type, 464 const AbstractType& type,
443 bool negate_result) { 465 bool negate_result) {
444 ASSERT(type.IsFinalized() && !type.IsMalformed()); 466 ASSERT(type.IsFinalized() && !type.IsMalformed());
445 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 467 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
446 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 468 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
447 469
448 // All instances are of a subtype of the Object type. 470 // All instances are of a subtype of the Object type.
449 const Type& object_type = 471 const Type& object_type =
450 Type::Handle(Isolate::Current()->object_store()->object_type()); 472 Type::Handle(Isolate::Current()->object_store()->object_type());
451 Error& malformed_error = Error::Handle(); 473 Error& malformed_error = Error::Handle();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 Immediate(reinterpret_cast<int64_t>(Smi::New(node_id))); 582 Immediate(reinterpret_cast<int64_t>(Smi::New(node_id)));
561 __ pushq(location); // Push the source location. 583 __ pushq(location); // Push the source location.
562 __ pushq(node_id_as_smi); 584 __ pushq(node_id_as_smi);
563 __ pushq(RAX); // Push the instance. 585 __ pushq(RAX); // Push the instance.
564 __ PushObject(type); // Push the type. 586 __ PushObject(type); // Push the type.
565 if (!type.IsInstantiated()) { 587 if (!type.IsInstantiated()) {
566 GenerateInstantiatorTypeArguments(token_index); 588 GenerateInstantiatorTypeArguments(token_index);
567 } else { 589 } else {
568 __ pushq(raw_null); // Null instantiator. 590 __ pushq(raw_null); // Null instantiator.
569 } 591 }
570 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); 592 GenerateCallRuntime(node_id, token_index, try_index, kInstanceofRuntimeEntry);
571 // Pop the two parameters supplied to the runtime entry. The result of the 593 // Pop the two parameters supplied to the runtime entry. The result of the
572 // instanceof runtime call will be left as the result of the operation. 594 // instanceof runtime call will be left as the result of the operation.
573 __ addq(RSP, Immediate(5 * kWordSize)); 595 __ addq(RSP, Immediate(5 * kWordSize));
574 if (negate_result) { 596 if (negate_result) {
575 Label negate_done; 597 Label negate_done;
576 __ popq(RDX); 598 __ popq(RDX);
577 __ LoadObject(RAX, bool_true); 599 __ LoadObject(RAX, bool_true);
578 __ cmpq(RDX, RAX); 600 __ cmpq(RDX, RAX);
579 __ j(NOT_EQUAL, &negate_done, Assembler::kNearJump); 601 __ j(NOT_EQUAL, &negate_done, Assembler::kNearJump);
580 __ LoadObject(RAX, bool_false); 602 __ LoadObject(RAX, bool_false);
581 __ Bind(&negate_done); 603 __ Bind(&negate_done);
582 __ pushq(RAX); 604 __ pushq(RAX);
583 } 605 }
584 __ Bind(&done); 606 __ Bind(&done);
585 __ popq(RAX); 607 __ popq(RAX);
586 } 608 }
587 609
588 610
589 void FlowGraphCompiler::VisitInstanceOf(InstanceOfComp* comp) { 611 void FlowGraphCompiler::VisitInstanceOf(InstanceOfComp* comp) {
590 __ popq(RAX); 612 __ popq(RAX);
591 GenerateInstanceOf(comp->node_id(), 613 GenerateInstanceOf(comp->node_id(),
592 comp->token_index(), 614 comp->token_index(),
615 comp->try_index(),
593 comp->type(), 616 comp->type(),
594 comp->negate_result()); 617 comp->negate_result());
595 } 618 }
596 619
597 620
598 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) { 621 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) {
599 const Class& cls = Class::ZoneHandle(comp->constructor().owner()); 622 const Class& cls = Class::ZoneHandle(comp->constructor().owner());
600 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 623 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
601 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 624 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
602 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); 625 GenerateCall(comp->token_index(), comp->try_index(), &label,
626 PcDescriptors::kOther);
603 for (intptr_t i = 0; i < comp->arguments().length(); i++) { 627 for (intptr_t i = 0; i < comp->arguments().length(); i++) {
604 __ popq(RCX); // Discard allocation argument 628 __ popq(RCX); // Discard allocation argument
605 } 629 }
606 } 630 }
607 631
608 632
609 void FlowGraphCompiler::VisitCreateArray(CreateArrayComp* comp) { 633 void FlowGraphCompiler::VisitCreateArray(CreateArrayComp* comp) {
610 // 1. Allocate the array. R10 = length, RBX = element type. 634 // 1. Allocate the array. R10 = length, RBX = element type.
611 __ movq(R10, Immediate(Smi::RawValue(comp->ElementCount()))); 635 __ movq(R10, Immediate(Smi::RawValue(comp->ElementCount())));
612 const AbstractTypeArguments& element_type = comp->type_arguments(); 636 const AbstractTypeArguments& element_type = comp->type_arguments();
613 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); 637 ASSERT(element_type.IsNull() || element_type.IsInstantiated());
614 __ LoadObject(RBX, element_type); 638 __ LoadObject(RBX, element_type);
615 GenerateCall(comp->token_index(), 639 GenerateCall(comp->token_index(),
640 comp->try_index(),
616 &StubCode::AllocateArrayLabel(), 641 &StubCode::AllocateArrayLabel(),
617 PcDescriptors::kOther); 642 PcDescriptors::kOther);
618 643
619 // 2. Initialize the array in RAX with the element values. 644 // 2. Initialize the array in RAX with the element values.
620 __ leaq(RCX, FieldAddress(RAX, Array::data_offset())); 645 __ leaq(RCX, FieldAddress(RAX, Array::data_offset()));
621 for (int i = comp->ElementCount() - 1; i >= 0; --i) { 646 for (int i = comp->ElementCount() - 1; i >= 0; --i) {
622 if (comp->ElementAt(i)->IsTemp()) { 647 if (comp->ElementAt(i)->IsTemp()) {
623 __ popq(Address(RCX, i * kWordSize)); 648 __ popq(Address(RCX, i * kWordSize));
624 } else { 649 } else {
625 LoadValue(RDX, comp->ElementAt(i)); 650 LoadValue(RDX, comp->ElementAt(i));
626 __ movq(Address(RCX, i * kWordSize), RDX); 651 __ movq(Address(RCX, i * kWordSize), RDX);
627 } 652 }
628 } 653 }
629 } 654 }
630 655
631 656
632 void FlowGraphCompiler::VisitCreateClosure(CreateClosureComp* comp) { 657 void FlowGraphCompiler::VisitCreateClosure(CreateClosureComp* comp) {
633 const Function& function = comp->function(); 658 const Function& function = comp->function();
634 const Code& stub = Code::Handle( 659 const Code& stub = Code::Handle(
635 StubCode::GetAllocationStubForClosure(function)); 660 StubCode::GetAllocationStubForClosure(function));
636 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); 661 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
637 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); 662 GenerateCall(comp->token_index(), comp->try_index(), &label,
663 PcDescriptors::kOther);
638 664
639 const Class& cls = Class::Handle(function.signature_class()); 665 const Class& cls = Class::Handle(function.signature_class());
640 if (cls.HasTypeArguments()) { 666 if (cls.HasTypeArguments()) {
641 __ popq(RCX); // Discard type arguments. 667 __ popq(RCX); // Discard type arguments.
642 } 668 }
643 if (function.IsImplicitInstanceClosureFunction()) { 669 if (function.IsImplicitInstanceClosureFunction()) {
644 __ popq(RCX); // Discard receiver. 670 __ popq(RCX); // Discard receiver.
645 } 671 }
646 } 672 }
647 673
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 711 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
686 __ Bind(&type_arguments_uninstantiated); 712 __ Bind(&type_arguments_uninstantiated);
687 } 713 }
688 // A runtime call to instantiate the type arguments is required before 714 // A runtime call to instantiate the type arguments is required before
689 // calling the factory. 715 // calling the factory.
690 __ PushObject(Object::ZoneHandle()); // Make room for the result. 716 __ PushObject(Object::ZoneHandle()); // Make room for the result.
691 __ PushObject(comp->type_arguments()); 717 __ PushObject(comp->type_arguments());
692 __ pushq(RAX); // Push instantiator type arguments. 718 __ pushq(RAX); // Push instantiator type arguments.
693 GenerateCallRuntime(comp->node_id(), 719 GenerateCallRuntime(comp->node_id(),
694 comp->token_index(), 720 comp->token_index(),
721 comp->try_index(),
695 kInstantiateTypeArgumentsRuntimeEntry); 722 kInstantiateTypeArgumentsRuntimeEntry);
696 __ popq(RAX); // Pop instantiator type arguments. 723 __ popq(RAX); // Pop instantiator type arguments.
697 __ popq(RAX); // Pop uninstantiated type arguments. 724 __ popq(RAX); // Pop uninstantiated type arguments.
698 __ popq(RAX); // Pop instantiated type arguments. 725 __ popq(RAX); // Pop instantiated type arguments.
699 __ Bind(&type_arguments_instantiated); 726 __ Bind(&type_arguments_instantiated);
700 // RAX: Instantiated type arguments. 727 // RAX: Instantiated type arguments.
701 } 728 }
702 729
703 730
704 void FlowGraphCompiler::VisitExtractConstructorTypeArguments( 731 void FlowGraphCompiler::VisitExtractConstructorTypeArguments(
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 } 821 }
795 __ Bind(&done); 822 __ Bind(&done);
796 // RAX: instantiator or kNoInstantiator. 823 // RAX: instantiator or kNoInstantiator.
797 } 824 }
798 825
799 826
800 void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) { 827 void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) {
801 __ movq(R10, Immediate(comp->num_context_variables())); 828 __ movq(R10, Immediate(comp->num_context_variables()));
802 const ExternalLabel label("alloc_context", 829 const ExternalLabel label("alloc_context",
803 StubCode::AllocateContextEntryPoint()); 830 StubCode::AllocateContextEntryPoint());
804 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); 831 GenerateCall(comp->token_index(), comp->try_index(), &label,
832 PcDescriptors::kOther);
805 } 833 }
806 834
807 835
808 void FlowGraphCompiler::VisitChainContext(ChainContextComp* comp) { 836 void FlowGraphCompiler::VisitChainContext(ChainContextComp* comp) {
809 __ popq(RAX); 837 __ popq(RAX);
810 // Chain the new context in RAX to its parent in CTX. 838 // Chain the new context in RAX to its parent in CTX.
811 __ StoreIntoObject(RAX, 839 __ StoreIntoObject(RAX,
812 FieldAddress(RAX, Context::parent_offset()), 840 FieldAddress(RAX, Context::parent_offset()),
813 CTX); 841 CTX);
814 // Set new context as current context. 842 // Set new context as current context.
815 __ movq(CTX, RAX); 843 __ movq(CTX, RAX);
816 } 844 }
817 845
818 846
819 void FlowGraphCompiler::VisitCloneContext(CloneContextComp* comp) { 847 void FlowGraphCompiler::VisitCloneContext(CloneContextComp* comp) {
820 __ popq(RAX); // Get context value from stack. 848 __ popq(RAX); // Get context value from stack.
821 __ PushObject(Object::ZoneHandle()); // Make room for the result. 849 __ PushObject(Object::ZoneHandle()); // Make room for the result.
822 __ pushq(RAX); 850 __ pushq(RAX);
823 GenerateCallRuntime(comp->node_id(), 851 GenerateCallRuntime(comp->node_id(),
824 comp->token_index(), 852 comp->token_index(),
853 comp->try_index(),
825 kCloneContextRuntimeEntry); 854 kCloneContextRuntimeEntry);
826 __ popq(RAX); // Remove argument. 855 __ popq(RAX); // Remove argument.
827 __ popq(RAX); // Get result (cloned context). 856 __ popq(RAX); // Get result (cloned context).
828 } 857 }
829 858
830 859
860 // Restore stack and initialize the two exception variables:
861 // exception and stack trace variables.
862 void FlowGraphCompiler::VisitCatchEntry(CatchEntryComp* comp) {
863 // Restore RSP from RBP as we are coming from a throw and the code for
864 // popping arguments has not been run.
865 const intptr_t locals_space_size = StackSize() * kWordSize;
866 ASSERT(locals_space_size >= 0);
867 __ movq(RSP, RBP);
868 __ subq(RSP, Immediate(locals_space_size));
869
870 ASSERT(!comp->exception_var().is_captured());
871 ASSERT(!comp->stacktrace_var().is_captured());
872 __ movq(Address(RBP, comp->exception_var().index() * kWordSize),
873 kExceptionObjectReg);
874 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize),
875 kStackTraceObjectReg);
876 }
877
878
831 void FlowGraphCompiler::VisitBlocks() { 879 void FlowGraphCompiler::VisitBlocks() {
832 for (intptr_t i = 0; i < block_order_.length(); ++i) { 880 for (intptr_t i = 0; i < block_order_.length(); ++i) {
833 // Compile the block entry. 881 // Compile the block entry.
834 current_block_ = block_order_[i]; 882 current_block_ = block_order_[i];
835 Instruction* instr = current_block()->Accept(this); 883 Instruction* instr = current_block()->Accept(this);
836 // Compile all successors until an exit, branch, or a block entry. 884 // Compile all successors until an exit, branch, or a block entry.
837 while ((instr != NULL) && !instr->IsBlockEntry()) { 885 while ((instr != NULL) && !instr->IsBlockEntry()) {
838 instr = instr->Accept(this); 886 instr = instr->Accept(this);
839 } 887 }
840 888
(...skipping 11 matching lines...) Expand all
852 } 900 }
853 901
854 902
855 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) { 903 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
856 __ Bind(&block_info_[instr->postorder_number()]->label); 904 __ Bind(&block_info_[instr->postorder_number()]->label);
857 } 905 }
858 906
859 907
860 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) { 908 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) {
861 __ Bind(&block_info_[instr->postorder_number()]->label); 909 __ Bind(&block_info_[instr->postorder_number()]->label);
910 if (instr->HasTryIndex()) {
911 exception_handlers_list_->AddHandler(instr->try_index(),
912 assembler_->CodeSize());
913 // Bailout("Untested CatchEntry");
914 }
862 } 915 }
863 916
864 917
865 void FlowGraphCompiler::VisitPickTemp(PickTempInstr* instr) { 918 void FlowGraphCompiler::VisitPickTemp(PickTempInstr* instr) {
866 // Semantics is to copy a stack-allocated temporary to the top of stack. 919 // Semantics is to copy a stack-allocated temporary to the top of stack.
867 // Destination index d is assumed the new top of stack after the 920 // Destination index d is assumed the new top of stack after the
868 // operation, so d-1 is the current top of stack and so d-s-1 is the 921 // operation, so d-1 is the current top of stack and so d-s-1 is the
869 // offset to source index s. 922 // offset to source index s.
870 intptr_t offset = instr->destination() - instr->source() - 1; 923 intptr_t offset = instr->destination() - instr->source() - 1;
871 ASSERT(offset >= 0); 924 ASSERT(offset >= 0);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 #endif // DEBUG. 963 #endif // DEBUG.
911 964
912 if (FLAG_trace_functions) { 965 if (FLAG_trace_functions) {
913 __ pushq(RAX); // Preserve result. 966 __ pushq(RAX); // Preserve result.
914 const Function& function = 967 const Function& function =
915 Function::ZoneHandle(parsed_function_.function().raw()); 968 Function::ZoneHandle(parsed_function_.function().raw());
916 __ LoadObject(RBX, function); 969 __ LoadObject(RBX, function);
917 __ pushq(RBX); 970 __ pushq(RBX);
918 GenerateCallRuntime(AstNode::kNoId, 971 GenerateCallRuntime(AstNode::kNoId,
919 0, 972 0,
973 CatchClauseNode::kInvalidTryIndex,
920 kTraceFunctionExitRuntimeEntry); 974 kTraceFunctionExitRuntimeEntry);
921 __ popq(RAX); // Remove argument. 975 __ popq(RAX); // Remove argument.
922 __ popq(RAX); // Restore result. 976 __ popq(RAX); // Restore result.
923 } 977 }
924 __ LeaveFrame(); 978 __ LeaveFrame();
925 __ ret(); 979 __ ret();
926 980
927 // Generate 8 bytes of NOPs so that the debugger can patch the 981 // Generate 8 bytes of NOPs so that the debugger can patch the
928 // return pattern with a call to the debug stub. 982 // return pattern with a call to the debug stub.
929 __ nop(1); 983 __ nop(1);
930 __ nop(1); 984 __ nop(1);
931 __ nop(1); 985 __ nop(1);
932 __ nop(1); 986 __ nop(1);
933 __ nop(1); 987 __ nop(1);
934 __ nop(1); 988 __ nop(1);
935 __ nop(1); 989 __ nop(1);
936 __ nop(1); 990 __ nop(1);
937 AddCurrentDescriptor(PcDescriptors::kReturn, 991 AddCurrentDescriptor(PcDescriptors::kReturn,
938 AstNode::kNoId, 992 AstNode::kNoId,
939 instr->token_index()); 993 instr->token_index(),
994 CatchClauseNode::kInvalidTryIndex); // try-index.
940 } 995 }
941 996
942 997
943 void FlowGraphCompiler::VisitThrow(ThrowInstr* instr) { 998 void FlowGraphCompiler::VisitThrow(ThrowInstr* instr) {
944 LoadValue(RAX, instr->exception()); 999 LoadValue(RAX, instr->exception());
945 __ pushq(RAX); 1000 __ pushq(RAX);
946 GenerateCallRuntime(instr->node_id(), 1001 GenerateCallRuntime(instr->node_id(),
947 instr->token_index(), 1002 instr->token_index(),
1003 instr->try_index(),
948 kThrowRuntimeEntry); 1004 kThrowRuntimeEntry);
949 __ int3(); 1005 __ int3();
950 } 1006 }
951 1007
952 1008
953 void FlowGraphCompiler::VisitReThrow(ReThrowInstr* instr) { 1009 void FlowGraphCompiler::VisitReThrow(ReThrowInstr* instr) {
954 LoadValue(RBX, instr->stack_trace()); 1010 LoadValue(RBX, instr->stack_trace());
955 LoadValue(RAX, instr->exception()); 1011 LoadValue(RAX, instr->exception());
956 __ pushq(RAX); 1012 __ pushq(RAX);
957 __ pushq(RBX); 1013 __ pushq(RBX);
958 GenerateCallRuntime( 1014 GenerateCallRuntime(instr->node_id(),
959 instr->node_id(), instr->token_index(), kReThrowRuntimeEntry); 1015 instr->token_index(),
1016 instr->try_index(),
1017 kReThrowRuntimeEntry);
960 Bailout("ReThrow Untested"); 1018 Bailout("ReThrow Untested");
961 } 1019 }
962 1020
963 1021
964 1022
965 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) { 1023 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) {
966 // Determine if the true branch is fall through (!negated) or the false 1024 // Determine if the true branch is fall through (!negated) or the false
967 // branch is. They cannot both be backwards branches. 1025 // branch is. They cannot both be backwards branches.
968 intptr_t index = reverse_index(current_block()->postorder_number()); 1026 intptr_t index = reverse_index(current_block()->postorder_number());
969 bool negated = (block_order_[index + 1] == instr->false_successor()); 1027 bool negated = (block_order_[index + 1] == instr->false_successor());
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 const Immediate raw_null = 1160 const Immediate raw_null =
1103 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1161 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1104 Label all_arguments_processed; 1162 Label all_arguments_processed;
1105 __ cmpq(Address(RDI, 0), raw_null); 1163 __ cmpq(Address(RDI, 0), raw_null);
1106 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 1164 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
1107 1165
1108 __ Bind(&wrong_num_arguments); 1166 __ Bind(&wrong_num_arguments);
1109 if (function.IsClosureFunction()) { 1167 if (function.IsClosureFunction()) {
1110 GenerateCallRuntime(AstNode::kNoId, 1168 GenerateCallRuntime(AstNode::kNoId,
1111 0, 1169 0,
1170 CatchClauseNode::kInvalidTryIndex,
1112 kClosureArgumentMismatchRuntimeEntry); 1171 kClosureArgumentMismatchRuntimeEntry);
1113 } else { 1172 } else {
1114 // Invoke noSuchMethod function. 1173 // Invoke noSuchMethod function.
1115 const int kNumArgsChecked = 1; 1174 const int kNumArgsChecked = 1;
1116 ICData& ic_data = ICData::ZoneHandle(); 1175 ICData& ic_data = ICData::ZoneHandle();
1117 ic_data = ICData::New(parsed_function_.function(), 1176 ic_data = ICData::New(parsed_function_.function(),
1118 String::Handle(function.name()), 1177 String::Handle(function.name()),
1119 AstNode::kNoId, 1178 AstNode::kNoId,
1120 kNumArgsChecked); 1179 kNumArgsChecked);
1121 __ LoadObject(RBX, ic_data); 1180 __ LoadObject(RBX, ic_data);
1122 // RBP : points to previous frame pointer. 1181 // RBP : points to previous frame pointer.
1123 // RBP + 8 : points to return address. 1182 // RBP + 8 : points to return address.
1124 // RBP + 16 : address of last argument (arg n-1). 1183 // RBP + 16 : address of last argument (arg n-1).
1125 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). 1184 // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
1126 // RBX : ic-data. 1185 // RBX : ic-data.
1127 // R10 : arguments descriptor array. 1186 // R10 : arguments descriptor array.
1128 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 1187 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
1129 } 1188 }
1130 1189
1131 if (FLAG_trace_functions) { 1190 if (FLAG_trace_functions) {
1132 __ pushq(RAX); // Preserve result. 1191 __ pushq(RAX); // Preserve result.
1133 __ PushObject(Function::ZoneHandle(function.raw())); 1192 __ PushObject(Function::ZoneHandle(function.raw()));
1134 GenerateCallRuntime(AstNode::kNoId, 1193 GenerateCallRuntime(AstNode::kNoId,
1135 0, 1194 0,
1195 CatchClauseNode::kInvalidTryIndex,
1136 kTraceFunctionExitRuntimeEntry); 1196 kTraceFunctionExitRuntimeEntry);
1137 __ popq(RAX); // Remove argument. 1197 __ popq(RAX); // Remove argument.
1138 __ popq(RAX); // Restore result. 1198 __ popq(RAX); // Restore result.
1139 } 1199 }
1140 __ LeaveFrame(); 1200 __ LeaveFrame();
1141 __ ret(); 1201 __ ret();
1142 1202
1143 __ Bind(&all_arguments_processed); 1203 __ Bind(&all_arguments_processed);
1144 // Nullify originally passed arguments only after they have been copied and 1204 // Nullify originally passed arguments only after they have been copied and
1145 // checked, otherwise noSuchMethod would not see their original values. 1205 // checked, otherwise noSuchMethod would not see their original values.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 if (check_arguments) { 1246 if (check_arguments) {
1187 // Check that num_fixed <= argc <= num_params. 1247 // Check that num_fixed <= argc <= num_params.
1188 Label argc_in_range; 1248 Label argc_in_range;
1189 // Total number of args is the first Smi in args descriptor array (R10). 1249 // Total number of args is the first Smi in args descriptor array (R10).
1190 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 1250 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
1191 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count))); 1251 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count)));
1192 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 1252 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
1193 if (function.IsClosureFunction()) { 1253 if (function.IsClosureFunction()) {
1194 GenerateCallRuntime(AstNode::kNoId, 1254 GenerateCallRuntime(AstNode::kNoId,
1195 function.token_index(), 1255 function.token_index(),
1256 CatchClauseNode::kInvalidTryIndex,
1196 kClosureArgumentMismatchRuntimeEntry); 1257 kClosureArgumentMismatchRuntimeEntry);
1197 } else { 1258 } else {
1198 __ Stop("Wrong number of arguments"); 1259 __ Stop("Wrong number of arguments");
1199 } 1260 }
1200 __ Bind(&argc_in_range); 1261 __ Bind(&argc_in_range);
1201 } 1262 }
1202 } else { 1263 } else {
1203 CopyParameters(); 1264 CopyParameters();
1204 } 1265 }
1205 1266
1206 // Initialize locals to null. 1267 // Initialize locals to null.
1207 if (local_count > 0) { 1268 if (local_count > 0) {
1208 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null()))); 1269 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null())));
1209 const int base = parsed_function_.first_stack_local_index(); 1270 const int base = parsed_function_.first_stack_local_index();
1210 for (int i = 0; i < local_count; ++i) { 1271 for (int i = 0; i < local_count; ++i) {
1211 // Subtract index i (locals lie at lower addresses than RBP). 1272 // Subtract index i (locals lie at lower addresses than RBP).
1212 __ movq(Address(RBP, (base - i) * kWordSize), RAX); 1273 __ movq(Address(RBP, (base - i) * kWordSize), RAX);
1213 } 1274 }
1214 } 1275 }
1215 1276
1216 // Generate stack overflow check. 1277 // Generate stack overflow check.
1217 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address())); 1278 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
1218 __ cmpq(RSP, Address(TMP, 0)); 1279 __ cmpq(RSP, Address(TMP, 0));
1219 Label no_stack_overflow; 1280 Label no_stack_overflow;
1220 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 1281 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
1221 GenerateCallRuntime(AstNode::kNoId, 1282 GenerateCallRuntime(AstNode::kNoId,
1222 function.token_index(), 1283 function.token_index(),
1284 CatchClauseNode::kInvalidTryIndex,
1223 kStackOverflowRuntimeEntry); 1285 kStackOverflowRuntimeEntry);
1224 __ Bind(&no_stack_overflow); 1286 __ Bind(&no_stack_overflow);
1225 1287
1226 if (FLAG_print_scopes) { 1288 if (FLAG_print_scopes) {
1227 // Print the function scope (again) after generating the prologue in order 1289 // Print the function scope (again) after generating the prologue in order
1228 // to see annotations such as allocation indices of locals. 1290 // to see annotations such as allocation indices of locals.
1229 if (FLAG_print_ast) { 1291 if (FLAG_print_ast) {
1230 // Second printing. 1292 // Second printing.
1231 OS::Print("Annotated "); 1293 OS::Print("Annotated ");
1232 } 1294 }
1233 AstPrinter::PrintFunctionScope(parsed_function_); 1295 AstPrinter::PrintFunctionScope(parsed_function_);
1234 } 1296 }
1235 1297
1236 VisitBlocks(); 1298 VisitBlocks();
1237 1299
1238 __ int3(); 1300 __ int3();
1239 // Emit function patching code. This will be swapped with the first 13 bytes 1301 // Emit function patching code. This will be swapped with the first 13 bytes
1240 // at entry point. 1302 // at entry point.
1241 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, 1303 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode,
1242 assembler_->CodeSize(), 1304 assembler_->CodeSize(),
1243 AstNode::kNoId, 1305 AstNode::kNoId,
1244 0, 1306 0,
1245 -1); 1307 -1);
1246 __ jmp(&StubCode::FixCallersTargetLabel()); 1308 __ jmp(&StubCode::FixCallersTargetLabel());
1247 } 1309 }
1248 1310
1249 1311
1250 // Infrastructure copied from class CodeGenerator. 1312 // Infrastructure copied from class CodeGenerator.
1251 void FlowGraphCompiler::GenerateCall(intptr_t token_index, 1313 void FlowGraphCompiler::GenerateCall(intptr_t token_index,
1314 intptr_t try_index,
1252 const ExternalLabel* label, 1315 const ExternalLabel* label,
1253 PcDescriptors::Kind kind) { 1316 PcDescriptors::Kind kind) {
1254 __ call(label); 1317 __ call(label);
1255 AddCurrentDescriptor(kind, AstNode::kNoId, token_index); 1318 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index);
1256 } 1319 }
1257 1320
1258 1321
1259 void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id, 1322 void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id,
1260 intptr_t token_index, 1323 intptr_t token_index,
1324 intptr_t try_index,
1261 const RuntimeEntry& entry) { 1325 const RuntimeEntry& entry) {
1262 __ CallRuntimeFromDart(entry); 1326 __ CallRuntimeFromDart(entry);
1263 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); 1327 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index, try_index);
1264 } 1328 }
1265 1329
1266 1330
1267 // Uses current pc position and try-index. 1331 // Uses current pc position and try-index.
1268 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, 1332 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
1269 intptr_t node_id, 1333 intptr_t node_id,
1270 intptr_t token_index) { 1334 intptr_t token_index,
1335 intptr_t try_index) {
1271 pc_descriptors_list_->AddDescriptor(kind, 1336 pc_descriptors_list_->AddDescriptor(kind,
1272 assembler_->CodeSize(), 1337 assembler_->CodeSize(),
1273 node_id, 1338 node_id,
1274 token_index, 1339 token_index,
1275 CatchClauseNode::kInvalidTryIndex); 1340 try_index);
1276 } 1341 }
1277 1342
1278 1343
1279 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { 1344 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
1280 ASSERT(pc_descriptors_list_ != NULL); 1345 ASSERT(pc_descriptors_list_ != NULL);
1281 const PcDescriptors& descriptors = PcDescriptors::Handle( 1346 const PcDescriptors& descriptors = PcDescriptors::Handle(
1282 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); 1347 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
1283 descriptors.Verify(parsed_function_.function().is_optimizable()); 1348 descriptors.Verify(parsed_function_.function().is_optimizable());
1284 code.set_pc_descriptors(descriptors); 1349 code.set_pc_descriptors(descriptors);
1285 } 1350 }
1286 1351
1287 1352
1288 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) { 1353 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
1289 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle( 1354 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
1290 parsed_function_.node_sequence()->scope()->GetVarDescriptors()); 1355 parsed_function_.node_sequence()->scope()->GetVarDescriptors());
1291 code.set_var_descriptors(var_descs); 1356 code.set_var_descriptors(var_descs);
1292 } 1357 }
1293 1358
1294 1359
1295 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 1360 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
1296 // We don't compile exception handlers yet. 1361 ASSERT(exception_handlers_list_ != NULL);
1297 code.set_exception_handlers( 1362 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
1298 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); 1363 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
1364 code.set_exception_handlers(handlers);
1299 } 1365 }
1300 1366
1301 1367
1302 } // namespace dart 1368 } // namespace dart
1303 1369
1304 #endif // defined TARGET_ARCH_X64 1370 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698