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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 __ call(isolate()->builtins()->InterruptCheck(), | 459 __ call(isolate()->builtins()->InterruptCheck(), |
460 RelocInfo::CODE_TARGET); | 460 RelocInfo::CODE_TARGET); |
461 __ pop(eax); | 461 __ pop(eax); |
462 EmitProfilingCounterReset(); | 462 EmitProfilingCounterReset(); |
463 __ bind(&ok); | 463 __ bind(&ok); |
464 #ifdef DEBUG | 464 #ifdef DEBUG |
465 // Add a label for checking the size of the code used for returning. | 465 // Add a label for checking the size of the code used for returning. |
466 Label check_exit_codesize; | 466 Label check_exit_codesize; |
467 masm_->bind(&check_exit_codesize); | 467 masm_->bind(&check_exit_codesize); |
468 #endif | 468 #endif |
469 SetSourcePosition(function()->end_position() - 1); | 469 SetReturnPosition(function()); |
470 __ RecordJSReturn(); | 470 __ RecordJSReturn(); |
471 // Do not use the leave instruction here because it is too short to | 471 // Do not use the leave instruction here because it is too short to |
472 // patch with the code required by the debugger. | 472 // patch with the code required by the debugger. |
473 __ mov(esp, ebp); | 473 __ mov(esp, ebp); |
474 int no_frame_start = masm_->pc_offset(); | 474 int no_frame_start = masm_->pc_offset(); |
475 __ pop(ebp); | 475 __ pop(ebp); |
476 | 476 |
477 int arg_count = info_->scope()->num_parameters() + 1; | 477 int arg_count = info_->scope()->num_parameters() + 1; |
478 int arguments_bytes = arg_count * kPointerSize; | 478 int arguments_bytes = arg_count * kPointerSize; |
479 __ Ret(arguments_bytes, ecx); | 479 __ Ret(arguments_bytes, ecx); |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 __ or_(ecx, eax); | 1011 __ or_(ecx, eax); |
1012 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 1012 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
1013 | 1013 |
1014 __ cmp(edx, eax); | 1014 __ cmp(edx, eax); |
1015 __ j(not_equal, &next_test); | 1015 __ j(not_equal, &next_test); |
1016 __ Drop(1); // Switch value is no longer needed. | 1016 __ Drop(1); // Switch value is no longer needed. |
1017 __ jmp(clause->body_target()); | 1017 __ jmp(clause->body_target()); |
1018 __ bind(&slow_case); | 1018 __ bind(&slow_case); |
1019 } | 1019 } |
1020 | 1020 |
1021 // Record position before stub call for type feedback. | 1021 SetExpressionPosition(clause); |
1022 SetSourcePosition(clause->position()); | |
1023 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, | 1022 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, |
1024 strength(language_mode())).code(); | 1023 strength(language_mode())).code(); |
1025 CallIC(ic, clause->CompareId()); | 1024 CallIC(ic, clause->CompareId()); |
1026 patch_site.EmitPatchInfo(); | 1025 patch_site.EmitPatchInfo(); |
1027 | 1026 |
1028 Label skip; | 1027 Label skip; |
1029 __ jmp(&skip, Label::kNear); | 1028 __ jmp(&skip, Label::kNear); |
1030 PrepareForBailout(clause, TOS_REG); | 1029 PrepareForBailout(clause, TOS_REG); |
1031 __ cmp(eax, isolate()->factory()->true_value()); | 1030 __ cmp(eax, isolate()->factory()->true_value()); |
1032 __ j(not_equal, &next_test); | 1031 __ j(not_equal, &next_test); |
(...skipping 26 matching lines...) Expand all Loading... |
1059 VisitStatements(clause->statements()); | 1058 VisitStatements(clause->statements()); |
1060 } | 1059 } |
1061 | 1060 |
1062 __ bind(nested_statement.break_label()); | 1061 __ bind(nested_statement.break_label()); |
1063 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1062 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1064 } | 1063 } |
1065 | 1064 |
1066 | 1065 |
1067 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1066 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1068 Comment cmnt(masm_, "[ ForInStatement"); | 1067 Comment cmnt(masm_, "[ ForInStatement"); |
| 1068 SetStatementPosition(stmt, SKIP_BREAK); |
| 1069 |
1069 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 1070 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
1070 | 1071 |
1071 SetStatementPosition(stmt); | |
1072 | |
1073 Label loop, exit; | 1072 Label loop, exit; |
1074 ForIn loop_statement(this, stmt); | 1073 ForIn loop_statement(this, stmt); |
1075 increment_loop_depth(); | 1074 increment_loop_depth(); |
1076 | 1075 |
1077 // Get the object to enumerate over. If the object is null or undefined, skip | 1076 // Get the object to enumerate over. If the object is null or undefined, skip |
1078 // over the loop. See ECMA-262 version 5, section 12.6.4. | 1077 // over the loop. See ECMA-262 version 5, section 12.6.4. |
1079 SetExpressionPosition(stmt->enumerable()); | 1078 SetExpressionAsStatementPosition(stmt->enumerable()); |
1080 VisitForAccumulatorValue(stmt->enumerable()); | 1079 VisitForAccumulatorValue(stmt->enumerable()); |
1081 __ cmp(eax, isolate()->factory()->undefined_value()); | 1080 __ cmp(eax, isolate()->factory()->undefined_value()); |
1082 __ j(equal, &exit); | 1081 __ j(equal, &exit); |
1083 __ cmp(eax, isolate()->factory()->null_value()); | 1082 __ cmp(eax, isolate()->factory()->null_value()); |
1084 __ j(equal, &exit); | 1083 __ j(equal, &exit); |
1085 | 1084 |
1086 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1085 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
1087 | 1086 |
1088 // Convert the object to a JS object. | 1087 // Convert the object to a JS object. |
1089 Label convert, done_convert; | 1088 Label convert, done_convert; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 __ bind(&non_proxy); | 1163 __ bind(&non_proxy); |
1165 __ push(ebx); // Smi | 1164 __ push(ebx); // Smi |
1166 __ push(eax); // Array | 1165 __ push(eax); // Array |
1167 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); | 1166 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); |
1168 __ push(eax); // Fixed array length (as smi). | 1167 __ push(eax); // Fixed array length (as smi). |
1169 __ push(Immediate(Smi::FromInt(0))); // Initial index. | 1168 __ push(Immediate(Smi::FromInt(0))); // Initial index. |
1170 | 1169 |
1171 // Generate code for doing the condition check. | 1170 // Generate code for doing the condition check. |
1172 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1171 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
1173 __ bind(&loop); | 1172 __ bind(&loop); |
1174 SetExpressionPosition(stmt->each()); | 1173 SetExpressionAsStatementPosition(stmt->each()); |
1175 | 1174 |
1176 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. | 1175 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. |
1177 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. | 1176 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. |
1178 __ j(above_equal, loop_statement.break_label()); | 1177 __ j(above_equal, loop_statement.break_label()); |
1179 | 1178 |
1180 // Get the current entry of the array into register ebx. | 1179 // Get the current entry of the array into register ebx. |
1181 __ mov(ebx, Operand(esp, 2 * kPointerSize)); | 1180 __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
1182 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); | 1181 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); |
1183 | 1182 |
1184 // Get the expected map from the stack or a smi in the | 1183 // Get the expected map from the stack or a smi in the |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 __ push(Immediate(var->name())); | 1408 __ push(Immediate(var->name())); |
1410 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1409 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
1411 } | 1410 } |
1412 } | 1411 } |
1413 __ jmp(done); | 1412 __ jmp(done); |
1414 } | 1413 } |
1415 } | 1414 } |
1416 | 1415 |
1417 | 1416 |
1418 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1417 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1419 // Record position before possible IC call. | 1418 SetExpressionPosition(proxy); |
1420 SetSourcePosition(proxy->position()); | |
1421 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1419 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
1422 Variable* var = proxy->var(); | 1420 Variable* var = proxy->var(); |
1423 | 1421 |
1424 // Three cases: global variables, lookup variables, and all other types of | 1422 // Three cases: global variables, lookup variables, and all other types of |
1425 // variables. | 1423 // variables. |
1426 switch (var->location()) { | 1424 switch (var->location()) { |
1427 case VariableLocation::GLOBAL: | 1425 case VariableLocation::GLOBAL: |
1428 case VariableLocation::UNALLOCATED: { | 1426 case VariableLocation::UNALLOCATED: { |
1429 Comment cmnt(masm_, "[ Global variable"); | 1427 Comment cmnt(masm_, "[ Global variable"); |
1430 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1428 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 } else { | 1905 } else { |
1908 context()->Plug(eax); | 1906 context()->Plug(eax); |
1909 } | 1907 } |
1910 } | 1908 } |
1911 | 1909 |
1912 | 1910 |
1913 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1911 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1914 DCHECK(expr->target()->IsValidReferenceExpression()); | 1912 DCHECK(expr->target()->IsValidReferenceExpression()); |
1915 | 1913 |
1916 Comment cmnt(masm_, "[ Assignment"); | 1914 Comment cmnt(masm_, "[ Assignment"); |
| 1915 SetExpressionPosition(expr, INSERT_BREAK); |
1917 | 1916 |
1918 Property* property = expr->target()->AsProperty(); | 1917 Property* property = expr->target()->AsProperty(); |
1919 LhsKind assign_type = Property::GetAssignType(property); | 1918 LhsKind assign_type = Property::GetAssignType(property); |
1920 | 1919 |
1921 // Evaluate LHS expression. | 1920 // Evaluate LHS expression. |
1922 switch (assign_type) { | 1921 switch (assign_type) { |
1923 case VARIABLE: | 1922 case VARIABLE: |
1924 // Nothing to do here. | 1923 // Nothing to do here. |
1925 break; | 1924 break; |
1926 case NAMED_SUPER_PROPERTY: | 1925 case NAMED_SUPER_PROPERTY: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 EmitKeyedPropertyLoad(property); | 1995 EmitKeyedPropertyLoad(property); |
1997 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1996 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1998 break; | 1997 break; |
1999 } | 1998 } |
2000 } | 1999 } |
2001 | 2000 |
2002 Token::Value op = expr->binary_op(); | 2001 Token::Value op = expr->binary_op(); |
2003 __ push(eax); // Left operand goes on the stack. | 2002 __ push(eax); // Left operand goes on the stack. |
2004 VisitForAccumulatorValue(expr->value()); | 2003 VisitForAccumulatorValue(expr->value()); |
2005 | 2004 |
2006 SetSourcePosition(expr->position() + 1); | |
2007 if (ShouldInlineSmiCase(op)) { | 2005 if (ShouldInlineSmiCase(op)) { |
2008 EmitInlineSmiBinaryOp(expr->binary_operation(), | 2006 EmitInlineSmiBinaryOp(expr->binary_operation(), |
2009 op, | 2007 op, |
2010 expr->target(), | 2008 expr->target(), |
2011 expr->value()); | 2009 expr->value()); |
2012 } else { | 2010 } else { |
2013 EmitBinaryOp(expr->binary_operation(), op); | 2011 EmitBinaryOp(expr->binary_operation(), op); |
2014 } | 2012 } |
2015 | 2013 |
2016 // Deoptimization point in case the binary operation may have side effects. | 2014 // Deoptimization point in case the binary operation may have side effects. |
2017 PrepareForBailout(expr->binary_operation(), TOS_REG); | 2015 PrepareForBailout(expr->binary_operation(), TOS_REG); |
2018 } else { | 2016 } else { |
2019 VisitForAccumulatorValue(expr->value()); | 2017 VisitForAccumulatorValue(expr->value()); |
2020 } | 2018 } |
2021 | 2019 |
2022 // Record source position before possible IC call. | 2020 SetExpressionPosition(expr); |
2023 SetSourcePosition(expr->position()); | |
2024 | 2021 |
2025 // Store the value. | 2022 // Store the value. |
2026 switch (assign_type) { | 2023 switch (assign_type) { |
2027 case VARIABLE: | 2024 case VARIABLE: |
2028 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2025 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
2029 expr->op(), expr->AssignmentSlot()); | 2026 expr->op(), expr->AssignmentSlot()); |
2030 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2027 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2031 context()->Plug(eax); | 2028 context()->Plug(eax); |
2032 break; | 2029 break; |
2033 case NAMED_PROPERTY: | 2030 case NAMED_PROPERTY: |
2034 EmitNamedPropertyAssignment(expr); | 2031 EmitNamedPropertyAssignment(expr); |
2035 break; | 2032 break; |
2036 case NAMED_SUPER_PROPERTY: | 2033 case NAMED_SUPER_PROPERTY: |
2037 EmitNamedSuperPropertyStore(property); | 2034 EmitNamedSuperPropertyStore(property); |
2038 context()->Plug(result_register()); | 2035 context()->Plug(result_register()); |
2039 break; | 2036 break; |
2040 case KEYED_SUPER_PROPERTY: | 2037 case KEYED_SUPER_PROPERTY: |
2041 EmitKeyedSuperPropertyStore(property); | 2038 EmitKeyedSuperPropertyStore(property); |
2042 context()->Plug(result_register()); | 2039 context()->Plug(result_register()); |
2043 break; | 2040 break; |
2044 case KEYED_PROPERTY: | 2041 case KEYED_PROPERTY: |
2045 EmitKeyedPropertyAssignment(expr); | 2042 EmitKeyedPropertyAssignment(expr); |
2046 break; | 2043 break; |
2047 } | 2044 } |
2048 } | 2045 } |
2049 | 2046 |
2050 | 2047 |
2051 void FullCodeGenerator::VisitYield(Yield* expr) { | 2048 void FullCodeGenerator::VisitYield(Yield* expr) { |
2052 Comment cmnt(masm_, "[ Yield"); | 2049 Comment cmnt(masm_, "[ Yield"); |
| 2050 SetExpressionPosition(expr); |
| 2051 |
2053 // Evaluate yielded value first; the initial iterator definition depends on | 2052 // Evaluate yielded value first; the initial iterator definition depends on |
2054 // this. It stays on the stack while we update the iterator. | 2053 // this. It stays on the stack while we update the iterator. |
2055 VisitForStackValue(expr->expression()); | 2054 VisitForStackValue(expr->expression()); |
2056 | 2055 |
2057 switch (expr->yield_kind()) { | 2056 switch (expr->yield_kind()) { |
2058 case Yield::kSuspend: | 2057 case Yield::kSuspend: |
2059 // Pop value from top-of-stack slot; box result into result register. | 2058 // Pop value from top-of-stack slot; box result into result register. |
2060 EmitCreateIteratorResult(false); | 2059 EmitCreateIteratorResult(false); |
2061 __ push(result_register()); | 2060 __ push(result_register()); |
2062 // Fall through. | 2061 // Fall through. |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2328 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); | 2327 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); |
2329 | 2328 |
2330 // Only the value field needs a write barrier, as the other values are in the | 2329 // Only the value field needs a write barrier, as the other values are in the |
2331 // root set. | 2330 // root set. |
2332 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, ecx, | 2331 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, ecx, |
2333 edx, kDontSaveFPRegs); | 2332 edx, kDontSaveFPRegs); |
2334 } | 2333 } |
2335 | 2334 |
2336 | 2335 |
2337 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2336 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2338 SetSourcePosition(prop->position()); | 2337 SetExpressionPosition(prop); |
2339 Literal* key = prop->key()->AsLiteral(); | 2338 Literal* key = prop->key()->AsLiteral(); |
2340 DCHECK(!key->value()->IsSmi()); | 2339 DCHECK(!key->value()->IsSmi()); |
2341 DCHECK(!prop->IsSuperAccess()); | 2340 DCHECK(!prop->IsSuperAccess()); |
2342 | 2341 |
2343 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); | 2342 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); |
2344 __ mov(LoadDescriptor::SlotRegister(), | 2343 __ mov(LoadDescriptor::SlotRegister(), |
2345 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2344 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
2346 CallLoadIC(NOT_CONTEXTUAL, language_mode()); | 2345 CallLoadIC(NOT_CONTEXTUAL, language_mode()); |
2347 } | 2346 } |
2348 | 2347 |
2349 | 2348 |
2350 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2349 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
2351 // Stack: receiver, home_object. | 2350 // Stack: receiver, home_object. |
2352 SetSourcePosition(prop->position()); | 2351 SetExpressionPosition(prop); |
2353 Literal* key = prop->key()->AsLiteral(); | 2352 Literal* key = prop->key()->AsLiteral(); |
2354 DCHECK(!key->value()->IsSmi()); | 2353 DCHECK(!key->value()->IsSmi()); |
2355 DCHECK(prop->IsSuperAccess()); | 2354 DCHECK(prop->IsSuperAccess()); |
2356 | 2355 |
2357 __ push(Immediate(key->value())); | 2356 __ push(Immediate(key->value())); |
2358 __ push(Immediate(Smi::FromInt(language_mode()))); | 2357 __ push(Immediate(Smi::FromInt(language_mode()))); |
2359 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2358 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
2360 } | 2359 } |
2361 | 2360 |
2362 | 2361 |
2363 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2362 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2364 SetSourcePosition(prop->position()); | 2363 SetExpressionPosition(prop); |
2365 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); | 2364 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); |
2366 __ mov(LoadDescriptor::SlotRegister(), | 2365 __ mov(LoadDescriptor::SlotRegister(), |
2367 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2366 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
2368 CallIC(ic); | 2367 CallIC(ic); |
2369 } | 2368 } |
2370 | 2369 |
2371 | 2370 |
2372 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2371 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
2373 // Stack: receiver, home_object, key. | 2372 // Stack: receiver, home_object, key. |
| 2373 SetExpressionPosition(prop); |
2374 __ push(Immediate(Smi::FromInt(language_mode()))); | 2374 __ push(Immediate(Smi::FromInt(language_mode()))); |
2375 SetSourcePosition(prop->position()); | |
2376 | |
2377 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2375 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
2378 } | 2376 } |
2379 | 2377 |
2380 | 2378 |
2381 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2379 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2382 Token::Value op, | 2380 Token::Value op, |
2383 Expression* left, | 2381 Expression* left, |
2384 Expression* right) { | 2382 Expression* right) { |
2385 // Do combined smi check of the operands. Left operand is on the | 2383 // Do combined smi check of the operands. Left operand is on the |
2386 // stack. Right operand is in eax. | 2384 // stack. Right operand is in eax. |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2726 } | 2724 } |
2727 // Silently ignore store in sloppy mode. | 2725 // Silently ignore store in sloppy mode. |
2728 } | 2726 } |
2729 } | 2727 } |
2730 | 2728 |
2731 | 2729 |
2732 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2730 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2733 // Assignment to a property, using a named store IC. | 2731 // Assignment to a property, using a named store IC. |
2734 // eax : value | 2732 // eax : value |
2735 // esp[0] : receiver | 2733 // esp[0] : receiver |
2736 | |
2737 Property* prop = expr->target()->AsProperty(); | 2734 Property* prop = expr->target()->AsProperty(); |
2738 DCHECK(prop != NULL); | 2735 DCHECK(prop != NULL); |
2739 DCHECK(prop->key()->IsLiteral()); | 2736 DCHECK(prop->key()->IsLiteral()); |
2740 | 2737 |
2741 // Record source code position before IC call. | |
2742 SetSourcePosition(expr->position()); | |
2743 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2738 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2744 __ pop(StoreDescriptor::ReceiverRegister()); | 2739 __ pop(StoreDescriptor::ReceiverRegister()); |
2745 if (FLAG_vector_stores) { | 2740 if (FLAG_vector_stores) { |
2746 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2741 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2747 CallStoreIC(); | 2742 CallStoreIC(); |
2748 } else { | 2743 } else { |
2749 CallStoreIC(expr->AssignmentFeedbackId()); | 2744 CallStoreIC(expr->AssignmentFeedbackId()); |
2750 } | 2745 } |
2751 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2746 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2752 context()->Plug(eax); | 2747 context()->Plug(eax); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2784 | 2779 |
2785 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2780 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2786 // Assignment to a property, using a keyed store IC. | 2781 // Assignment to a property, using a keyed store IC. |
2787 // eax : value | 2782 // eax : value |
2788 // esp[0] : key | 2783 // esp[0] : key |
2789 // esp[kPointerSize] : receiver | 2784 // esp[kPointerSize] : receiver |
2790 | 2785 |
2791 __ pop(StoreDescriptor::NameRegister()); // Key. | 2786 __ pop(StoreDescriptor::NameRegister()); // Key. |
2792 __ pop(StoreDescriptor::ReceiverRegister()); | 2787 __ pop(StoreDescriptor::ReceiverRegister()); |
2793 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2788 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2794 // Record source code position before IC call. | |
2795 SetSourcePosition(expr->position()); | |
2796 Handle<Code> ic = | 2789 Handle<Code> ic = |
2797 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2790 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2798 if (FLAG_vector_stores) { | 2791 if (FLAG_vector_stores) { |
2799 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2792 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2800 CallIC(ic); | 2793 CallIC(ic); |
2801 } else { | 2794 } else { |
2802 CallIC(ic, expr->AssignmentFeedbackId()); | 2795 CallIC(ic, expr->AssignmentFeedbackId()); |
2803 } | 2796 } |
2804 | 2797 |
2805 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2798 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2806 context()->Plug(eax); | 2799 context()->Plug(eax); |
2807 } | 2800 } |
2808 | 2801 |
2809 | 2802 |
2810 void FullCodeGenerator::VisitProperty(Property* expr) { | 2803 void FullCodeGenerator::VisitProperty(Property* expr) { |
2811 Comment cmnt(masm_, "[ Property"); | 2804 Comment cmnt(masm_, "[ Property"); |
| 2805 SetExpressionPosition(expr); |
| 2806 |
2812 Expression* key = expr->key(); | 2807 Expression* key = expr->key(); |
2813 | 2808 |
2814 if (key->IsPropertyName()) { | 2809 if (key->IsPropertyName()) { |
2815 if (!expr->IsSuperAccess()) { | 2810 if (!expr->IsSuperAccess()) { |
2816 VisitForAccumulatorValue(expr->obj()); | 2811 VisitForAccumulatorValue(expr->obj()); |
2817 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2812 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
2818 EmitNamedPropertyLoad(expr); | 2813 EmitNamedPropertyLoad(expr); |
2819 } else { | 2814 } else { |
2820 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2815 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2821 VisitForStackValue( | 2816 VisitForStackValue( |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2874 // Push the target function under the receiver. | 2869 // Push the target function under the receiver. |
2875 __ push(Operand(esp, 0)); | 2870 __ push(Operand(esp, 0)); |
2876 __ mov(Operand(esp, kPointerSize), eax); | 2871 __ mov(Operand(esp, kPointerSize), eax); |
2877 } | 2872 } |
2878 | 2873 |
2879 EmitCall(expr, call_type); | 2874 EmitCall(expr, call_type); |
2880 } | 2875 } |
2881 | 2876 |
2882 | 2877 |
2883 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2878 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2879 SetExpressionPosition(expr); |
2884 Expression* callee = expr->expression(); | 2880 Expression* callee = expr->expression(); |
2885 DCHECK(callee->IsProperty()); | 2881 DCHECK(callee->IsProperty()); |
2886 Property* prop = callee->AsProperty(); | 2882 Property* prop = callee->AsProperty(); |
2887 DCHECK(prop->IsSuperAccess()); | 2883 DCHECK(prop->IsSuperAccess()); |
2888 | 2884 |
2889 SetSourcePosition(prop->position()); | |
2890 Literal* key = prop->key()->AsLiteral(); | 2885 Literal* key = prop->key()->AsLiteral(); |
2891 DCHECK(!key->value()->IsSmi()); | 2886 DCHECK(!key->value()->IsSmi()); |
2892 // Load the function from the receiver. | 2887 // Load the function from the receiver. |
2893 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2888 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2894 VisitForStackValue(super_ref->home_object()); | 2889 VisitForStackValue(super_ref->home_object()); |
2895 VisitForAccumulatorValue(super_ref->this_var()); | 2890 VisitForAccumulatorValue(super_ref->this_var()); |
2896 __ push(eax); | 2891 __ push(eax); |
2897 __ push(eax); | 2892 __ push(eax); |
2898 __ push(Operand(esp, kPointerSize * 2)); | 2893 __ push(Operand(esp, kPointerSize * 2)); |
2899 __ push(Immediate(key->value())); | 2894 __ push(Immediate(key->value())); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2939 EmitCall(expr, CallICState::METHOD); | 2934 EmitCall(expr, CallICState::METHOD); |
2940 } | 2935 } |
2941 | 2936 |
2942 | 2937 |
2943 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2938 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2944 Expression* callee = expr->expression(); | 2939 Expression* callee = expr->expression(); |
2945 DCHECK(callee->IsProperty()); | 2940 DCHECK(callee->IsProperty()); |
2946 Property* prop = callee->AsProperty(); | 2941 Property* prop = callee->AsProperty(); |
2947 DCHECK(prop->IsSuperAccess()); | 2942 DCHECK(prop->IsSuperAccess()); |
2948 | 2943 |
2949 SetSourcePosition(prop->position()); | 2944 SetExpressionPosition(prop); |
2950 // Load the function from the receiver. | 2945 // Load the function from the receiver. |
2951 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2946 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2952 VisitForStackValue(super_ref->home_object()); | 2947 VisitForStackValue(super_ref->home_object()); |
2953 VisitForAccumulatorValue(super_ref->this_var()); | 2948 VisitForAccumulatorValue(super_ref->this_var()); |
2954 __ push(eax); | 2949 __ push(eax); |
2955 __ push(eax); | 2950 __ push(eax); |
2956 __ push(Operand(esp, kPointerSize * 2)); | 2951 __ push(Operand(esp, kPointerSize * 2)); |
2957 VisitForStackValue(prop->key()); | 2952 VisitForStackValue(prop->key()); |
2958 __ push(Immediate(Smi::FromInt(language_mode()))); | 2953 __ push(Immediate(Smi::FromInt(language_mode()))); |
2959 // Stack here: | 2954 // Stack here: |
(...skipping 12 matching lines...) Expand all Loading... |
2972 // - target function | 2967 // - target function |
2973 // - this (receiver) | 2968 // - this (receiver) |
2974 EmitCall(expr, CallICState::METHOD); | 2969 EmitCall(expr, CallICState::METHOD); |
2975 } | 2970 } |
2976 | 2971 |
2977 | 2972 |
2978 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 2973 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
2979 // Load the arguments. | 2974 // Load the arguments. |
2980 ZoneList<Expression*>* args = expr->arguments(); | 2975 ZoneList<Expression*>* args = expr->arguments(); |
2981 int arg_count = args->length(); | 2976 int arg_count = args->length(); |
2982 { PreservePositionScope scope(masm()->positions_recorder()); | 2977 for (int i = 0; i < arg_count; i++) { |
2983 for (int i = 0; i < arg_count; i++) { | 2978 VisitForStackValue(args->at(i)); |
2984 VisitForStackValue(args->at(i)); | |
2985 } | |
2986 } | 2979 } |
2987 | 2980 |
2988 // Record source position of the IC call. | 2981 SetExpressionPosition(expr); |
2989 SetSourcePosition(expr->position()); | |
2990 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 2982 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); |
2991 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2983 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2992 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2984 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2993 // Don't assign a type feedback id to the IC, since type feedback is provided | 2985 // Don't assign a type feedback id to the IC, since type feedback is provided |
2994 // by the vector above. | 2986 // by the vector above. |
2995 CallIC(ic); | 2987 CallIC(ic); |
2996 | 2988 |
2997 RecordJSReturnSite(expr); | 2989 RecordJSReturnSite(expr); |
2998 | 2990 |
2999 // Restore context register. | 2991 // Restore context register. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3039 | 3031 |
3040 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3032 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3041 } | 3033 } |
3042 | 3034 |
3043 | 3035 |
3044 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3036 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3045 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3037 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3046 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3038 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3047 if (callee->var()->IsLookupSlot()) { | 3039 if (callee->var()->IsLookupSlot()) { |
3048 Label slow, done; | 3040 Label slow, done; |
3049 SetSourcePosition(callee->position()); | 3041 SetExpressionPosition(callee); |
3050 { | 3042 // Generate code for loading from variables potentially shadowed by |
3051 PreservePositionScope scope(masm()->positions_recorder()); | 3043 // eval-introduced variables. |
3052 // Generate code for loading from variables potentially shadowed by | 3044 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3053 // eval-introduced variables. | 3045 |
3054 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | |
3055 } | |
3056 __ bind(&slow); | 3046 __ bind(&slow); |
3057 // Call the runtime to find the function to call (returned in eax) and | 3047 // Call the runtime to find the function to call (returned in eax) and |
3058 // the object holding it (returned in edx). | 3048 // the object holding it (returned in edx). |
3059 __ push(context_register()); | 3049 __ push(context_register()); |
3060 __ push(Immediate(callee->name())); | 3050 __ push(Immediate(callee->name())); |
3061 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 3051 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
3062 __ push(eax); // Function. | 3052 __ push(eax); // Function. |
3063 __ push(edx); // Receiver. | 3053 __ push(edx); // Receiver. |
3064 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 3054 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
3065 | 3055 |
(...skipping 28 matching lines...) Expand all Loading... |
3094 Comment cmnt(masm_, "[ Call"); | 3084 Comment cmnt(masm_, "[ Call"); |
3095 Expression* callee = expr->expression(); | 3085 Expression* callee = expr->expression(); |
3096 Call::CallType call_type = expr->GetCallType(isolate()); | 3086 Call::CallType call_type = expr->GetCallType(isolate()); |
3097 | 3087 |
3098 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3088 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
3099 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3089 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
3100 // to resolve the function we need to call. Then we call the resolved | 3090 // to resolve the function we need to call. Then we call the resolved |
3101 // function using the given arguments. | 3091 // function using the given arguments. |
3102 ZoneList<Expression*>* args = expr->arguments(); | 3092 ZoneList<Expression*>* args = expr->arguments(); |
3103 int arg_count = args->length(); | 3093 int arg_count = args->length(); |
3104 { PreservePositionScope pos_scope(masm()->positions_recorder()); | |
3105 PushCalleeAndWithBaseObject(expr); | |
3106 | 3094 |
3107 // Push the arguments. | 3095 PushCalleeAndWithBaseObject(expr); |
3108 for (int i = 0; i < arg_count; i++) { | |
3109 VisitForStackValue(args->at(i)); | |
3110 } | |
3111 | 3096 |
3112 // Push a copy of the function (found below the arguments) and | 3097 // Push the arguments. |
3113 // resolve eval. | 3098 for (int i = 0; i < arg_count; i++) { |
3114 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); | 3099 VisitForStackValue(args->at(i)); |
3115 EmitResolvePossiblyDirectEval(arg_count); | 3100 } |
3116 | 3101 |
3117 // Touch up the stack with the resolved function. | 3102 // Push a copy of the function (found below the arguments) and |
3118 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); | 3103 // resolve eval. |
| 3104 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); |
| 3105 EmitResolvePossiblyDirectEval(arg_count); |
3119 | 3106 |
3120 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 3107 // Touch up the stack with the resolved function. |
3121 } | 3108 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); |
3122 // Record source position for debugger. | 3109 |
3123 SetSourcePosition(expr->position()); | 3110 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
| 3111 |
| 3112 SetExpressionPosition(expr); |
3124 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3113 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
3125 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 3114 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
3126 __ CallStub(&stub); | 3115 __ CallStub(&stub); |
3127 RecordJSReturnSite(expr); | 3116 RecordJSReturnSite(expr); |
3128 // Restore context register. | 3117 // Restore context register. |
3129 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3118 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
3130 context()->DropAndPlug(1, eax); | 3119 context()->DropAndPlug(1, eax); |
3131 | 3120 |
3132 } else if (call_type == Call::GLOBAL_CALL) { | 3121 } else if (call_type == Call::GLOBAL_CALL) { |
3133 EmitCallWithLoadIC(expr); | 3122 EmitCallWithLoadIC(expr); |
3134 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 3123 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
3135 // Call to a lookup slot (dynamically introduced variable). | 3124 // Call to a lookup slot (dynamically introduced variable). |
3136 PushCalleeAndWithBaseObject(expr); | 3125 PushCalleeAndWithBaseObject(expr); |
3137 EmitCall(expr); | 3126 EmitCall(expr); |
3138 } else if (call_type == Call::PROPERTY_CALL) { | 3127 } else if (call_type == Call::PROPERTY_CALL) { |
3139 Property* property = callee->AsProperty(); | 3128 Property* property = callee->AsProperty(); |
3140 bool is_named_call = property->key()->IsPropertyName(); | 3129 bool is_named_call = property->key()->IsPropertyName(); |
3141 if (property->IsSuperAccess()) { | 3130 if (property->IsSuperAccess()) { |
3142 if (is_named_call) { | 3131 if (is_named_call) { |
3143 EmitSuperCallWithLoadIC(expr); | 3132 EmitSuperCallWithLoadIC(expr); |
3144 } else { | 3133 } else { |
3145 EmitKeyedSuperCallWithLoadIC(expr); | 3134 EmitKeyedSuperCallWithLoadIC(expr); |
3146 } | 3135 } |
3147 } else { | 3136 } else { |
3148 { | 3137 VisitForStackValue(property->obj()); |
3149 PreservePositionScope scope(masm()->positions_recorder()); | |
3150 VisitForStackValue(property->obj()); | |
3151 } | |
3152 if (is_named_call) { | 3138 if (is_named_call) { |
3153 EmitCallWithLoadIC(expr); | 3139 EmitCallWithLoadIC(expr); |
3154 } else { | 3140 } else { |
3155 EmitKeyedCallWithLoadIC(expr, property->key()); | 3141 EmitKeyedCallWithLoadIC(expr, property->key()); |
3156 } | 3142 } |
3157 } | 3143 } |
3158 } else if (call_type == Call::SUPER_CALL) { | 3144 } else if (call_type == Call::SUPER_CALL) { |
3159 EmitSuperConstructorCall(expr); | 3145 EmitSuperConstructorCall(expr); |
3160 } else { | 3146 } else { |
3161 DCHECK(call_type == Call::OTHER_CALL); | 3147 DCHECK(call_type == Call::OTHER_CALL); |
3162 // Call to an arbitrary expression not handled specially above. | 3148 // Call to an arbitrary expression not handled specially above. |
3163 { PreservePositionScope scope(masm()->positions_recorder()); | 3149 VisitForStackValue(callee); |
3164 VisitForStackValue(callee); | |
3165 } | |
3166 __ push(Immediate(isolate()->factory()->undefined_value())); | 3150 __ push(Immediate(isolate()->factory()->undefined_value())); |
3167 // Emit function call. | 3151 // Emit function call. |
3168 EmitCall(expr); | 3152 EmitCall(expr); |
3169 } | 3153 } |
3170 | 3154 |
3171 #ifdef DEBUG | 3155 #ifdef DEBUG |
3172 // RecordJSReturnSite should have been called. | 3156 // RecordJSReturnSite should have been called. |
3173 DCHECK(expr->return_is_recorded_); | 3157 DCHECK(expr->return_is_recorded_); |
3174 #endif | 3158 #endif |
3175 } | 3159 } |
(...skipping 13 matching lines...) Expand all Loading... |
3189 | 3173 |
3190 // Push the arguments ("left-to-right") on the stack. | 3174 // Push the arguments ("left-to-right") on the stack. |
3191 ZoneList<Expression*>* args = expr->arguments(); | 3175 ZoneList<Expression*>* args = expr->arguments(); |
3192 int arg_count = args->length(); | 3176 int arg_count = args->length(); |
3193 for (int i = 0; i < arg_count; i++) { | 3177 for (int i = 0; i < arg_count; i++) { |
3194 VisitForStackValue(args->at(i)); | 3178 VisitForStackValue(args->at(i)); |
3195 } | 3179 } |
3196 | 3180 |
3197 // Call the construct call builtin that handles allocation and | 3181 // Call the construct call builtin that handles allocation and |
3198 // constructor invocation. | 3182 // constructor invocation. |
3199 SetSourcePosition(expr->position()); | 3183 SetExpressionPosition(expr); |
3200 | 3184 |
3201 // Load function and argument count into edi and eax. | 3185 // Load function and argument count into edi and eax. |
3202 __ Move(eax, Immediate(arg_count)); | 3186 __ Move(eax, Immediate(arg_count)); |
3203 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 3187 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
3204 | 3188 |
3205 // Record call targets in unoptimized code. | 3189 // Record call targets in unoptimized code. |
3206 if (FLAG_pretenuring_call_new) { | 3190 if (FLAG_pretenuring_call_new) { |
3207 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3191 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
3208 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == | 3192 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == |
3209 expr->CallNewFeedbackSlot().ToInt() + 1); | 3193 expr->CallNewFeedbackSlot().ToInt() + 1); |
(...skipping 22 matching lines...) Expand all Loading... |
3232 | 3216 |
3233 // Push the arguments ("left-to-right") on the stack. | 3217 // Push the arguments ("left-to-right") on the stack. |
3234 ZoneList<Expression*>* args = expr->arguments(); | 3218 ZoneList<Expression*>* args = expr->arguments(); |
3235 int arg_count = args->length(); | 3219 int arg_count = args->length(); |
3236 for (int i = 0; i < arg_count; i++) { | 3220 for (int i = 0; i < arg_count; i++) { |
3237 VisitForStackValue(args->at(i)); | 3221 VisitForStackValue(args->at(i)); |
3238 } | 3222 } |
3239 | 3223 |
3240 // Call the construct call builtin that handles allocation and | 3224 // Call the construct call builtin that handles allocation and |
3241 // constructor invocation. | 3225 // constructor invocation. |
3242 SetSourcePosition(expr->position()); | 3226 SetExpressionPosition(expr); |
3243 | 3227 |
3244 // Load function and argument count into edi and eax. | 3228 // Load function and argument count into edi and eax. |
3245 __ Move(eax, Immediate(arg_count)); | 3229 __ Move(eax, Immediate(arg_count)); |
3246 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 3230 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
3247 | 3231 |
3248 // Record call targets in unoptimized code. | 3232 // Record call targets in unoptimized code. |
3249 if (FLAG_pretenuring_call_new) { | 3233 if (FLAG_pretenuring_call_new) { |
3250 UNREACHABLE(); | 3234 UNREACHABLE(); |
3251 /* TODO(dslomov): support pretenuring. | 3235 /* TODO(dslomov): support pretenuring. |
3252 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3236 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4654 __ mov(LoadDescriptor::SlotRegister(), | 4638 __ mov(LoadDescriptor::SlotRegister(), |
4655 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | 4639 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
4656 CallLoadIC(NOT_CONTEXTUAL); | 4640 CallLoadIC(NOT_CONTEXTUAL); |
4657 } | 4641 } |
4658 | 4642 |
4659 | 4643 |
4660 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4644 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4661 ZoneList<Expression*>* args = expr->arguments(); | 4645 ZoneList<Expression*>* args = expr->arguments(); |
4662 int arg_count = args->length(); | 4646 int arg_count = args->length(); |
4663 | 4647 |
4664 // Record source position of the IC call. | 4648 SetExpressionPosition(expr); |
4665 SetSourcePosition(expr->position()); | |
4666 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4649 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
4667 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 4650 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
4668 __ CallStub(&stub); | 4651 __ CallStub(&stub); |
4669 } | 4652 } |
4670 | 4653 |
4671 | 4654 |
4672 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4655 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4673 ZoneList<Expression*>* args = expr->arguments(); | 4656 ZoneList<Expression*>* args = expr->arguments(); |
4674 int arg_count = args->length(); | 4657 int arg_count = args->length(); |
4675 | 4658 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4835 default: | 4818 default: |
4836 UNREACHABLE(); | 4819 UNREACHABLE(); |
4837 } | 4820 } |
4838 } | 4821 } |
4839 | 4822 |
4840 | 4823 |
4841 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4824 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4842 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4825 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4843 | 4826 |
4844 Comment cmnt(masm_, "[ CountOperation"); | 4827 Comment cmnt(masm_, "[ CountOperation"); |
4845 SetSourcePosition(expr->position()); | |
4846 | 4828 |
4847 Property* prop = expr->expression()->AsProperty(); | 4829 Property* prop = expr->expression()->AsProperty(); |
4848 LhsKind assign_type = Property::GetAssignType(prop); | 4830 LhsKind assign_type = Property::GetAssignType(prop); |
4849 | 4831 |
4850 // Evaluate expression and get value. | 4832 // Evaluate expression and get value. |
4851 if (assign_type == VARIABLE) { | 4833 if (assign_type == VARIABLE) { |
4852 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4834 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4853 AccumulatorValueContext context(this); | 4835 AccumulatorValueContext context(this); |
4854 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4836 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4855 } else { | 4837 } else { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4986 case KEYED_PROPERTY: | 4968 case KEYED_PROPERTY: |
4987 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4969 __ mov(Operand(esp, 2 * kPointerSize), eax); |
4988 break; | 4970 break; |
4989 case KEYED_SUPER_PROPERTY: | 4971 case KEYED_SUPER_PROPERTY: |
4990 __ mov(Operand(esp, 3 * kPointerSize), eax); | 4972 __ mov(Operand(esp, 3 * kPointerSize), eax); |
4991 break; | 4973 break; |
4992 } | 4974 } |
4993 } | 4975 } |
4994 } | 4976 } |
4995 | 4977 |
4996 // Record position before stub call. | 4978 SetExpressionPosition(expr); |
4997 SetSourcePosition(expr->position()); | |
4998 | 4979 |
4999 // Call stub for +1/-1. | 4980 // Call stub for +1/-1. |
5000 __ bind(&stub_call); | 4981 __ bind(&stub_call); |
5001 __ mov(edx, eax); | 4982 __ mov(edx, eax); |
5002 __ mov(eax, Immediate(Smi::FromInt(1))); | 4983 __ mov(eax, Immediate(Smi::FromInt(1))); |
5003 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), | 4984 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), |
5004 strength(language_mode())).code(); | 4985 strength(language_mode())).code(); |
5005 CallIC(code, expr->CountBinOpFeedbackId()); | 4986 CallIC(code, expr->CountBinOpFeedbackId()); |
5006 patch_site.EmitPatchInfo(); | 4987 patch_site.EmitPatchInfo(); |
5007 __ bind(&done); | 4988 __ bind(&done); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5208 Split(zero, if_true, if_false, fall_through); | 5189 Split(zero, if_true, if_false, fall_through); |
5209 } else { | 5190 } else { |
5210 if (if_false != fall_through) __ jmp(if_false); | 5191 if (if_false != fall_through) __ jmp(if_false); |
5211 } | 5192 } |
5212 context()->Plug(if_true, if_false); | 5193 context()->Plug(if_true, if_false); |
5213 } | 5194 } |
5214 | 5195 |
5215 | 5196 |
5216 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 5197 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
5217 Comment cmnt(masm_, "[ CompareOperation"); | 5198 Comment cmnt(masm_, "[ CompareOperation"); |
5218 SetSourcePosition(expr->position()); | 5199 SetExpressionPosition(expr); |
5219 | 5200 |
5220 // First we try a fast inlined version of the compare when one of | 5201 // First we try a fast inlined version of the compare when one of |
5221 // the operands is a literal. | 5202 // the operands is a literal. |
5222 if (TryLiteralCompare(expr)) return; | 5203 if (TryLiteralCompare(expr)) return; |
5223 | 5204 |
5224 // Always perform the comparison for its control flow. Pack the result | 5205 // Always perform the comparison for its control flow. Pack the result |
5225 // into the expression's context after the comparison is performed. | 5206 // into the expression's context after the comparison is performed. |
5226 Label materialize_true, materialize_false; | 5207 Label materialize_true, materialize_false; |
5227 Label* if_true = NULL; | 5208 Label* if_true = NULL; |
5228 Label* if_false = NULL; | 5209 Label* if_false = NULL; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5262 if (inline_smi_code) { | 5243 if (inline_smi_code) { |
5263 Label slow_case; | 5244 Label slow_case; |
5264 __ mov(ecx, edx); | 5245 __ mov(ecx, edx); |
5265 __ or_(ecx, eax); | 5246 __ or_(ecx, eax); |
5266 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 5247 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
5267 __ cmp(edx, eax); | 5248 __ cmp(edx, eax); |
5268 Split(cc, if_true, if_false, NULL); | 5249 Split(cc, if_true, if_false, NULL); |
5269 __ bind(&slow_case); | 5250 __ bind(&slow_case); |
5270 } | 5251 } |
5271 | 5252 |
5272 // Record position and call the compare IC. | |
5273 SetSourcePosition(expr->position()); | |
5274 Handle<Code> ic = CodeFactory::CompareIC( | 5253 Handle<Code> ic = CodeFactory::CompareIC( |
5275 isolate(), op, strength(language_mode())).code(); | 5254 isolate(), op, strength(language_mode())).code(); |
5276 CallIC(ic, expr->CompareOperationFeedbackId()); | 5255 CallIC(ic, expr->CompareOperationFeedbackId()); |
5277 patch_site.EmitPatchInfo(); | 5256 patch_site.EmitPatchInfo(); |
5278 | 5257 |
5279 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 5258 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
5280 __ test(eax, eax); | 5259 __ test(eax, eax); |
5281 Split(cc, if_true, if_false, fall_through); | 5260 Split(cc, if_true, if_false, fall_through); |
5282 } | 5261 } |
5283 } | 5262 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5503 Assembler::target_address_at(call_target_address, | 5482 Assembler::target_address_at(call_target_address, |
5504 unoptimized_code)); | 5483 unoptimized_code)); |
5505 return OSR_AFTER_STACK_CHECK; | 5484 return OSR_AFTER_STACK_CHECK; |
5506 } | 5485 } |
5507 | 5486 |
5508 | 5487 |
5509 } // namespace internal | 5488 } // namespace internal |
5510 } // namespace v8 | 5489 } // namespace v8 |
5511 | 5490 |
5512 #endif // V8_TARGET_ARCH_X87 | 5491 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |