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

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

Issue 1218493005: Debugger: use debug break slots instead of ICs (except for calls). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: minor fixes Created 5 years, 5 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 __ call(isolate()->builtins()->InterruptCheck(), 465 __ call(isolate()->builtins()->InterruptCheck(),
466 RelocInfo::CODE_TARGET); 466 RelocInfo::CODE_TARGET);
467 __ Pop(rax); 467 __ Pop(rax);
468 EmitProfilingCounterReset(); 468 EmitProfilingCounterReset();
469 __ bind(&ok); 469 __ bind(&ok);
470 #ifdef DEBUG 470 #ifdef DEBUG
471 // Add a label for checking the size of the code used for returning. 471 // Add a label for checking the size of the code used for returning.
472 Label check_exit_codesize; 472 Label check_exit_codesize;
473 masm_->bind(&check_exit_codesize); 473 masm_->bind(&check_exit_codesize);
474 #endif 474 #endif
475 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); 475 SetReturnPosition(function());
476 __ RecordJSReturn(); 476 __ RecordJSReturn();
477 // Do not use the leave instruction here because it is too short to 477 // Do not use the leave instruction here because it is too short to
478 // patch with the code required by the debugger. 478 // patch with the code required by the debugger.
479 __ movp(rsp, rbp); 479 __ movp(rsp, rbp);
480 __ popq(rbp); 480 __ popq(rbp);
481 int no_frame_start = masm_->pc_offset(); 481 int no_frame_start = masm_->pc_offset();
482 482
483 int arg_count = info_->scope()->num_parameters() + 1; 483 int arg_count = info_->scope()->num_parameters() + 1;
484 int arguments_bytes = arg_count * kPointerSize; 484 int arguments_bytes = arg_count * kPointerSize;
485 __ Ret(arguments_bytes, rcx); 485 __ Ret(arguments_bytes, rcx);
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); 1039 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear);
1040 1040
1041 __ cmpp(rdx, rax); 1041 __ cmpp(rdx, rax);
1042 __ j(not_equal, &next_test); 1042 __ j(not_equal, &next_test);
1043 __ Drop(1); // Switch value is no longer needed. 1043 __ Drop(1); // Switch value is no longer needed.
1044 __ jmp(clause->body_target()); 1044 __ jmp(clause->body_target());
1045 __ bind(&slow_case); 1045 __ bind(&slow_case);
1046 } 1046 }
1047 1047
1048 // Record position before stub call for type feedback. 1048 // Record position before stub call for type feedback.
1049 SetSourcePosition(clause->position()); 1049 SetExpressionPosition(clause);
1050 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, 1050 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
1051 strength(language_mode())).code(); 1051 strength(language_mode())).code();
1052 CallIC(ic, clause->CompareId()); 1052 CallIC(ic, clause->CompareId());
1053 patch_site.EmitPatchInfo(); 1053 patch_site.EmitPatchInfo();
1054 1054
1055 Label skip; 1055 Label skip;
1056 __ jmp(&skip, Label::kNear); 1056 __ jmp(&skip, Label::kNear);
1057 PrepareForBailout(clause, TOS_REG); 1057 PrepareForBailout(clause, TOS_REG);
1058 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 1058 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
1059 __ j(not_equal, &next_test); 1059 __ j(not_equal, &next_test);
(...skipping 26 matching lines...) Expand all
1086 VisitStatements(clause->statements()); 1086 VisitStatements(clause->statements());
1087 } 1087 }
1088 1088
1089 __ bind(nested_statement.break_label()); 1089 __ bind(nested_statement.break_label());
1090 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1090 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1091 } 1091 }
1092 1092
1093 1093
1094 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1094 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1095 Comment cmnt(masm_, "[ ForInStatement"); 1095 Comment cmnt(masm_, "[ ForInStatement");
1096 SetStatementPosition(stmt, SKIP_BREAK);
1097
1096 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1098 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
1097 SetStatementPosition(stmt);
1098 1099
1099 Label loop, exit; 1100 Label loop, exit;
1100 ForIn loop_statement(this, stmt); 1101 ForIn loop_statement(this, stmt);
1101 increment_loop_depth(); 1102 increment_loop_depth();
1102 1103
1103 // Get the object to enumerate over. If the object is null or undefined, skip 1104 // Get the object to enumerate over. If the object is null or undefined, skip
1104 // over the loop. See ECMA-262 version 5, section 12.6.4. 1105 // over the loop. See ECMA-262 version 5, section 12.6.4.
1105 SetExpressionPosition(stmt->enumerable()); 1106 SetExpressionAsStatementPosition(stmt->enumerable());
1106 VisitForAccumulatorValue(stmt->enumerable()); 1107 VisitForAccumulatorValue(stmt->enumerable());
1107 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 1108 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
1108 __ j(equal, &exit); 1109 __ j(equal, &exit);
1109 Register null_value = rdi; 1110 Register null_value = rdi;
1110 __ LoadRoot(null_value, Heap::kNullValueRootIndex); 1111 __ LoadRoot(null_value, Heap::kNullValueRootIndex);
1111 __ cmpp(rax, null_value); 1112 __ cmpp(rax, null_value);
1112 __ j(equal, &exit); 1113 __ j(equal, &exit);
1113 1114
1114 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); 1115 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
1115 1116
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 __ bind(&non_proxy); 1200 __ bind(&non_proxy);
1200 __ Push(rbx); // Smi 1201 __ Push(rbx); // Smi
1201 __ Push(rax); // Array 1202 __ Push(rax); // Array
1202 __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset)); 1203 __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset));
1203 __ Push(rax); // Fixed array length (as smi). 1204 __ Push(rax); // Fixed array length (as smi).
1204 __ Push(Smi::FromInt(0)); // Initial index. 1205 __ Push(Smi::FromInt(0)); // Initial index.
1205 1206
1206 // Generate code for doing the condition check. 1207 // Generate code for doing the condition check.
1207 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1208 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1208 __ bind(&loop); 1209 __ bind(&loop);
1209 SetExpressionPosition(stmt->each()); 1210 SetExpressionAsStatementPosition(stmt->each());
1210 1211
1211 __ movp(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. 1212 __ movp(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index.
1212 __ cmpp(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. 1213 __ cmpp(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length.
1213 __ j(above_equal, loop_statement.break_label()); 1214 __ j(above_equal, loop_statement.break_label());
1214 1215
1215 // Get the current entry of the array into register rbx. 1216 // Get the current entry of the array into register rbx.
1216 __ movp(rbx, Operand(rsp, 2 * kPointerSize)); 1217 __ movp(rbx, Operand(rsp, 2 * kPointerSize));
1217 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); 1218 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2);
1218 __ movp(rbx, FieldOperand(rbx, 1219 __ movp(rbx, FieldOperand(rbx,
1219 index.reg, 1220 index.reg,
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1449 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1449 } 1450 }
1450 } 1451 }
1451 __ jmp(done); 1452 __ jmp(done);
1452 } 1453 }
1453 } 1454 }
1454 1455
1455 1456
1456 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1457 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1457 // Record position before possible IC call. 1458 // Record position before possible IC call.
1458 SetSourcePosition(proxy->position()); 1459 SetExpressionPosition(proxy);
1459 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1460 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1460 Variable* var = proxy->var(); 1461 Variable* var = proxy->var();
1461 1462
1462 // Three cases: global variables, lookup variables, and all other types of 1463 // Three cases: global variables, lookup variables, and all other types of
1463 // variables. 1464 // variables.
1464 switch (var->location()) { 1465 switch (var->location()) {
1465 case Variable::UNALLOCATED: { 1466 case Variable::UNALLOCATED: {
1466 Comment cmnt(masm_, "[ Global variable"); 1467 Comment cmnt(masm_, "[ Global variable");
1467 __ Move(LoadDescriptor::NameRegister(), var->name()); 1468 __ Move(LoadDescriptor::NameRegister(), var->name());
1468 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 1469 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 } else { 1943 } else {
1943 context()->Plug(rax); 1944 context()->Plug(rax);
1944 } 1945 }
1945 } 1946 }
1946 1947
1947 1948
1948 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1949 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1949 DCHECK(expr->target()->IsValidReferenceExpression()); 1950 DCHECK(expr->target()->IsValidReferenceExpression());
1950 1951
1951 Comment cmnt(masm_, "[ Assignment"); 1952 Comment cmnt(masm_, "[ Assignment");
1953 SetExpressionPosition(expr, INSERT_BREAK);
1952 1954
1953 Property* property = expr->target()->AsProperty(); 1955 Property* property = expr->target()->AsProperty();
1954 LhsKind assign_type = Property::GetAssignType(property); 1956 LhsKind assign_type = Property::GetAssignType(property);
1955 1957
1956 // Evaluate LHS expression. 1958 // Evaluate LHS expression.
1957 switch (assign_type) { 1959 switch (assign_type) {
1958 case VARIABLE: 1960 case VARIABLE:
1959 // Nothing to do here. 1961 // Nothing to do here.
1960 break; 1962 break;
1961 case NAMED_PROPERTY: 1963 case NAMED_PROPERTY:
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 EmitKeyedPropertyLoad(property); 2032 EmitKeyedPropertyLoad(property);
2031 PrepareForBailoutForId(property->LoadId(), TOS_REG); 2033 PrepareForBailoutForId(property->LoadId(), TOS_REG);
2032 break; 2034 break;
2033 } 2035 }
2034 } 2036 }
2035 2037
2036 Token::Value op = expr->binary_op(); 2038 Token::Value op = expr->binary_op();
2037 __ Push(rax); // Left operand goes on the stack. 2039 __ Push(rax); // Left operand goes on the stack.
2038 VisitForAccumulatorValue(expr->value()); 2040 VisitForAccumulatorValue(expr->value());
2039 2041
2040 SetSourcePosition(expr->position() + 1);
2041 AccumulatorValueContext context(this); 2042 AccumulatorValueContext context(this);
2042 if (ShouldInlineSmiCase(op)) { 2043 if (ShouldInlineSmiCase(op)) {
2043 EmitInlineSmiBinaryOp(expr->binary_operation(), 2044 EmitInlineSmiBinaryOp(expr->binary_operation(),
2044 op, 2045 op,
2045 expr->target(), 2046 expr->target(),
2046 expr->value()); 2047 expr->value());
2047 } else { 2048 } else {
2048 EmitBinaryOp(expr->binary_operation(), op); 2049 EmitBinaryOp(expr->binary_operation(), op);
2049 } 2050 }
2050 // Deoptimization point in case the binary operation may have side effects. 2051 // Deoptimization point in case the binary operation may have side effects.
2051 PrepareForBailout(expr->binary_operation(), TOS_REG); 2052 PrepareForBailout(expr->binary_operation(), TOS_REG);
2052 } else { 2053 } else {
2053 VisitForAccumulatorValue(expr->value()); 2054 VisitForAccumulatorValue(expr->value());
2054 } 2055 }
2055 2056
2056 // Record source position before possible IC call. 2057 SetExpressionPosition(expr);
2057 SetSourcePosition(expr->position());
2058 2058
2059 // Store the value. 2059 // Store the value.
2060 switch (assign_type) { 2060 switch (assign_type) {
2061 case VARIABLE: 2061 case VARIABLE:
2062 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 2062 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
2063 expr->op(), expr->AssignmentSlot()); 2063 expr->op(), expr->AssignmentSlot());
2064 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2064 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2065 context()->Plug(rax); 2065 context()->Plug(rax);
2066 break; 2066 break;
2067 case NAMED_PROPERTY: 2067 case NAMED_PROPERTY:
2068 EmitNamedPropertyAssignment(expr); 2068 EmitNamedPropertyAssignment(expr);
2069 break; 2069 break;
2070 case NAMED_SUPER_PROPERTY: 2070 case NAMED_SUPER_PROPERTY:
2071 EmitNamedSuperPropertyStore(property); 2071 EmitNamedSuperPropertyStore(property);
2072 context()->Plug(rax); 2072 context()->Plug(rax);
2073 break; 2073 break;
2074 case KEYED_SUPER_PROPERTY: 2074 case KEYED_SUPER_PROPERTY:
2075 EmitKeyedSuperPropertyStore(property); 2075 EmitKeyedSuperPropertyStore(property);
2076 context()->Plug(rax); 2076 context()->Plug(rax);
2077 break; 2077 break;
2078 case KEYED_PROPERTY: 2078 case KEYED_PROPERTY:
2079 EmitKeyedPropertyAssignment(expr); 2079 EmitKeyedPropertyAssignment(expr);
2080 break; 2080 break;
2081 } 2081 }
2082 } 2082 }
2083 2083
2084 2084
2085 void FullCodeGenerator::VisitYield(Yield* expr) { 2085 void FullCodeGenerator::VisitYield(Yield* expr) {
2086 Comment cmnt(masm_, "[ Yield"); 2086 Comment cmnt(masm_, "[ Yield");
2087 SetExpressionPosition(expr);
2088
2087 // Evaluate yielded value first; the initial iterator definition depends on 2089 // Evaluate yielded value first; the initial iterator definition depends on
2088 // this. It stays on the stack while we update the iterator. 2090 // this. It stays on the stack while we update the iterator.
2089 VisitForStackValue(expr->expression()); 2091 VisitForStackValue(expr->expression());
2090 2092
2091 switch (expr->yield_kind()) { 2093 switch (expr->yield_kind()) {
2092 case Yield::kSuspend: 2094 case Yield::kSuspend:
2093 // Pop value from top-of-stack slot; box result into result register. 2095 // Pop value from top-of-stack slot; box result into result register.
2094 EmitCreateIteratorResult(false); 2096 EmitCreateIteratorResult(false);
2095 __ Push(result_register()); 2097 __ Push(result_register());
2096 // Fall through. 2098 // Fall through.
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2363 rdx); 2365 rdx);
2364 2366
2365 // Only the value field needs a write barrier, as the other values are in the 2367 // Only the value field needs a write barrier, as the other values are in the
2366 // root set. 2368 // root set.
2367 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, 2369 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset,
2368 rcx, rdx, kDontSaveFPRegs); 2370 rcx, rdx, kDontSaveFPRegs);
2369 } 2371 }
2370 2372
2371 2373
2372 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2374 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2373 SetSourcePosition(prop->position()); 2375 SetExpressionPosition(prop);
2374 Literal* key = prop->key()->AsLiteral(); 2376 Literal* key = prop->key()->AsLiteral();
2375 DCHECK(!prop->IsSuperAccess()); 2377 DCHECK(!prop->IsSuperAccess());
2376 2378
2377 __ Move(LoadDescriptor::NameRegister(), key->value()); 2379 __ Move(LoadDescriptor::NameRegister(), key->value());
2378 __ Move(LoadDescriptor::SlotRegister(), 2380 __ Move(LoadDescriptor::SlotRegister(),
2379 SmiFromSlot(prop->PropertyFeedbackSlot())); 2381 SmiFromSlot(prop->PropertyFeedbackSlot()));
2380 CallLoadIC(NOT_CONTEXTUAL, language_mode()); 2382 CallLoadIC(NOT_CONTEXTUAL, language_mode());
2381 } 2383 }
2382 2384
2383 2385
2384 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2386 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2385 // Stack: receiver, home_object 2387 // Stack: receiver, home_object
2386 SetSourcePosition(prop->position()); 2388 SetExpressionPosition(prop);
2387 Literal* key = prop->key()->AsLiteral(); 2389 Literal* key = prop->key()->AsLiteral();
2388 DCHECK(!key->value()->IsSmi()); 2390 DCHECK(!key->value()->IsSmi());
2389 DCHECK(prop->IsSuperAccess()); 2391 DCHECK(prop->IsSuperAccess());
2390 2392
2391 __ Push(key->value()); 2393 __ Push(key->value());
2392 __ Push(Smi::FromInt(language_mode())); 2394 __ Push(Smi::FromInt(language_mode()));
2393 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2395 __ CallRuntime(Runtime::kLoadFromSuper, 4);
2394 } 2396 }
2395 2397
2396 2398
2397 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2399 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2398 SetSourcePosition(prop->position()); 2400 SetExpressionPosition(prop);
2399 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); 2401 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
2400 __ Move(LoadDescriptor::SlotRegister(), 2402 __ Move(LoadDescriptor::SlotRegister(),
2401 SmiFromSlot(prop->PropertyFeedbackSlot())); 2403 SmiFromSlot(prop->PropertyFeedbackSlot()));
2402 CallIC(ic); 2404 CallIC(ic);
2403 } 2405 }
2404 2406
2405 2407
2406 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2408 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2407 // Stack: receiver, home_object, key. 2409 // Stack: receiver, home_object, key.
2410 SetExpressionPosition(prop);
2408 __ Push(Smi::FromInt(language_mode())); 2411 __ Push(Smi::FromInt(language_mode()));
2409 SetSourcePosition(prop->position());
2410
2411 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2412 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
2412 } 2413 }
2413 2414
2414 2415
2415 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2416 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2416 Token::Value op, 2417 Token::Value op,
2417 Expression* left, 2418 Expression* left,
2418 Expression* right) { 2419 Expression* right) {
2419 // Do combined smi check of the operands. Left operand is on the 2420 // Do combined smi check of the operands. Left operand is on the
2420 // stack (popped into rdx). Right operand is in rax but moved into 2421 // stack (popped into rdx). Right operand is in rax but moved into
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
2727 if (is_strict(language_mode())) { 2728 if (is_strict(language_mode())) {
2728 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2729 __ CallRuntime(Runtime::kThrowConstAssignError, 0);
2729 } 2730 }
2730 // Silently ignore store in sloppy mode. 2731 // Silently ignore store in sloppy mode.
2731 } 2732 }
2732 } 2733 }
2733 2734
2734 2735
2735 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2736 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2736 // Assignment to a property, using a named store IC. 2737 // Assignment to a property, using a named store IC.
2738 SetExpressionPosition(expr);
2737 Property* prop = expr->target()->AsProperty(); 2739 Property* prop = expr->target()->AsProperty();
2738 DCHECK(prop != NULL); 2740 DCHECK(prop != NULL);
2739 DCHECK(prop->key()->IsLiteral()); 2741 DCHECK(prop->key()->IsLiteral());
2740 2742
2741 // Record source code position before IC call.
2742 SetSourcePosition(expr->position());
2743 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2743 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2744 __ Pop(StoreDescriptor::ReceiverRegister()); 2744 __ Pop(StoreDescriptor::ReceiverRegister());
2745 if (FLAG_vector_stores) { 2745 if (FLAG_vector_stores) {
2746 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2746 EmitLoadStoreICSlot(expr->AssignmentSlot());
2747 CallStoreIC(); 2747 CallStoreIC();
2748 } else { 2748 } else {
2749 CallStoreIC(expr->AssignmentFeedbackId()); 2749 CallStoreIC(expr->AssignmentFeedbackId());
2750 } 2750 }
2751 2751
2752 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2752 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 26 matching lines...) Expand all
2779 __ Push(rax); 2779 __ Push(rax);
2780 __ CallRuntime( 2780 __ CallRuntime(
2781 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 2781 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
2782 : Runtime::kStoreKeyedToSuper_Sloppy), 2782 : Runtime::kStoreKeyedToSuper_Sloppy),
2783 4); 2783 4);
2784 } 2784 }
2785 2785
2786 2786
2787 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2787 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2788 // Assignment to a property, using a keyed store IC. 2788 // Assignment to a property, using a keyed store IC.
2789 SetExpressionPosition(expr);
2789 2790
2790 __ Pop(StoreDescriptor::NameRegister()); // Key. 2791 __ Pop(StoreDescriptor::NameRegister()); // Key.
2791 __ Pop(StoreDescriptor::ReceiverRegister()); 2792 __ Pop(StoreDescriptor::ReceiverRegister());
2792 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 2793 DCHECK(StoreDescriptor::ValueRegister().is(rax));
2793 // Record source code position before IC call.
2794 SetSourcePosition(expr->position());
2795 Handle<Code> ic = 2794 Handle<Code> ic =
2796 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2795 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2797 if (FLAG_vector_stores) { 2796 if (FLAG_vector_stores) {
2798 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2797 EmitLoadStoreICSlot(expr->AssignmentSlot());
2799 CallIC(ic); 2798 CallIC(ic);
2800 } else { 2799 } else {
2801 CallIC(ic, expr->AssignmentFeedbackId()); 2800 CallIC(ic, expr->AssignmentFeedbackId());
2802 } 2801 }
2803 2802
2804 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2803 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2805 context()->Plug(rax); 2804 context()->Plug(rax);
2806 } 2805 }
2807 2806
2808 2807
2809 void FullCodeGenerator::VisitProperty(Property* expr) { 2808 void FullCodeGenerator::VisitProperty(Property* expr) {
2810 Comment cmnt(masm_, "[ Property"); 2809 Comment cmnt(masm_, "[ Property");
2810 SetExpressionPosition(expr);
2811
2811 Expression* key = expr->key(); 2812 Expression* key = expr->key();
2812 2813
2813 if (key->IsPropertyName()) { 2814 if (key->IsPropertyName()) {
2814 if (!expr->IsSuperAccess()) { 2815 if (!expr->IsSuperAccess()) {
2815 VisitForAccumulatorValue(expr->obj()); 2816 VisitForAccumulatorValue(expr->obj());
2816 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister())); 2817 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister()));
2817 __ movp(LoadDescriptor::ReceiverRegister(), rax); 2818 __ movp(LoadDescriptor::ReceiverRegister(), rax);
2818 EmitNamedPropertyLoad(expr); 2819 EmitNamedPropertyLoad(expr);
2819 } else { 2820 } else {
2820 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2821 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 2879
2879 EmitCall(expr, call_type); 2880 EmitCall(expr, call_type);
2880 } 2881 }
2881 2882
2882 2883
2883 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2884 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2884 Expression* callee = expr->expression(); 2885 Expression* callee = expr->expression();
2885 DCHECK(callee->IsProperty()); 2886 DCHECK(callee->IsProperty());
2886 Property* prop = callee->AsProperty(); 2887 Property* prop = callee->AsProperty();
2887 DCHECK(prop->IsSuperAccess()); 2888 DCHECK(prop->IsSuperAccess());
2889 SetExpressionPosition(prop);
2888 2890
2889 SetSourcePosition(prop->position());
2890 Literal* key = prop->key()->AsLiteral(); 2891 Literal* key = prop->key()->AsLiteral();
2891 DCHECK(!key->value()->IsSmi()); 2892 DCHECK(!key->value()->IsSmi());
2892 // Load the function from the receiver. 2893 // Load the function from the receiver.
2893 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2894 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2894 VisitForStackValue(super_ref->home_object()); 2895 VisitForStackValue(super_ref->home_object());
2895 VisitForAccumulatorValue(super_ref->this_var()); 2896 VisitForAccumulatorValue(super_ref->this_var());
2896 __ Push(rax); 2897 __ Push(rax);
2897 __ Push(rax); 2898 __ Push(rax);
2898 __ Push(Operand(rsp, kPointerSize * 2)); 2899 __ Push(Operand(rsp, kPointerSize * 2));
2899 __ Push(key->value()); 2900 __ Push(key->value());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2940 EmitCall(expr, CallICState::METHOD); 2941 EmitCall(expr, CallICState::METHOD);
2941 } 2942 }
2942 2943
2943 2944
2944 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2945 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2945 Expression* callee = expr->expression(); 2946 Expression* callee = expr->expression();
2946 DCHECK(callee->IsProperty()); 2947 DCHECK(callee->IsProperty());
2947 Property* prop = callee->AsProperty(); 2948 Property* prop = callee->AsProperty();
2948 DCHECK(prop->IsSuperAccess()); 2949 DCHECK(prop->IsSuperAccess());
2949 2950
2950 SetSourcePosition(prop->position()); 2951 SetExpressionPosition(prop);
2951 // Load the function from the receiver. 2952 // Load the function from the receiver.
2952 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2953 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2953 VisitForStackValue(super_ref->home_object()); 2954 VisitForStackValue(super_ref->home_object());
2954 VisitForAccumulatorValue(super_ref->this_var()); 2955 VisitForAccumulatorValue(super_ref->this_var());
2955 __ Push(rax); 2956 __ Push(rax);
2956 __ Push(rax); 2957 __ Push(rax);
2957 __ Push(Operand(rsp, kPointerSize * 2)); 2958 __ Push(Operand(rsp, kPointerSize * 2));
2958 VisitForStackValue(prop->key()); 2959 VisitForStackValue(prop->key());
2959 __ Push(Smi::FromInt(language_mode())); 2960 __ Push(Smi::FromInt(language_mode()));
2960 2961
(...skipping 13 matching lines...) Expand all
2974 // - target function 2975 // - target function
2975 // - this (receiver) 2976 // - this (receiver)
2976 EmitCall(expr, CallICState::METHOD); 2977 EmitCall(expr, CallICState::METHOD);
2977 } 2978 }
2978 2979
2979 2980
2980 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { 2981 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
2981 // Load the arguments. 2982 // Load the arguments.
2982 ZoneList<Expression*>* args = expr->arguments(); 2983 ZoneList<Expression*>* args = expr->arguments();
2983 int arg_count = args->length(); 2984 int arg_count = args->length();
2984 { PreservePositionScope scope(masm()->positions_recorder()); 2985 for (int i = 0; i < arg_count; i++) {
2985 for (int i = 0; i < arg_count; i++) { 2986 VisitForStackValue(args->at(i));
2986 VisitForStackValue(args->at(i));
2987 }
2988 } 2987 }
2989 2988
2990 // Record source position of the IC call. 2989 SetExpressionPosition(expr);
2991 SetSourcePosition(expr->position());
2992 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); 2990 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
2993 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot())); 2991 __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
2994 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2992 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2995 // Don't assign a type feedback id to the IC, since type feedback is provided 2993 // Don't assign a type feedback id to the IC, since type feedback is provided
2996 // by the vector above. 2994 // by the vector above.
2997 CallIC(ic); 2995 CallIC(ic);
2998 2996
2999 RecordJSReturnSite(expr); 2997 RecordJSReturnSite(expr);
3000 2998
3001 // Restore context register. 2999 // Restore context register.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3040 3038
3041 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); 3039 EmitVariableAssignment(this_var, Token::INIT_CONST, slot);
3042 } 3040 }
3043 3041
3044 3042
3045 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. 3043 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
3046 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { 3044 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
3047 VariableProxy* callee = expr->expression()->AsVariableProxy(); 3045 VariableProxy* callee = expr->expression()->AsVariableProxy();
3048 if (callee->var()->IsLookupSlot()) { 3046 if (callee->var()->IsLookupSlot()) {
3049 Label slow, done; 3047 Label slow, done;
3050 SetSourcePosition(callee->position()); 3048 SetExpressionPosition(callee);
3051 { 3049 // Generate code for loading from variables potentially shadowed by
3052 PreservePositionScope scope(masm()->positions_recorder()); 3050 // eval-introduced variables.
3053 // Generate code for loading from variables potentially shadowed by 3051 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
3054 // eval-introduced variables.
3055 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
3056 }
3057 __ bind(&slow); 3052 __ bind(&slow);
3058 // Call the runtime to find the function to call (returned in rax) and 3053 // Call the runtime to find the function to call (returned in rax) and
3059 // the object holding it (returned in rdx). 3054 // the object holding it (returned in rdx).
3060 __ Push(context_register()); 3055 __ Push(context_register());
3061 __ Push(callee->name()); 3056 __ Push(callee->name());
3062 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 3057 __ CallRuntime(Runtime::kLoadLookupSlot, 2);
3063 __ Push(rax); // Function. 3058 __ Push(rax); // Function.
3064 __ Push(rdx); // Receiver. 3059 __ Push(rdx); // Receiver.
3065 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 3060 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
3066 3061
(...skipping 29 matching lines...) Expand all
3096 Comment cmnt(masm_, "[ Call"); 3091 Comment cmnt(masm_, "[ Call");
3097 Expression* callee = expr->expression(); 3092 Expression* callee = expr->expression();
3098 Call::CallType call_type = expr->GetCallType(isolate()); 3093 Call::CallType call_type = expr->GetCallType(isolate());
3099 3094
3100 if (call_type == Call::POSSIBLY_EVAL_CALL) { 3095 if (call_type == Call::POSSIBLY_EVAL_CALL) {
3101 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 3096 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
3102 // to resolve the function we need to call. Then we call the resolved 3097 // to resolve the function we need to call. Then we call the resolved
3103 // function using the given arguments. 3098 // function using the given arguments.
3104 ZoneList<Expression*>* args = expr->arguments(); 3099 ZoneList<Expression*>* args = expr->arguments();
3105 int arg_count = args->length(); 3100 int arg_count = args->length();
3106 { PreservePositionScope pos_scope(masm()->positions_recorder());
3107 PushCalleeAndWithBaseObject(expr); 3101 PushCalleeAndWithBaseObject(expr);
3108 3102
3109 // Push the arguments. 3103 // Push the arguments.
3110 for (int i = 0; i < arg_count; i++) { 3104 for (int i = 0; i < arg_count; i++) {
3111 VisitForStackValue(args->at(i)); 3105 VisitForStackValue(args->at(i));
3112 } 3106 }
3113 3107
3114 // Push a copy of the function (found below the arguments) and resolve 3108 // Push a copy of the function (found below the arguments) and resolve
3115 // eval. 3109 // eval.
3116 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); 3110 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
3117 EmitResolvePossiblyDirectEval(arg_count); 3111 EmitResolvePossiblyDirectEval(arg_count);
3118 3112
3119 // Touch up the callee. 3113 // Touch up the callee.
3120 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); 3114 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
3121 3115
3122 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 3116 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
3123 }
3124 // Record source position for debugger. 3117 // Record source position for debugger.
3125 SetSourcePosition(expr->position()); 3118 SetExpressionPosition(expr);
3126 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 3119 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
3127 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 3120 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
3128 __ CallStub(&stub); 3121 __ CallStub(&stub);
3129 RecordJSReturnSite(expr); 3122 RecordJSReturnSite(expr);
3130 // Restore context register. 3123 // Restore context register.
3131 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3124 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3132 context()->DropAndPlug(1, rax); 3125 context()->DropAndPlug(1, rax);
3133 } else if (call_type == Call::GLOBAL_CALL) { 3126 } else if (call_type == Call::GLOBAL_CALL) {
3134 EmitCallWithLoadIC(expr); 3127 EmitCallWithLoadIC(expr);
3135 3128
3136 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 3129 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
3137 // Call to a lookup slot (dynamically introduced variable). 3130 // Call to a lookup slot (dynamically introduced variable).
3138 PushCalleeAndWithBaseObject(expr); 3131 PushCalleeAndWithBaseObject(expr);
3139 EmitCall(expr); 3132 EmitCall(expr);
3140 } else if (call_type == Call::PROPERTY_CALL) { 3133 } else if (call_type == Call::PROPERTY_CALL) {
3141 Property* property = callee->AsProperty(); 3134 Property* property = callee->AsProperty();
3142 bool is_named_call = property->key()->IsPropertyName(); 3135 bool is_named_call = property->key()->IsPropertyName();
3143 if (property->IsSuperAccess()) { 3136 if (property->IsSuperAccess()) {
3144 if (is_named_call) { 3137 if (is_named_call) {
3145 EmitSuperCallWithLoadIC(expr); 3138 EmitSuperCallWithLoadIC(expr);
3146 } else { 3139 } else {
3147 EmitKeyedSuperCallWithLoadIC(expr); 3140 EmitKeyedSuperCallWithLoadIC(expr);
3148 } 3141 }
3149 } else { 3142 } else {
3150 {
3151 PreservePositionScope scope(masm()->positions_recorder());
3152 VisitForStackValue(property->obj()); 3143 VisitForStackValue(property->obj());
3153 }
3154 if (is_named_call) { 3144 if (is_named_call) {
3155 EmitCallWithLoadIC(expr); 3145 EmitCallWithLoadIC(expr);
3156 } else { 3146 } else {
3157 EmitKeyedCallWithLoadIC(expr, property->key()); 3147 EmitKeyedCallWithLoadIC(expr, property->key());
3158 } 3148 }
3159 } 3149 }
3160 } else if (call_type == Call::SUPER_CALL) { 3150 } else if (call_type == Call::SUPER_CALL) {
3161 EmitSuperConstructorCall(expr); 3151 EmitSuperConstructorCall(expr);
3162 } else { 3152 } else {
3163 DCHECK(call_type == Call::OTHER_CALL); 3153 DCHECK(call_type == Call::OTHER_CALL);
3164 // Call to an arbitrary expression not handled specially above. 3154 // Call to an arbitrary expression not handled specially above.
3165 { PreservePositionScope scope(masm()->positions_recorder());
3166 VisitForStackValue(callee); 3155 VisitForStackValue(callee);
3167 }
3168 __ PushRoot(Heap::kUndefinedValueRootIndex); 3156 __ PushRoot(Heap::kUndefinedValueRootIndex);
3169 // Emit function call. 3157 // Emit function call.
3170 EmitCall(expr); 3158 EmitCall(expr);
3171 } 3159 }
3172 3160
3173 #ifdef DEBUG 3161 #ifdef DEBUG
3174 // RecordJSReturnSite should have been called. 3162 // RecordJSReturnSite should have been called.
3175 DCHECK(expr->return_is_recorded_); 3163 DCHECK(expr->return_is_recorded_);
3176 #endif 3164 #endif
3177 } 3165 }
(...skipping 13 matching lines...) Expand all
3191 3179
3192 // Push the arguments ("left-to-right") on the stack. 3180 // Push the arguments ("left-to-right") on the stack.
3193 ZoneList<Expression*>* args = expr->arguments(); 3181 ZoneList<Expression*>* args = expr->arguments();
3194 int arg_count = args->length(); 3182 int arg_count = args->length();
3195 for (int i = 0; i < arg_count; i++) { 3183 for (int i = 0; i < arg_count; i++) {
3196 VisitForStackValue(args->at(i)); 3184 VisitForStackValue(args->at(i));
3197 } 3185 }
3198 3186
3199 // Call the construct call builtin that handles allocation and 3187 // Call the construct call builtin that handles allocation and
3200 // constructor invocation. 3188 // constructor invocation.
3201 SetSourcePosition(expr->position()); 3189 SetExpressionPosition(expr);
3202 3190
3203 // Load function and argument count into rdi and rax. 3191 // Load function and argument count into rdi and rax.
3204 __ Set(rax, arg_count); 3192 __ Set(rax, arg_count);
3205 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 3193 __ movp(rdi, Operand(rsp, arg_count * kPointerSize));
3206 3194
3207 // Record call targets in unoptimized code, but not in the snapshot. 3195 // Record call targets in unoptimized code, but not in the snapshot.
3208 if (FLAG_pretenuring_call_new) { 3196 if (FLAG_pretenuring_call_new) {
3209 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 3197 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
3210 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == 3198 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
3211 expr->CallNewFeedbackSlot().ToInt() + 1); 3199 expr->CallNewFeedbackSlot().ToInt() + 1);
(...skipping 22 matching lines...) Expand all
3234 3222
3235 // Push the arguments ("left-to-right") on the stack. 3223 // Push the arguments ("left-to-right") on the stack.
3236 ZoneList<Expression*>* args = expr->arguments(); 3224 ZoneList<Expression*>* args = expr->arguments();
3237 int arg_count = args->length(); 3225 int arg_count = args->length();
3238 for (int i = 0; i < arg_count; i++) { 3226 for (int i = 0; i < arg_count; i++) {
3239 VisitForStackValue(args->at(i)); 3227 VisitForStackValue(args->at(i));
3240 } 3228 }
3241 3229
3242 // Call the construct call builtin that handles allocation and 3230 // Call the construct call builtin that handles allocation and
3243 // constructor invocation. 3231 // constructor invocation.
3244 SetSourcePosition(expr->position()); 3232 SetExpressionPosition(expr);
3245 3233
3246 // Load function and argument count into edi and eax. 3234 // Load function and argument count into edi and eax.
3247 __ Set(rax, arg_count); 3235 __ Set(rax, arg_count);
3248 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 3236 __ movp(rdi, Operand(rsp, arg_count * kPointerSize));
3249 3237
3250 // Record call targets in unoptimized code. 3238 // Record call targets in unoptimized code.
3251 if (FLAG_pretenuring_call_new) { 3239 if (FLAG_pretenuring_call_new) {
3252 UNREACHABLE(); 3240 UNREACHABLE();
3253 /* TODO(dslomov): support pretenuring. 3241 /* TODO(dslomov): support pretenuring.
3254 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 3242 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after
4683 __ Move(LoadDescriptor::SlotRegister(), 4671 __ Move(LoadDescriptor::SlotRegister(),
4684 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); 4672 SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
4685 CallLoadIC(NOT_CONTEXTUAL); 4673 CallLoadIC(NOT_CONTEXTUAL);
4686 } 4674 }
4687 4675
4688 4676
4689 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 4677 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4690 ZoneList<Expression*>* args = expr->arguments(); 4678 ZoneList<Expression*>* args = expr->arguments();
4691 int arg_count = args->length(); 4679 int arg_count = args->length();
4692 4680
4693 // Record source position of the IC call. 4681 SetExpressionPosition(expr);
4694 SetSourcePosition(expr->position());
4695 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4682 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4696 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 4683 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
4697 __ CallStub(&stub); 4684 __ CallStub(&stub);
4698 } 4685 }
4699 4686
4700 4687
4701 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4688 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4702 ZoneList<Expression*>* args = expr->arguments(); 4689 ZoneList<Expression*>* args = expr->arguments();
4703 int arg_count = args->length(); 4690 int arg_count = args->length();
4704 4691
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
4865 default: 4852 default:
4866 UNREACHABLE(); 4853 UNREACHABLE();
4867 } 4854 }
4868 } 4855 }
4869 4856
4870 4857
4871 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4858 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4872 DCHECK(expr->expression()->IsValidReferenceExpression()); 4859 DCHECK(expr->expression()->IsValidReferenceExpression());
4873 4860
4874 Comment cmnt(masm_, "[ CountOperation"); 4861 Comment cmnt(masm_, "[ CountOperation");
4875 SetSourcePosition(expr->position());
4876 4862
4877 Property* prop = expr->expression()->AsProperty(); 4863 Property* prop = expr->expression()->AsProperty();
4878 LhsKind assign_type = Property::GetAssignType(prop); 4864 LhsKind assign_type = Property::GetAssignType(prop);
4879 4865
4880 // Evaluate expression and get value. 4866 // Evaluate expression and get value.
4881 if (assign_type == VARIABLE) { 4867 if (assign_type == VARIABLE) {
4882 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4868 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4883 AccumulatorValueContext context(this); 4869 AccumulatorValueContext context(this);
4884 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4870 EmitVariableLoad(expr->expression()->AsVariableProxy());
4885 } else { 4871 } else {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
5012 case KEYED_PROPERTY: 4998 case KEYED_PROPERTY:
5013 __ movp(Operand(rsp, 2 * kPointerSize), rax); 4999 __ movp(Operand(rsp, 2 * kPointerSize), rax);
5014 break; 5000 break;
5015 case KEYED_SUPER_PROPERTY: 5001 case KEYED_SUPER_PROPERTY:
5016 __ movp(Operand(rsp, 3 * kPointerSize), rax); 5002 __ movp(Operand(rsp, 3 * kPointerSize), rax);
5017 break; 5003 break;
5018 } 5004 }
5019 } 5005 }
5020 } 5006 }
5021 5007
5022 // Record position before stub call. 5008 SetExpressionPosition(expr);
5023 SetSourcePosition(expr->position());
5024 5009
5025 // Call stub for +1/-1. 5010 // Call stub for +1/-1.
5026 __ bind(&stub_call); 5011 __ bind(&stub_call);
5027 __ movp(rdx, rax); 5012 __ movp(rdx, rax);
5028 __ Move(rax, Smi::FromInt(1)); 5013 __ Move(rax, Smi::FromInt(1));
5029 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), 5014 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
5030 strength(language_mode())).code(); 5015 strength(language_mode())).code();
5031 CallIC(code, expr->CountBinOpFeedbackId()); 5016 CallIC(code, expr->CountBinOpFeedbackId());
5032 patch_site.EmitPatchInfo(); 5017 patch_site.EmitPatchInfo();
5033 __ bind(&done); 5018 __ bind(&done);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
5233 Split(zero, if_true, if_false, fall_through); 5218 Split(zero, if_true, if_false, fall_through);
5234 } else { 5219 } else {
5235 if (if_false != fall_through) __ jmp(if_false); 5220 if (if_false != fall_through) __ jmp(if_false);
5236 } 5221 }
5237 context()->Plug(if_true, if_false); 5222 context()->Plug(if_true, if_false);
5238 } 5223 }
5239 5224
5240 5225
5241 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 5226 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
5242 Comment cmnt(masm_, "[ CompareOperation"); 5227 Comment cmnt(masm_, "[ CompareOperation");
5243 SetSourcePosition(expr->position()); 5228 SetExpressionPosition(expr);
5244 5229
5245 // First we try a fast inlined version of the compare when one of 5230 // First we try a fast inlined version of the compare when one of
5246 // the operands is a literal. 5231 // the operands is a literal.
5247 if (TryLiteralCompare(expr)) return; 5232 if (TryLiteralCompare(expr)) return;
5248 5233
5249 // Always perform the comparison for its control flow. Pack the result 5234 // Always perform the comparison for its control flow. Pack the result
5250 // into the expression's context after the comparison is performed. 5235 // into the expression's context after the comparison is performed.
5251 Label materialize_true, materialize_false; 5236 Label materialize_true, materialize_false;
5252 Label* if_true = NULL; 5237 Label* if_true = NULL;
5253 Label* if_false = NULL; 5238 Label* if_false = NULL;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5287 if (inline_smi_code) { 5272 if (inline_smi_code) {
5288 Label slow_case; 5273 Label slow_case;
5289 __ movp(rcx, rdx); 5274 __ movp(rcx, rdx);
5290 __ orp(rcx, rax); 5275 __ orp(rcx, rax);
5291 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); 5276 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear);
5292 __ cmpp(rdx, rax); 5277 __ cmpp(rdx, rax);
5293 Split(cc, if_true, if_false, NULL); 5278 Split(cc, if_true, if_false, NULL);
5294 __ bind(&slow_case); 5279 __ bind(&slow_case);
5295 } 5280 }
5296 5281
5297 // Record position and call the compare IC.
5298 SetSourcePosition(expr->position());
5299 Handle<Code> ic = CodeFactory::CompareIC( 5282 Handle<Code> ic = CodeFactory::CompareIC(
5300 isolate(), op, strength(language_mode())).code(); 5283 isolate(), op, strength(language_mode())).code();
5301 CallIC(ic, expr->CompareOperationFeedbackId()); 5284 CallIC(ic, expr->CompareOperationFeedbackId());
5302 patch_site.EmitPatchInfo(); 5285 patch_site.EmitPatchInfo();
5303 5286
5304 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 5287 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
5305 __ testp(rax, rax); 5288 __ testp(rax, rax);
5306 Split(cc, if_true, if_false, fall_through); 5289 Split(cc, if_true, if_false, fall_through);
5307 } 5290 }
5308 } 5291 }
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
5529 Assembler::target_address_at(call_target_address, 5512 Assembler::target_address_at(call_target_address,
5530 unoptimized_code)); 5513 unoptimized_code));
5531 return OSR_AFTER_STACK_CHECK; 5514 return OSR_AFTER_STACK_CHECK;
5532 } 5515 }
5533 5516
5534 5517
5535 } // namespace internal 5518 } // namespace internal
5536 } // namespace v8 5519 } // namespace v8
5537 5520
5538 #endif // V8_TARGET_ARCH_X64 5521 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/full-codegen.cc ('K') | « src/x64/debug-x64.cc ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698