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

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 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
« no previous file with comments | « src/x64/frames-x64.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 163 }
164 // Visit all the explicit declarations unless there is an illegal 164 // Visit all the explicit declarations unless there is an illegal
165 // redeclaration. 165 // redeclaration.
166 if (scope()->HasIllegalRedeclaration()) { 166 if (scope()->HasIllegalRedeclaration()) {
167 scope()->VisitIllegalRedeclaration(this); 167 scope()->VisitIllegalRedeclaration(this);
168 } else { 168 } else {
169 VisitDeclarations(scope()->declarations()); 169 VisitDeclarations(scope()->declarations());
170 } 170 }
171 } 171 }
172 172
173 if (FLAG_trace) {
174 __ CallRuntime(Runtime::kTraceEnter, 0);
175 }
176
173 { Comment cmnt(masm_, "[ Stack check"); 177 { Comment cmnt(masm_, "[ Stack check");
178 PrepareForBailout(info->function(), NO_REGISTERS);
174 NearLabel ok; 179 NearLabel ok;
175 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 180 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
176 __ j(above_equal, &ok); 181 __ j(above_equal, &ok);
177 StackCheckStub stub; 182 StackCheckStub stub;
178 __ CallStub(&stub); 183 __ CallStub(&stub);
179 __ bind(&ok); 184 __ bind(&ok);
180 } 185 }
181 186
182 if (FLAG_trace) {
183 __ CallRuntime(Runtime::kTraceEnter, 0);
184 }
185
186 { Comment cmnt(masm_, "[ Body"); 187 { Comment cmnt(masm_, "[ Body");
187 ASSERT(loop_depth() == 0); 188 ASSERT(loop_depth() == 0);
188 VisitStatements(function()->body()); 189 VisitStatements(function()->body());
189 ASSERT(loop_depth() == 0); 190 ASSERT(loop_depth() == 0);
190 } 191 }
191 192
192 { Comment cmnt(masm_, "[ return <undefined>;"); 193 { Comment cmnt(masm_, "[ return <undefined>;");
193 // Emit a 'return undefined' in case control fell off the end of the body. 194 // Emit a 'return undefined' in case control fell off the end of the body.
194 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 195 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
195 EmitReturnSequence(); 196 EmitReturnSequence();
196 } 197 }
197 } 198 }
198 199
199 200
201 void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
202 Comment cmnt(masm_, "[ Stack check");
203 NearLabel ok;
204 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
205 __ j(above_equal, &ok);
206 StackCheckStub stub;
207 __ CallStub(&stub);
208 __ bind(&ok);
209 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
210 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
211 RecordStackCheck(stmt->OsrEntryId());
212 }
213
214
200 void FullCodeGenerator::EmitReturnSequence() { 215 void FullCodeGenerator::EmitReturnSequence() {
201 Comment cmnt(masm_, "[ Return sequence"); 216 Comment cmnt(masm_, "[ Return sequence");
202 if (return_label_.is_bound()) { 217 if (return_label_.is_bound()) {
203 __ jmp(&return_label_); 218 __ jmp(&return_label_);
204 } else { 219 } else {
205 __ bind(&return_label_); 220 __ bind(&return_label_);
206 if (FLAG_trace) { 221 if (FLAG_trace) {
207 __ push(rax); 222 __ push(rax);
208 __ CallRuntime(Runtime::kTraceExit, 1); 223 __ CallRuntime(Runtime::kTraceExit, 1);
209 } 224 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 269
255 270
256 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const { 271 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const {
257 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register()); 272 MemOperand slot_operand = codegen()->EmitSlotSearch(slot, result_register());
258 __ push(slot_operand); 273 __ push(slot_operand);
259 } 274 }
260 275
261 276
262 void FullCodeGenerator::TestContext::Plug(Slot* slot) const { 277 void FullCodeGenerator::TestContext::Plug(Slot* slot) const {
263 codegen()->Move(result_register(), slot); 278 codegen()->Move(result_register(), slot);
279 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
264 codegen()->DoTest(true_label_, false_label_, fall_through_); 280 codegen()->DoTest(true_label_, false_label_, fall_through_);
265 } 281 }
266 282
267 283
268 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 284 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
269 } 285 }
270 286
271 287
272 void FullCodeGenerator::AccumulatorValueContext::Plug( 288 void FullCodeGenerator::AccumulatorValueContext::Plug(
273 Heap::RootListIndex index) const { 289 Heap::RootListIndex index) const {
274 __ LoadRoot(result_register(), index); 290 __ LoadRoot(result_register(), index);
275 } 291 }
276 292
277 293
278 void FullCodeGenerator::StackValueContext::Plug( 294 void FullCodeGenerator::StackValueContext::Plug(
279 Heap::RootListIndex index) const { 295 Heap::RootListIndex index) const {
280 __ PushRoot(index); 296 __ PushRoot(index);
281 } 297 }
282 298
283 299
284 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 300 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
301 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
302 true,
303 true_label_,
304 false_label_);
285 if (index == Heap::kUndefinedValueRootIndex || 305 if (index == Heap::kUndefinedValueRootIndex ||
286 index == Heap::kNullValueRootIndex || 306 index == Heap::kNullValueRootIndex ||
287 index == Heap::kFalseValueRootIndex) { 307 index == Heap::kFalseValueRootIndex) {
288 __ jmp(false_label_); 308 if (false_label_ != fall_through_) __ jmp(false_label_);
289 } else if (index == Heap::kTrueValueRootIndex) { 309 } else if (index == Heap::kTrueValueRootIndex) {
290 __ jmp(true_label_); 310 if (true_label_ != fall_through_) __ jmp(true_label_);
291 } else { 311 } else {
292 __ LoadRoot(result_register(), index); 312 __ LoadRoot(result_register(), index);
293 codegen()->DoTest(true_label_, false_label_, fall_through_); 313 codegen()->DoTest(true_label_, false_label_, fall_through_);
294 } 314 }
295 } 315 }
296 316
297 317
298 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const { 318 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {
299 } 319 }
300 320
301 321
302 void FullCodeGenerator::AccumulatorValueContext::Plug( 322 void FullCodeGenerator::AccumulatorValueContext::Plug(
303 Handle<Object> lit) const { 323 Handle<Object> lit) const {
304 __ Move(result_register(), lit); 324 __ Move(result_register(), lit);
305 } 325 }
306 326
307 327
308 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 328 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
309 __ Push(lit); 329 __ Push(lit);
310 } 330 }
311 331
312 332
313 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 333 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
334 codegen()->PrepareForBailoutBeforeSplit(TOS_REG,
335 true,
336 true_label_,
337 false_label_);
314 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. 338 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals.
315 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 339 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
316 __ jmp(false_label_); 340 if (false_label_ != fall_through_) __ jmp(false_label_);
317 } else if (lit->IsTrue() || lit->IsJSObject()) { 341 } else if (lit->IsTrue() || lit->IsJSObject()) {
318 __ jmp(true_label_); 342 if (true_label_ != fall_through_) __ jmp(true_label_);
319 } else if (lit->IsString()) { 343 } else if (lit->IsString()) {
320 if (String::cast(*lit)->length() == 0) { 344 if (String::cast(*lit)->length() == 0) {
321 __ jmp(false_label_); 345 if (false_label_ != fall_through_) __ jmp(false_label_);
322 } else { 346 } else {
323 __ jmp(true_label_); 347 if (true_label_ != fall_through_) __ jmp(true_label_);
324 } 348 }
325 } else if (lit->IsSmi()) { 349 } else if (lit->IsSmi()) {
326 if (Smi::cast(*lit)->value() == 0) { 350 if (Smi::cast(*lit)->value() == 0) {
327 __ jmp(false_label_); 351 if (false_label_ != fall_through_) __ jmp(false_label_);
328 } else { 352 } else {
329 __ jmp(true_label_); 353 if (true_label_ != fall_through_) __ jmp(true_label_);
330 } 354 }
331 } else { 355 } else {
332 // For simplicity we always test the accumulator register. 356 // For simplicity we always test the accumulator register.
333 __ Move(result_register(), lit); 357 __ Move(result_register(), lit);
334 codegen()->DoTest(true_label_, false_label_, fall_through_); 358 codegen()->DoTest(true_label_, false_label_, fall_through_);
335 } 359 }
336 } 360 }
337 361
338 362
339 void FullCodeGenerator::EffectContext::DropAndPlug(int count, 363 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
(...skipping 19 matching lines...) Expand all
359 __ movq(Operand(rsp, 0), reg); 383 __ movq(Operand(rsp, 0), reg);
360 } 384 }
361 385
362 386
363 void FullCodeGenerator::TestContext::DropAndPlug(int count, 387 void FullCodeGenerator::TestContext::DropAndPlug(int count,
364 Register reg) const { 388 Register reg) const {
365 ASSERT(count > 0); 389 ASSERT(count > 0);
366 // For simplicity we always test the accumulator register. 390 // For simplicity we always test the accumulator register.
367 __ Drop(count); 391 __ Drop(count);
368 __ Move(result_register(), reg); 392 __ Move(result_register(), reg);
393 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
369 codegen()->DoTest(true_label_, false_label_, fall_through_); 394 codegen()->DoTest(true_label_, false_label_, fall_through_);
370 } 395 }
371 396
372 397
373 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 398 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
374 Label* materialize_false) const { 399 Label* materialize_false) const {
375 ASSERT_EQ(materialize_true, materialize_false); 400 ASSERT(materialize_true == materialize_false);
376 __ bind(materialize_true); 401 __ bind(materialize_true);
377 } 402 }
378 403
379 404
380 void FullCodeGenerator::AccumulatorValueContext::Plug( 405 void FullCodeGenerator::AccumulatorValueContext::Plug(
381 Label* materialize_true, 406 Label* materialize_true,
382 Label* materialize_false) const { 407 Label* materialize_false) const {
383 NearLabel done; 408 NearLabel done;
384 __ bind(materialize_true); 409 __ bind(materialize_true);
385 __ Move(result_register(), FACTORY->true_value()); 410 __ Move(result_register(), FACTORY->true_value());
(...skipping 12 matching lines...) Expand all
398 __ Push(FACTORY->true_value()); 423 __ Push(FACTORY->true_value());
399 __ jmp(&done); 424 __ jmp(&done);
400 __ bind(materialize_false); 425 __ bind(materialize_false);
401 __ Push(FACTORY->false_value()); 426 __ Push(FACTORY->false_value());
402 __ bind(&done); 427 __ bind(&done);
403 } 428 }
404 429
405 430
406 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 431 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
407 Label* materialize_false) const { 432 Label* materialize_false) const {
433 ASSERT(materialize_true == true_label_);
408 ASSERT(materialize_false == false_label_); 434 ASSERT(materialize_false == false_label_);
409 ASSERT(materialize_true == true_label_);
410 } 435 }
411 436
412 437
413 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 438 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
414 } 439 }
415 440
416 441
417 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 442 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
418 Heap::RootListIndex value_root_index = 443 Heap::RootListIndex value_root_index =
419 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 444 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
420 __ LoadRoot(result_register(), value_root_index); 445 __ LoadRoot(result_register(), value_root_index);
421 } 446 }
422 447
423 448
424 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 449 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
425 Heap::RootListIndex value_root_index = 450 Heap::RootListIndex value_root_index =
426 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 451 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
427 __ PushRoot(value_root_index); 452 __ PushRoot(value_root_index);
428 } 453 }
429 454
430 455
431 void FullCodeGenerator::TestContext::Plug(bool flag) const { 456 void FullCodeGenerator::TestContext::Plug(bool flag) const {
457 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
432 if (flag) { 458 if (flag) {
433 if (true_label_ != fall_through_) __ jmp(true_label_); 459 if (true_label_ != fall_through_) __ jmp(true_label_);
434 } else { 460 } else {
435 if (false_label_ != fall_through_) __ jmp(false_label_); 461 if (false_label_ != fall_through_) __ jmp(false_label_);
436 } 462 }
437 } 463 }
438 464
439 465
440 void FullCodeGenerator::DoTest(Label* if_true, 466 void FullCodeGenerator::DoTest(Label* if_true,
441 Label* if_false, 467 Label* if_false,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 MemOperand location = EmitSlotSearch(dst, scratch1); 539 MemOperand location = EmitSlotSearch(dst, scratch1);
514 __ movq(location, src); 540 __ movq(location, src);
515 // Emit the write barrier code if the location is in the heap. 541 // Emit the write barrier code if the location is in the heap.
516 if (dst->type() == Slot::CONTEXT) { 542 if (dst->type() == Slot::CONTEXT) {
517 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize; 543 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
518 __ RecordWrite(scratch1, offset, src, scratch2); 544 __ RecordWrite(scratch1, offset, src, scratch2);
519 } 545 }
520 } 546 }
521 547
522 548
549 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
550 bool should_normalize,
551 Label* if_true,
552 Label* if_false) {
553 }
554
555
523 void FullCodeGenerator::EmitDeclaration(Variable* variable, 556 void FullCodeGenerator::EmitDeclaration(Variable* variable,
524 Variable::Mode mode, 557 Variable::Mode mode,
525 FunctionLiteral* function) { 558 FunctionLiteral* function) {
526 Comment cmnt(masm_, "[ Declaration"); 559 Comment cmnt(masm_, "[ Declaration");
527 ASSERT(variable != NULL); // Must have been resolved. 560 ASSERT(variable != NULL); // Must have been resolved.
528 Slot* slot = variable->AsSlot(); 561 Slot* slot = variable->AsSlot();
529 Property* prop = variable->AsProperty(); 562 Property* prop = variable->AsProperty();
530 563
531 if (slot != NULL) { 564 if (slot != NULL) {
532 switch (slot->type()) { 565 switch (slot->type()) {
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 __ movq(rbx, rax); 836 __ movq(rbx, rax);
804 837
805 // Update the 'each' property or variable from the possibly filtered 838 // Update the 'each' property or variable from the possibly filtered
806 // entry in register rbx. 839 // entry in register rbx.
807 __ bind(&update_each); 840 __ bind(&update_each);
808 __ movq(result_register(), rbx); 841 __ movq(result_register(), rbx);
809 // Perform the assignment as if via '='. 842 // Perform the assignment as if via '='.
810 EmitAssignment(stmt->each()); 843 EmitAssignment(stmt->each());
811 844
812 // Generate code for the body of the loop. 845 // Generate code for the body of the loop.
813 Label stack_limit_hit, stack_check_done;
814 Visit(stmt->body()); 846 Visit(stmt->body());
815 847
816 __ StackLimitCheck(&stack_limit_hit);
817 __ bind(&stack_check_done);
818
819 // Generate code for going to the next element by incrementing the 848 // Generate code for going to the next element by incrementing the
820 // index (smi) stored on top of the stack. 849 // index (smi) stored on top of the stack.
821 __ bind(loop_statement.continue_target()); 850 __ bind(loop_statement.continue_target());
822 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); 851 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1));
852
853 EmitStackCheck(stmt);
823 __ jmp(&loop); 854 __ jmp(&loop);
824 855
825 // Slow case for the stack limit check.
826 StackCheckStub stack_check_stub;
827 __ bind(&stack_limit_hit);
828 __ CallStub(&stack_check_stub);
829 __ jmp(&stack_check_done);
830
831 // Remove the pointers stored on the stack. 856 // Remove the pointers stored on the stack.
832 __ bind(loop_statement.break_target()); 857 __ bind(loop_statement.break_target());
833 __ addq(rsp, Immediate(5 * kPointerSize)); 858 __ addq(rsp, Immediate(5 * kPointerSize));
834 859
835 // Exit and decrement the loop depth. 860 // Exit and decrement the loop depth.
836 __ bind(&exit); 861 __ bind(&exit);
837 decrement_loop_depth(); 862 decrement_loop_depth();
838 } 863 }
839 864
840 865
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 } 1737 }
1713 1738
1714 1739
1715 void FullCodeGenerator::VisitProperty(Property* expr) { 1740 void FullCodeGenerator::VisitProperty(Property* expr) {
1716 Comment cmnt(masm_, "[ Property"); 1741 Comment cmnt(masm_, "[ Property");
1717 Expression* key = expr->key(); 1742 Expression* key = expr->key();
1718 1743
1719 if (key->IsPropertyName()) { 1744 if (key->IsPropertyName()) {
1720 VisitForAccumulatorValue(expr->obj()); 1745 VisitForAccumulatorValue(expr->obj());
1721 EmitNamedPropertyLoad(expr); 1746 EmitNamedPropertyLoad(expr);
1747 context()->Plug(rax);
1722 } else { 1748 } else {
1723 VisitForStackValue(expr->obj()); 1749 VisitForStackValue(expr->obj());
1724 VisitForAccumulatorValue(expr->key()); 1750 VisitForAccumulatorValue(expr->key());
1725 __ pop(rdx); 1751 __ pop(rdx);
1726 EmitKeyedPropertyLoad(expr); 1752 EmitKeyedPropertyLoad(expr);
1753 context()->Plug(rax);
1727 } 1754 }
1728 context()->Plug(rax);
1729 } 1755 }
1730 1756
1731 1757
1732 void FullCodeGenerator::EmitCallWithIC(Call* expr, 1758 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1733 Handle<Object> name, 1759 Handle<Object> name,
1734 RelocInfo::Mode mode) { 1760 RelocInfo::Mode mode) {
1735 // Code common for calls using the IC. 1761 // Code common for calls using the IC.
1736 ZoneList<Expression*>* args = expr->arguments(); 1762 ZoneList<Expression*>* args = expr->arguments();
1737 int arg_count = args->length(); 1763 int arg_count = args->length();
1738 { PreservePositionScope scope(masm()->positions_recorder()); 1764 { PreservePositionScope scope(masm()->positions_recorder());
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
2672 // InvokeFunction requires function in rdi. Move it in there. 2698 // InvokeFunction requires function in rdi. Move it in there.
2673 if (!result_register().is(rdi)) __ movq(rdi, result_register()); 2699 if (!result_register().is(rdi)) __ movq(rdi, result_register());
2674 ParameterCount count(arg_count); 2700 ParameterCount count(arg_count);
2675 __ InvokeFunction(rdi, count, CALL_FUNCTION); 2701 __ InvokeFunction(rdi, count, CALL_FUNCTION);
2676 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2702 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2677 context()->Plug(rax); 2703 context()->Plug(rax);
2678 } 2704 }
2679 2705
2680 2706
2681 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { 2707 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
2708 RegExpConstructResultStub stub;
2682 ASSERT(args->length() == 3); 2709 ASSERT(args->length() == 3);
2683 VisitForStackValue(args->at(0)); 2710 VisitForStackValue(args->at(0));
2684 VisitForStackValue(args->at(1)); 2711 VisitForStackValue(args->at(1));
2685 VisitForStackValue(args->at(2)); 2712 VisitForStackValue(args->at(2));
2686 __ CallRuntime(Runtime::kRegExpConstructResult, 3); 2713 __ CallStub(&stub);
2687 context()->Plug(rax); 2714 context()->Plug(rax);
2688 } 2715 }
2689 2716
2690 2717
2691 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { 2718 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
2692 ASSERT(args->length() == 3); 2719 ASSERT(args->length() == 3);
2693 VisitForStackValue(args->at(0)); 2720 VisitForStackValue(args->at(0));
2694 VisitForStackValue(args->at(1)); 2721 VisitForStackValue(args->at(1));
2695 VisitForStackValue(args->at(2)); 2722 VisitForStackValue(args->at(2));
2696 __ CallRuntime(Runtime::kSwapElements, 3); 2723 __ CallRuntime(Runtime::kSwapElements, 3);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
2939 VisitForTypeofValue(expr->expression()); 2966 VisitForTypeofValue(expr->expression());
2940 } 2967 }
2941 __ CallRuntime(Runtime::kTypeof, 1); 2968 __ CallRuntime(Runtime::kTypeof, 1);
2942 context()->Plug(rax); 2969 context()->Plug(rax);
2943 break; 2970 break;
2944 } 2971 }
2945 2972
2946 case Token::ADD: { 2973 case Token::ADD: {
2947 Comment cmt(masm_, "[ UnaryOperation (ADD)"); 2974 Comment cmt(masm_, "[ UnaryOperation (ADD)");
2948 VisitForAccumulatorValue(expr->expression()); 2975 VisitForAccumulatorValue(expr->expression());
2949 NearLabel no_conversion; 2976 Label no_conversion;
2950 Condition is_smi = masm_->CheckSmi(result_register()); 2977 Condition is_smi = masm_->CheckSmi(result_register());
2951 __ j(is_smi, &no_conversion); 2978 __ j(is_smi, &no_conversion);
2952 __ push(result_register()); 2979 __ push(result_register());
2953 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); 2980 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
2954 __ bind(&no_conversion); 2981 __ bind(&no_conversion);
2955 context()->Plug(result_register()); 2982 context()->Plug(result_register());
2956 break; 2983 break;
2957 } 2984 }
2958 2985
2959 case Token::SUB: { 2986 case Token::SUB: {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 is_smi = masm_->CheckSmi(rax); 3119 is_smi = masm_->CheckSmi(rax);
3093 __ j(is_smi, &done); 3120 __ j(is_smi, &done);
3094 __ bind(&stub_call); 3121 __ bind(&stub_call);
3095 // Call stub. Undo operation first. 3122 // Call stub. Undo operation first.
3096 if (expr->op() == Token::INC) { 3123 if (expr->op() == Token::INC) {
3097 __ SmiSubConstant(rax, rax, Smi::FromInt(1)); 3124 __ SmiSubConstant(rax, rax, Smi::FromInt(1));
3098 } else { 3125 } else {
3099 __ SmiAddConstant(rax, rax, Smi::FromInt(1)); 3126 __ SmiAddConstant(rax, rax, Smi::FromInt(1));
3100 } 3127 }
3101 } 3128 }
3129
3130 // Record position before stub call.
3131 SetSourcePosition(expr->position());
3132
3102 // Call stub for +1/-1. 3133 // Call stub for +1/-1.
3103 GenericBinaryOpStub stub(expr->binary_op(), 3134 GenericBinaryOpStub stub(expr->binary_op(),
3104 NO_OVERWRITE, 3135 NO_OVERWRITE,
3105 NO_GENERIC_BINARY_FLAGS); 3136 NO_GENERIC_BINARY_FLAGS);
3106 stub.GenerateCall(masm_, rax, Smi::FromInt(1)); 3137 stub.GenerateCall(masm_, rax, Smi::FromInt(1));
3107 __ bind(&done); 3138 __ bind(&done);
3108 3139
3109 // Store the value returned in rax. 3140 // Store the value returned in rax.
3110 switch (assign_type) { 3141 switch (assign_type) {
3111 case VARIABLE: 3142 case VARIABLE:
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
3432 Register FullCodeGenerator::context_register() { 3463 Register FullCodeGenerator::context_register() {
3433 return rsi; 3464 return rsi;
3434 } 3465 }
3435 3466
3436 3467
3437 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 3468 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
3438 ASSERT(mode == RelocInfo::CODE_TARGET || 3469 ASSERT(mode == RelocInfo::CODE_TARGET ||
3439 mode == RelocInfo::CODE_TARGET_CONTEXT); 3470 mode == RelocInfo::CODE_TARGET_CONTEXT);
3440 __ call(ic, mode); 3471 __ call(ic, mode);
3441 3472
3473 // Crankshaft doesn't need patching of inlined loads and stores.
3474 if (V8::UseCrankshaft()) return;
3475
3442 // If we're calling a (keyed) load or store stub, we have to mark 3476 // If we're calling a (keyed) load or store stub, we have to mark
3443 // the call as containing no inlined code so we will not attempt to 3477 // the call as containing no inlined code so we will not attempt to
3444 // patch it. 3478 // patch it.
3445 switch (ic->kind()) { 3479 switch (ic->kind()) {
3446 case Code::LOAD_IC: 3480 case Code::LOAD_IC:
3447 case Code::KEYED_LOAD_IC: 3481 case Code::KEYED_LOAD_IC:
3448 case Code::STORE_IC: 3482 case Code::STORE_IC:
3449 case Code::KEYED_STORE_IC: 3483 case Code::KEYED_STORE_IC:
3450 __ nop(); // Signals no inlined code. 3484 __ nop(); // Signals no inlined code.
3451 break; 3485 break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3500 __ ret(0); 3534 __ ret(0);
3501 } 3535 }
3502 3536
3503 3537
3504 #undef __ 3538 #undef __
3505 3539
3506 3540
3507 } } // namespace v8::internal 3541 } } // namespace v8::internal
3508 3542
3509 #endif // V8_TARGET_ARCH_X64 3543 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/frames-x64.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698