OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |