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