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

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

Issue 6793016: Record AST ids in relocation info at spots where we collect dynamic type feedback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: last change Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 26 matching lines...) Expand all
37 #include "parser.h" 37 #include "parser.h"
38 #include "scopes.h" 38 #include "scopes.h"
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 #define __ ACCESS_MASM(masm_) 45 #define __ ACCESS_MASM(masm_)
46 46
47 static unsigned GetPropertyId(Property* property) {
48 if (property->is_synthetic()) return AstNode::kNoNumber;
49 return property->id();
50 }
51
47 52
48 class JumpPatchSite BASE_EMBEDDED { 53 class JumpPatchSite BASE_EMBEDDED {
49 public: 54 public:
50 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 55 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
51 #ifdef DEBUG 56 #ifdef DEBUG
52 info_emitted_ = false; 57 info_emitted_ = false;
53 #endif 58 #endif
54 } 59 }
55 60
56 ~JumpPatchSite() { 61 ~JumpPatchSite() {
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 __ cmp(edx, Operand(eax)); 806 __ cmp(edx, Operand(eax));
802 __ j(not_equal, &next_test); 807 __ j(not_equal, &next_test);
803 __ Drop(1); // Switch value is no longer needed. 808 __ Drop(1); // Switch value is no longer needed.
804 __ jmp(clause->body_target()); 809 __ jmp(clause->body_target());
805 __ bind(&slow_case); 810 __ bind(&slow_case);
806 } 811 }
807 812
808 // Record position before stub call for type feedback. 813 // Record position before stub call for type feedback.
809 SetSourcePosition(clause->position()); 814 SetSourcePosition(clause->position());
810 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 815 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
811 EmitCallIC(ic, &patch_site); 816 EmitCallIC(ic, &patch_site, clause->label()->id());
812 __ test(eax, Operand(eax)); 817 __ test(eax, Operand(eax));
813 __ j(not_equal, &next_test); 818 __ j(not_equal, &next_test);
814 __ Drop(1); // Switch value is no longer needed. 819 __ Drop(1); // Switch value is no longer needed.
815 __ jmp(clause->body_target()); 820 __ jmp(clause->body_target());
816 } 821 }
817 822
818 // Discard the test value and jump to the default if present, otherwise to 823 // Discard the test value and jump to the default if present, otherwise to
819 // the end of the statement. 824 // the end of the statement.
820 __ bind(&next_test); 825 __ bind(&next_test);
821 __ Drop(1); // Switch value is no longer needed. 826 __ Drop(1); // Switch value is no longer needed.
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 key_literal->handle()->IsSmi()) { 1185 key_literal->handle()->IsSmi()) {
1181 // Load arguments object if there are no eval-introduced 1186 // Load arguments object if there are no eval-introduced
1182 // variables. Then load the argument from the arguments 1187 // variables. Then load the argument from the arguments
1183 // object using keyed load. 1188 // object using keyed load.
1184 __ mov(edx, 1189 __ mov(edx,
1185 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1190 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1186 slow)); 1191 slow));
1187 __ mov(eax, Immediate(key_literal->handle())); 1192 __ mov(eax, Immediate(key_literal->handle()));
1188 Handle<Code> ic = 1193 Handle<Code> ic =
1189 isolate()->builtins()->KeyedLoadIC_Initialize(); 1194 isolate()->builtins()->KeyedLoadIC_Initialize();
1190 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1195 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1191 __ jmp(done); 1196 __ jmp(done);
1192 } 1197 }
1193 } 1198 }
1194 } 1199 }
1195 } 1200 }
1196 } 1201 }
1197 1202
1198 1203
1199 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1204 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1200 // Four cases: non-this global variables, lookup slots, all other 1205 // Four cases: non-this global variables, lookup slots, all other
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 // Assert that the key is a smi. 1271 // Assert that the key is a smi.
1267 Literal* key_literal = property->key()->AsLiteral(); 1272 Literal* key_literal = property->key()->AsLiteral();
1268 ASSERT_NOT_NULL(key_literal); 1273 ASSERT_NOT_NULL(key_literal);
1269 ASSERT(key_literal->handle()->IsSmi()); 1274 ASSERT(key_literal->handle()->IsSmi());
1270 1275
1271 // Load the key. 1276 // Load the key.
1272 __ mov(eax, Immediate(key_literal->handle())); 1277 __ mov(eax, Immediate(key_literal->handle()));
1273 1278
1274 // Do a keyed property load. 1279 // Do a keyed property load.
1275 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1280 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1276 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1281 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1277 1282
1278 // Drop key and object left on the stack by IC. 1283 // Drop key and object left on the stack by IC.
1279 context()->Plug(eax); 1284 context()->Plug(eax);
1280 } 1285 }
1281 } 1286 }
1282 1287
1283 1288
1284 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1289 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1285 Comment cmnt(masm_, "[ RegExpLiteral"); 1290 Comment cmnt(masm_, "[ RegExpLiteral");
1286 NearLabel materialized; 1291 NearLabel materialized;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 // Fall through. 1384 // Fall through.
1380 case ObjectLiteral::Property::COMPUTED: 1385 case ObjectLiteral::Property::COMPUTED:
1381 if (key->handle()->IsSymbol()) { 1386 if (key->handle()->IsSymbol()) {
1382 if (property->emit_store()) { 1387 if (property->emit_store()) {
1383 VisitForAccumulatorValue(value); 1388 VisitForAccumulatorValue(value);
1384 __ mov(ecx, Immediate(key->handle())); 1389 __ mov(ecx, Immediate(key->handle()));
1385 __ mov(edx, Operand(esp, 0)); 1390 __ mov(edx, Operand(esp, 0));
1386 Handle<Code> ic = is_strict_mode() 1391 Handle<Code> ic = is_strict_mode()
1387 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1392 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1388 : isolate()->builtins()->StoreIC_Initialize(); 1393 : isolate()->builtins()->StoreIC_Initialize();
1389 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1394 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id());
1390 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1395 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1391 } else { 1396 } else {
1392 VisitForEffect(value); 1397 VisitForEffect(value);
1393 } 1398 }
1394 break; 1399 break;
1395 } 1400 }
1396 // Fall through. 1401 // Fall through.
1397 case ObjectLiteral::Property::PROTOTYPE: 1402 case ObjectLiteral::Property::PROTOTYPE:
1398 __ push(Operand(esp, 0)); // Duplicate receiver. 1403 __ push(Operand(esp, 0)); // Duplicate receiver.
1399 VisitForStackValue(key); 1404 VisitForStackValue(key);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 Token::Value op = expr->binary_op(); 1591 Token::Value op = expr->binary_op();
1587 __ push(eax); // Left operand goes on the stack. 1592 __ push(eax); // Left operand goes on the stack.
1588 VisitForAccumulatorValue(expr->value()); 1593 VisitForAccumulatorValue(expr->value());
1589 1594
1590 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1595 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1591 ? OVERWRITE_RIGHT 1596 ? OVERWRITE_RIGHT
1592 : NO_OVERWRITE; 1597 : NO_OVERWRITE;
1593 SetSourcePosition(expr->position() + 1); 1598 SetSourcePosition(expr->position() + 1);
1594 AccumulatorValueContext context(this); 1599 AccumulatorValueContext context(this);
1595 if (ShouldInlineSmiCase(op)) { 1600 if (ShouldInlineSmiCase(op)) {
1596 EmitInlineSmiBinaryOp(expr, 1601 EmitInlineSmiBinaryOp(expr->binary_operation(),
1597 op, 1602 op,
1598 mode, 1603 mode,
1599 expr->target(), 1604 expr->target(),
1600 expr->value()); 1605 expr->value());
1601 } else { 1606 } else {
1602 EmitBinaryOp(op, mode); 1607 EmitBinaryOp(expr->binary_operation(), op, mode);
1603 } 1608 }
1604 1609
1605 // Deoptimization point in case the binary operation may have side effects. 1610 // Deoptimization point in case the binary operation may have side effects.
1606 PrepareForBailout(expr->binary_operation(), TOS_REG); 1611 PrepareForBailout(expr->binary_operation(), TOS_REG);
1607 } else { 1612 } else {
1608 VisitForAccumulatorValue(expr->value()); 1613 VisitForAccumulatorValue(expr->value());
1609 } 1614 }
1610 1615
1611 // Record source position before possible IC call. 1616 // Record source position before possible IC call.
1612 SetSourcePosition(expr->position()); 1617 SetSourcePosition(expr->position());
(...skipping 14 matching lines...) Expand all
1627 break; 1632 break;
1628 } 1633 }
1629 } 1634 }
1630 1635
1631 1636
1632 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1637 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1633 SetSourcePosition(prop->position()); 1638 SetSourcePosition(prop->position());
1634 Literal* key = prop->key()->AsLiteral(); 1639 Literal* key = prop->key()->AsLiteral();
1635 __ mov(ecx, Immediate(key->handle())); 1640 __ mov(ecx, Immediate(key->handle()));
1636 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1641 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1637 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1642 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
1638 } 1643 }
1639 1644
1640 1645
1641 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1646 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1642 SetSourcePosition(prop->position()); 1647 SetSourcePosition(prop->position());
1643 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1648 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1644 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1649 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
1645 } 1650 }
1646 1651
1647 1652
1648 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1653 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1649 Token::Value op, 1654 Token::Value op,
1650 OverwriteMode mode, 1655 OverwriteMode mode,
1651 Expression* left, 1656 Expression* left,
1652 Expression* right) { 1657 Expression* right) {
1653 // Do combined smi check of the operands. Left operand is on the 1658 // Do combined smi check of the operands. Left operand is on the
1654 // stack. Right operand is in eax. 1659 // stack. Right operand is in eax.
1655 NearLabel done, smi_case, stub_call; 1660 NearLabel done, smi_case, stub_call;
1656 __ pop(edx); 1661 __ pop(edx);
1657 __ mov(ecx, eax); 1662 __ mov(ecx, eax);
1658 __ or_(eax, Operand(edx)); 1663 __ or_(eax, Operand(edx));
1659 JumpPatchSite patch_site(masm_); 1664 JumpPatchSite patch_site(masm_);
1660 patch_site.EmitJumpIfSmi(eax, &smi_case); 1665 patch_site.EmitJumpIfSmi(eax, &smi_case);
1661 1666
1662 __ bind(&stub_call); 1667 __ bind(&stub_call);
1663 __ mov(eax, ecx); 1668 __ mov(eax, ecx);
1664 TypeRecordingBinaryOpStub stub(op, mode); 1669 TypeRecordingBinaryOpStub stub(op, mode);
1665 EmitCallIC(stub.GetCode(), &patch_site); 1670 EmitCallIC(stub.GetCode(), &patch_site, expr->id());
1666 __ jmp(&done); 1671 __ jmp(&done);
1667 1672
1668 // Smi case. 1673 // Smi case.
1669 __ bind(&smi_case); 1674 __ bind(&smi_case);
1670 __ mov(eax, edx); // Copy left operand in case of a stub call. 1675 __ mov(eax, edx); // Copy left operand in case of a stub call.
1671 1676
1672 switch (op) { 1677 switch (op) {
1673 case Token::SAR: 1678 case Token::SAR:
1674 __ SmiUntag(eax); 1679 __ SmiUntag(eax);
1675 __ SmiUntag(ecx); 1680 __ SmiUntag(ecx);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 break; 1738 break;
1734 default: 1739 default:
1735 UNREACHABLE(); 1740 UNREACHABLE();
1736 } 1741 }
1737 1742
1738 __ bind(&done); 1743 __ bind(&done);
1739 context()->Plug(eax); 1744 context()->Plug(eax);
1740 } 1745 }
1741 1746
1742 1747
1743 void FullCodeGenerator::EmitBinaryOp(Token::Value op, 1748 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1749 Token::Value op,
1744 OverwriteMode mode) { 1750 OverwriteMode mode) {
1745 __ pop(edx); 1751 __ pop(edx);
1746 TypeRecordingBinaryOpStub stub(op, mode); 1752 TypeRecordingBinaryOpStub stub(op, mode);
1747 EmitCallIC(stub.GetCode(), NULL); // NULL signals no inlined smi code. 1753 // NULL signals no inlined smi code.
1754 EmitCallIC(stub.GetCode(), NULL, expr->id());
1748 context()->Plug(eax); 1755 context()->Plug(eax);
1749 } 1756 }
1750 1757
1751 1758
1752 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1759 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1753 // Invalid left-hand sides are rewritten to have a 'throw 1760 // Invalid left-hand sides are rewritten to have a 'throw
1754 // ReferenceError' on the left-hand side. 1761 // ReferenceError' on the left-hand side.
1755 if (!expr->IsValidLeftHandSide()) { 1762 if (!expr->IsValidLeftHandSide()) {
1756 VisitForEffect(expr); 1763 VisitForEffect(expr);
1757 return; 1764 return;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 SetSourcePosition(expr->position()); 1936 SetSourcePosition(expr->position());
1930 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1937 __ mov(ecx, prop->key()->AsLiteral()->handle());
1931 if (expr->ends_initialization_block()) { 1938 if (expr->ends_initialization_block()) {
1932 __ mov(edx, Operand(esp, 0)); 1939 __ mov(edx, Operand(esp, 0));
1933 } else { 1940 } else {
1934 __ pop(edx); 1941 __ pop(edx);
1935 } 1942 }
1936 Handle<Code> ic = is_strict_mode() 1943 Handle<Code> ic = is_strict_mode()
1937 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1944 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1938 : isolate()->builtins()->StoreIC_Initialize(); 1945 : isolate()->builtins()->StoreIC_Initialize();
1939 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1946 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
1940 1947
1941 // If the assignment ends an initialization block, revert to fast case. 1948 // If the assignment ends an initialization block, revert to fast case.
1942 if (expr->ends_initialization_block()) { 1949 if (expr->ends_initialization_block()) {
1943 __ push(eax); // Result of assignment, saved even if not needed. 1950 __ push(eax); // Result of assignment, saved even if not needed.
1944 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1951 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1945 __ CallRuntime(Runtime::kToFastProperties, 1); 1952 __ CallRuntime(Runtime::kToFastProperties, 1);
1946 __ pop(eax); 1953 __ pop(eax);
1947 __ Drop(1); 1954 __ Drop(1);
1948 } 1955 }
1949 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1956 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 19 matching lines...) Expand all
1969 if (expr->ends_initialization_block()) { 1976 if (expr->ends_initialization_block()) {
1970 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1977 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1971 } else { 1978 } else {
1972 __ pop(edx); 1979 __ pop(edx);
1973 } 1980 }
1974 // Record source code position before IC call. 1981 // Record source code position before IC call.
1975 SetSourcePosition(expr->position()); 1982 SetSourcePosition(expr->position());
1976 Handle<Code> ic = is_strict_mode() 1983 Handle<Code> ic = is_strict_mode()
1977 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1984 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1978 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1985 : isolate()->builtins()->KeyedStoreIC_Initialize();
1979 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1986 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
1980 1987
1981 // If the assignment ends an initialization block, revert to fast case. 1988 // If the assignment ends an initialization block, revert to fast case.
1982 if (expr->ends_initialization_block()) { 1989 if (expr->ends_initialization_block()) {
1983 __ pop(edx); 1990 __ pop(edx);
1984 __ push(eax); // Result of assignment, saved even if not needed. 1991 __ push(eax); // Result of assignment, saved even if not needed.
1985 __ push(edx); 1992 __ push(edx);
1986 __ CallRuntime(Runtime::kToFastProperties, 1); 1993 __ CallRuntime(Runtime::kToFastProperties, 1);
1987 __ pop(eax); 1994 __ pop(eax);
1988 } 1995 }
1989 1996
(...skipping 30 matching lines...) Expand all
2020 for (int i = 0; i < arg_count; i++) { 2027 for (int i = 0; i < arg_count; i++) {
2021 VisitForStackValue(args->at(i)); 2028 VisitForStackValue(args->at(i));
2022 } 2029 }
2023 __ Set(ecx, Immediate(name)); 2030 __ Set(ecx, Immediate(name));
2024 } 2031 }
2025 // Record source position of the IC call. 2032 // Record source position of the IC call.
2026 SetSourcePosition(expr->position()); 2033 SetSourcePosition(expr->position());
2027 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2034 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2028 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 2035 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
2029 arg_count, in_loop); 2036 arg_count, in_loop);
2030 EmitCallIC(ic, mode); 2037 EmitCallIC(ic, mode, expr->id());
2031 RecordJSReturnSite(expr); 2038 RecordJSReturnSite(expr);
2032 // Restore context register. 2039 // Restore context register.
2033 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2040 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2034 context()->Plug(eax); 2041 context()->Plug(eax);
2035 } 2042 }
2036 2043
2037 2044
2038 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2045 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2039 Expression* key, 2046 Expression* key,
2040 RelocInfo::Mode mode) { 2047 RelocInfo::Mode mode) {
(...skipping 13 matching lines...) Expand all
2054 for (int i = 0; i < arg_count; i++) { 2061 for (int i = 0; i < arg_count; i++) {
2055 VisitForStackValue(args->at(i)); 2062 VisitForStackValue(args->at(i));
2056 } 2063 }
2057 } 2064 }
2058 // Record source position of the IC call. 2065 // Record source position of the IC call.
2059 SetSourcePosition(expr->position()); 2066 SetSourcePosition(expr->position());
2060 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2067 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2061 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( 2068 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2062 arg_count, in_loop); 2069 arg_count, in_loop);
2063 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2070 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2064 EmitCallIC(ic, mode); 2071 EmitCallIC(ic, mode, expr->id());
2065 RecordJSReturnSite(expr); 2072 RecordJSReturnSite(expr);
2066 // Restore context register. 2073 // Restore context register.
2067 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2074 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2068 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2075 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2069 } 2076 }
2070 2077
2071 2078
2072 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2079 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2073 // Code common for calls using the call stub. 2080 // Code common for calls using the call stub.
2074 ZoneList<Expression*>* args = expr->arguments(); 2081 ZoneList<Expression*>* args = expr->arguments();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 __ mov(edx, operand); 2252 __ mov(edx, operand);
2246 2253
2247 ASSERT(prop->key()->AsLiteral() != NULL); 2254 ASSERT(prop->key()->AsLiteral() != NULL);
2248 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2255 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2249 __ mov(eax, prop->key()->AsLiteral()->handle()); 2256 __ mov(eax, prop->key()->AsLiteral()->handle());
2250 2257
2251 // Record source code position for IC call. 2258 // Record source code position for IC call.
2252 SetSourcePosition(prop->position()); 2259 SetSourcePosition(prop->position());
2253 2260
2254 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2261 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2255 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2262 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
2256 // Push result (function). 2263 // Push result (function).
2257 __ push(eax); 2264 __ push(eax);
2258 // Push Global receiver. 2265 // Push Global receiver.
2259 __ mov(ecx, GlobalObjectOperand()); 2266 __ mov(ecx, GlobalObjectOperand());
2260 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2267 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2261 EmitCallWithStub(expr); 2268 EmitCallWithStub(expr);
2262 } else { 2269 } else {
2263 { PreservePositionScope scope(masm()->positions_recorder()); 2270 { PreservePositionScope scope(masm()->positions_recorder());
2264 VisitForStackValue(prop->obj()); 2271 VisitForStackValue(prop->obj());
2265 } 2272 }
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after
3604 for (int i = 0; i < arg_count; i++) { 3611 for (int i = 0; i < arg_count; i++) {
3605 VisitForStackValue(args->at(i)); 3612 VisitForStackValue(args->at(i));
3606 } 3613 }
3607 3614
3608 if (expr->is_jsruntime()) { 3615 if (expr->is_jsruntime()) {
3609 // Call the JS runtime function via a call IC. 3616 // Call the JS runtime function via a call IC.
3610 __ Set(ecx, Immediate(expr->name())); 3617 __ Set(ecx, Immediate(expr->name()));
3611 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3618 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3612 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 3619 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3613 arg_count, in_loop); 3620 arg_count, in_loop);
3614 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3621 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3615 // Restore context register. 3622 // Restore context register.
3616 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3623 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3617 } else { 3624 } else {
3618 // Call the C runtime function. 3625 // Call the C runtime function.
3619 __ CallRuntime(expr->function(), arg_count); 3626 __ CallRuntime(expr->function(), arg_count);
3620 } 3627 }
3621 context()->Plug(eax); 3628 context()->Plug(eax);
3622 } 3629 }
3623 3630
3624 3631
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
3891 } 3898 }
3892 } 3899 }
3893 3900
3894 // Record position before stub call. 3901 // Record position before stub call.
3895 SetSourcePosition(expr->position()); 3902 SetSourcePosition(expr->position());
3896 3903
3897 // Call stub for +1/-1. 3904 // Call stub for +1/-1.
3898 __ mov(edx, eax); 3905 __ mov(edx, eax);
3899 __ mov(eax, Immediate(Smi::FromInt(1))); 3906 __ mov(eax, Immediate(Smi::FromInt(1)));
3900 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 3907 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
3901 EmitCallIC(stub.GetCode(), &patch_site); 3908 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
3902 __ bind(&done); 3909 __ bind(&done);
3903 3910
3904 // Store the value returned in eax. 3911 // Store the value returned in eax.
3905 switch (assign_type) { 3912 switch (assign_type) {
3906 case VARIABLE: 3913 case VARIABLE:
3907 if (expr->is_postfix()) { 3914 if (expr->is_postfix()) {
3908 // Perform the assignment as if via '='. 3915 // Perform the assignment as if via '='.
3909 { EffectContext context(this); 3916 { EffectContext context(this);
3910 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3917 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3911 Token::ASSIGN); 3918 Token::ASSIGN);
(...skipping 12 matching lines...) Expand all
3924 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3931 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3925 context()->Plug(eax); 3932 context()->Plug(eax);
3926 } 3933 }
3927 break; 3934 break;
3928 case NAMED_PROPERTY: { 3935 case NAMED_PROPERTY: {
3929 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3936 __ mov(ecx, prop->key()->AsLiteral()->handle());
3930 __ pop(edx); 3937 __ pop(edx);
3931 Handle<Code> ic = is_strict_mode() 3938 Handle<Code> ic = is_strict_mode()
3932 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3939 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3933 : isolate()->builtins()->StoreIC_Initialize(); 3940 : isolate()->builtins()->StoreIC_Initialize();
3934 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3941 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3935 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3942 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3936 if (expr->is_postfix()) { 3943 if (expr->is_postfix()) {
3937 if (!context()->IsEffect()) { 3944 if (!context()->IsEffect()) {
3938 context()->PlugTOS(); 3945 context()->PlugTOS();
3939 } 3946 }
3940 } else { 3947 } else {
3941 context()->Plug(eax); 3948 context()->Plug(eax);
3942 } 3949 }
3943 break; 3950 break;
3944 } 3951 }
3945 case KEYED_PROPERTY: { 3952 case KEYED_PROPERTY: {
3946 __ pop(ecx); 3953 __ pop(ecx);
3947 __ pop(edx); 3954 __ pop(edx);
3948 Handle<Code> ic = is_strict_mode() 3955 Handle<Code> ic = is_strict_mode()
3949 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3956 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3950 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3957 : isolate()->builtins()->KeyedStoreIC_Initialize();
3951 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3958 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3952 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3959 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3953 if (expr->is_postfix()) { 3960 if (expr->is_postfix()) {
3954 // Result is on the stack 3961 // Result is on the stack
3955 if (!context()->IsEffect()) { 3962 if (!context()->IsEffect()) {
3956 context()->PlugTOS(); 3963 context()->PlugTOS();
3957 } 3964 }
3958 } else { 3965 } else {
3959 context()->Plug(eax); 3966 context()->Plug(eax);
3960 } 3967 }
3961 break; 3968 break;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
4168 __ or_(ecx, Operand(eax)); 4175 __ or_(ecx, Operand(eax));
4169 patch_site.EmitJumpIfNotSmi(ecx, &slow_case); 4176 patch_site.EmitJumpIfNotSmi(ecx, &slow_case);
4170 __ cmp(edx, Operand(eax)); 4177 __ cmp(edx, Operand(eax));
4171 Split(cc, if_true, if_false, NULL); 4178 Split(cc, if_true, if_false, NULL);
4172 __ bind(&slow_case); 4179 __ bind(&slow_case);
4173 } 4180 }
4174 4181
4175 // Record position and call the compare IC. 4182 // Record position and call the compare IC.
4176 SetSourcePosition(expr->position()); 4183 SetSourcePosition(expr->position());
4177 Handle<Code> ic = CompareIC::GetUninitialized(op); 4184 Handle<Code> ic = CompareIC::GetUninitialized(op);
4178 EmitCallIC(ic, &patch_site); 4185 EmitCallIC(ic, &patch_site, expr->id());
4179 4186
4180 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4187 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4181 __ test(eax, Operand(eax)); 4188 __ test(eax, Operand(eax));
4182 Split(cc, if_true, if_false, fall_through); 4189 Split(cc, if_true, if_false, fall_through);
4183 } 4190 }
4184 } 4191 }
4185 4192
4186 // Convert the result of the comparison into one expected for this 4193 // Convert the result of the comparison into one expected for this
4187 // expression's context. 4194 // expression's context.
4188 context()->Plug(if_true, if_false); 4195 context()->Plug(if_true, if_false);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 Register FullCodeGenerator::result_register() { 4235 Register FullCodeGenerator::result_register() {
4229 return eax; 4236 return eax;
4230 } 4237 }
4231 4238
4232 4239
4233 Register FullCodeGenerator::context_register() { 4240 Register FullCodeGenerator::context_register() {
4234 return esi; 4241 return esi;
4235 } 4242 }
4236 4243
4237 4244
4238 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4245 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4246 RelocInfo::Mode mode,
4247 unsigned ast_id) {
4239 ASSERT(mode == RelocInfo::CODE_TARGET || 4248 ASSERT(mode == RelocInfo::CODE_TARGET ||
4240 mode == RelocInfo::CODE_TARGET_CONTEXT); 4249 mode == RelocInfo::CODE_TARGET_CONTEXT);
4241 switch (ic->kind()) { 4250 switch (ic->kind()) {
4242 case Code::LOAD_IC: 4251 case Code::LOAD_IC:
4243 __ IncrementCounter(isolate()->counters()->named_load_full(), 1); 4252 __ IncrementCounter(isolate()->counters()->named_load_full(), 1);
4244 break; 4253 break;
4245 case Code::KEYED_LOAD_IC: 4254 case Code::KEYED_LOAD_IC:
4246 __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1); 4255 __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
4247 break; 4256 break;
4248 case Code::STORE_IC: 4257 case Code::STORE_IC:
4249 __ IncrementCounter(isolate()->counters()->named_store_full(), 1); 4258 __ IncrementCounter(isolate()->counters()->named_store_full(), 1);
4250 break; 4259 break;
4251 case Code::KEYED_STORE_IC: 4260 case Code::KEYED_STORE_IC:
4252 __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1); 4261 __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
4253 default: 4262 default:
4254 break; 4263 break;
4255 } 4264 }
4256 __ call(ic, mode); 4265 __ call(ic, mode, ast_id);
4257 } 4266 }
4258 4267
4259 4268
4260 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 4269 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4270 JumpPatchSite* patch_site,
4271 unsigned ast_id) {
4261 Counters* counters = isolate()->counters(); 4272 Counters* counters = isolate()->counters();
4262 switch (ic->kind()) { 4273 switch (ic->kind()) {
4263 case Code::LOAD_IC: 4274 case Code::LOAD_IC:
4264 __ IncrementCounter(counters->named_load_full(), 1); 4275 __ IncrementCounter(counters->named_load_full(), 1);
4265 break; 4276 break;
4266 case Code::KEYED_LOAD_IC: 4277 case Code::KEYED_LOAD_IC:
4267 __ IncrementCounter(counters->keyed_load_full(), 1); 4278 __ IncrementCounter(counters->keyed_load_full(), 1);
4268 break; 4279 break;
4269 case Code::STORE_IC: 4280 case Code::STORE_IC:
4270 __ IncrementCounter(counters->named_store_full(), 1); 4281 __ IncrementCounter(counters->named_store_full(), 1);
4271 break; 4282 break;
4272 case Code::KEYED_STORE_IC: 4283 case Code::KEYED_STORE_IC:
4273 __ IncrementCounter(counters->keyed_store_full(), 1); 4284 __ IncrementCounter(counters->keyed_store_full(), 1);
4274 default: 4285 default:
4275 break; 4286 break;
4276 } 4287 }
4277 __ call(ic, RelocInfo::CODE_TARGET); 4288 __ call(ic, RelocInfo::CODE_TARGET, ast_id);
4278 if (patch_site != NULL && patch_site->is_bound()) { 4289 if (patch_site != NULL && patch_site->is_bound()) {
4279 patch_site->EmitPatchInfo(); 4290 patch_site->EmitPatchInfo();
4280 } else { 4291 } else {
4281 __ nop(); // Signals no inlined code. 4292 __ nop(); // Signals no inlined code.
4282 } 4293 }
4283 } 4294 }
4284 4295
4285 4296
4286 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4297 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4287 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4298 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4323 // And return. 4334 // And return.
4324 __ ret(0); 4335 __ ret(0);
4325 } 4336 }
4326 4337
4327 4338
4328 #undef __ 4339 #undef __
4329 4340
4330 } } // namespace v8::internal 4341 } } // namespace v8::internal
4331 4342
4332 #endif // V8_TARGET_ARCH_IA32 4343 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698