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

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

Issue 3431010: Clean up the insertion of nops (signalling non-inlined loads and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 3 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 | « no previous file | src/full-codegen.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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 VisitForValue(function, kAccumulator); 613 VisitForValue(function, kAccumulator);
614 __ pop(r1); // Key. 614 __ pop(r1); // Key.
615 } else { 615 } else {
616 VisitForValue(prop->key(), kAccumulator); 616 VisitForValue(prop->key(), kAccumulator);
617 __ mov(r1, result_register()); // Key. 617 __ mov(r1, result_register()); // Key.
618 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); 618 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex);
619 } 619 }
620 __ pop(r2); // Receiver. 620 __ pop(r2); // Receiver.
621 621
622 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 622 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
623 __ Call(ic, RelocInfo::CODE_TARGET); 623 EmitCallIC(ic, RelocInfo::CODE_TARGET);
624 // Value in r0 is ignored (declarations are statements). 624 // Value in r0 is ignored (declarations are statements).
625 } 625 }
626 } 626 }
627 } 627 }
628 628
629 629
630 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 630 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
631 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 631 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
632 } 632 }
633 633
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 obj_proxy->IsArguments() && 949 obj_proxy->IsArguments() &&
950 key_literal->handle()->IsSmi()) { 950 key_literal->handle()->IsSmi()) {
951 // Load arguments object if there are no eval-introduced 951 // Load arguments object if there are no eval-introduced
952 // variables. Then load the argument from the arguments 952 // variables. Then load the argument from the arguments
953 // object using keyed load. 953 // object using keyed load.
954 __ ldr(r1, 954 __ ldr(r1,
955 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), 955 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
956 slow)); 956 slow));
957 __ mov(r0, Operand(key_literal->handle())); 957 __ mov(r0, Operand(key_literal->handle()));
958 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 958 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
959 __ Call(ic, RelocInfo::CODE_TARGET); 959 EmitCallIC(ic, RelocInfo::CODE_TARGET);
960 __ jmp(done); 960 __ jmp(done);
961 } 961 }
962 } 962 }
963 } 963 }
964 } 964 }
965 } 965 }
966 966
967 967
968 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( 968 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
969 Slot* slot, 969 Slot* slot,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 __ b(&loop); 1015 __ b(&loop);
1016 __ bind(&fast); 1016 __ bind(&fast);
1017 } 1017 }
1018 1018
1019 __ ldr(r0, CodeGenerator::GlobalObject()); 1019 __ ldr(r0, CodeGenerator::GlobalObject());
1020 __ mov(r2, Operand(slot->var()->name())); 1020 __ mov(r2, Operand(slot->var()->name()));
1021 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1021 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1022 ? RelocInfo::CODE_TARGET 1022 ? RelocInfo::CODE_TARGET
1023 : RelocInfo::CODE_TARGET_CONTEXT; 1023 : RelocInfo::CODE_TARGET_CONTEXT;
1024 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1024 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1025 __ Call(ic, mode); 1025 EmitCallIC(ic, mode);
1026 } 1026 }
1027 1027
1028 1028
1029 void FullCodeGenerator::EmitVariableLoad(Variable* var, 1029 void FullCodeGenerator::EmitVariableLoad(Variable* var,
1030 Expression::Context context) { 1030 Expression::Context context) {
1031 // Four cases: non-this global variables, lookup slots, all other 1031 // Four cases: non-this global variables, lookup slots, all other
1032 // types of slots, and parameters that rewrite to explicit property 1032 // types of slots, and parameters that rewrite to explicit property
1033 // accesses on the arguments object. 1033 // accesses on the arguments object.
1034 Slot* slot = var->slot(); 1034 Slot* slot = var->slot();
1035 Property* property = var->AsProperty(); 1035 Property* property = var->AsProperty();
1036 1036
1037 if (var->is_global() && !var->is_this()) { 1037 if (var->is_global() && !var->is_this()) {
1038 Comment cmnt(masm_, "Global variable"); 1038 Comment cmnt(masm_, "Global variable");
1039 // Use inline caching. Variable name is passed in r2 and the global 1039 // Use inline caching. Variable name is passed in r2 and the global
1040 // object (receiver) in r0. 1040 // object (receiver) in r0.
1041 __ ldr(r0, CodeGenerator::GlobalObject()); 1041 __ ldr(r0, CodeGenerator::GlobalObject());
1042 __ mov(r2, Operand(var->name())); 1042 __ mov(r2, Operand(var->name()));
1043 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1043 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1044 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1044 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1045 Apply(context, r0); 1045 Apply(context, r0);
1046 1046
1047 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1047 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1048 Label done, slow; 1048 Label done, slow;
1049 1049
1050 // Generate code for loading from variables potentially shadowed 1050 // Generate code for loading from variables potentially shadowed
1051 // by eval-introduced variables. 1051 // by eval-introduced variables.
1052 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1052 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1053 1053
1054 __ bind(&slow); 1054 __ bind(&slow);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 // Assert that the key is a smi. 1093 // Assert that the key is a smi.
1094 Literal* key_literal = property->key()->AsLiteral(); 1094 Literal* key_literal = property->key()->AsLiteral();
1095 ASSERT_NOT_NULL(key_literal); 1095 ASSERT_NOT_NULL(key_literal);
1096 ASSERT(key_literal->handle()->IsSmi()); 1096 ASSERT(key_literal->handle()->IsSmi());
1097 1097
1098 // Load the key. 1098 // Load the key.
1099 __ mov(r0, Operand(key_literal->handle())); 1099 __ mov(r0, Operand(key_literal->handle()));
1100 1100
1101 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1101 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1102 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1102 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1103 __ Call(ic, RelocInfo::CODE_TARGET); 1103 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1104 Apply(context, r0); 1104 Apply(context, r0);
1105 } 1105 }
1106 } 1106 }
1107 1107
1108 1108
1109 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1109 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1110 Comment cmnt(masm_, "[ RegExpLiteral"); 1110 Comment cmnt(masm_, "[ RegExpLiteral");
1111 Label materialized; 1111 Label materialized;
1112 // Registers will be used as follows: 1112 // Registers will be used as follows:
1113 // r4 = JS function, literals array 1113 // r4 = JS function, literals array
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 UNREACHABLE(); 1182 UNREACHABLE();
1183 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1183 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1184 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1184 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1185 // Fall through. 1185 // Fall through.
1186 case ObjectLiteral::Property::COMPUTED: 1186 case ObjectLiteral::Property::COMPUTED:
1187 if (key->handle()->IsSymbol()) { 1187 if (key->handle()->IsSymbol()) {
1188 VisitForValue(value, kAccumulator); 1188 VisitForValue(value, kAccumulator);
1189 __ mov(r2, Operand(key->handle())); 1189 __ mov(r2, Operand(key->handle()));
1190 __ ldr(r1, MemOperand(sp)); 1190 __ ldr(r1, MemOperand(sp));
1191 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1191 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1192 __ Call(ic, RelocInfo::CODE_TARGET); 1192 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1193 break; 1193 break;
1194 } 1194 }
1195 // Fall through. 1195 // Fall through.
1196 case ObjectLiteral::Property::PROTOTYPE: 1196 case ObjectLiteral::Property::PROTOTYPE:
1197 // Duplicate receiver on stack. 1197 // Duplicate receiver on stack.
1198 __ ldr(r0, MemOperand(sp)); 1198 __ ldr(r0, MemOperand(sp));
1199 __ push(r0); 1199 __ push(r0);
1200 VisitForValue(key, kStack); 1200 VisitForValue(key, kStack);
1201 VisitForValue(value, kStack); 1201 VisitForValue(value, kStack);
1202 __ CallRuntime(Runtime::kSetProperty, 3); 1202 __ CallRuntime(Runtime::kSetProperty, 3);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 } 1402 }
1403 } 1403 }
1404 1404
1405 1405
1406 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1406 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1407 SetSourcePosition(prop->position()); 1407 SetSourcePosition(prop->position());
1408 Literal* key = prop->key()->AsLiteral(); 1408 Literal* key = prop->key()->AsLiteral();
1409 __ mov(r2, Operand(key->handle())); 1409 __ mov(r2, Operand(key->handle()));
1410 // Call load IC. It has arguments receiver and property name r0 and r2. 1410 // Call load IC. It has arguments receiver and property name r0 and r2.
1411 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1411 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1412 __ Call(ic, RelocInfo::CODE_TARGET); 1412 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1413 } 1413 }
1414 1414
1415 1415
1416 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1416 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1417 SetSourcePosition(prop->position()); 1417 SetSourcePosition(prop->position());
1418 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1418 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1419 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1419 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1420 __ Call(ic, RelocInfo::CODE_TARGET); 1420 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1421 } 1421 }
1422 1422
1423 1423
1424 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1424 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1425 Token::Value op, 1425 Token::Value op,
1426 Expression::Context context, 1426 Expression::Context context,
1427 OverwriteMode mode, 1427 OverwriteMode mode,
1428 Expression* left, 1428 Expression* left,
1429 Expression* right, 1429 Expression* right,
1430 ConstantOperand constant) { 1430 ConstantOperand constant) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect); 1468 EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect);
1469 break; 1469 break;
1470 } 1470 }
1471 case NAMED_PROPERTY: { 1471 case NAMED_PROPERTY: {
1472 __ push(r0); // Preserve value. 1472 __ push(r0); // Preserve value.
1473 VisitForValue(prop->obj(), kAccumulator); 1473 VisitForValue(prop->obj(), kAccumulator);
1474 __ mov(r1, r0); 1474 __ mov(r1, r0);
1475 __ pop(r0); // Restore value. 1475 __ pop(r0); // Restore value.
1476 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 1476 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1477 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1477 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1478 __ Call(ic, RelocInfo::CODE_TARGET); 1478 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1479 break; 1479 break;
1480 } 1480 }
1481 case KEYED_PROPERTY: { 1481 case KEYED_PROPERTY: {
1482 __ push(r0); // Preserve value. 1482 __ push(r0); // Preserve value.
1483 VisitForValue(prop->obj(), kStack); 1483 VisitForValue(prop->obj(), kStack);
1484 VisitForValue(prop->key(), kAccumulator); 1484 VisitForValue(prop->key(), kAccumulator);
1485 __ mov(r1, r0); 1485 __ mov(r1, r0);
1486 __ pop(r2); 1486 __ pop(r2);
1487 __ pop(r0); // Restore value. 1487 __ pop(r0); // Restore value.
1488 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1488 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1489 __ Call(ic, RelocInfo::CODE_TARGET); 1489 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1490 break; 1490 break;
1491 } 1491 }
1492 } 1492 }
1493 } 1493 }
1494 1494
1495 1495
1496 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1496 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1497 Token::Value op, 1497 Token::Value op,
1498 Expression::Context context) { 1498 Expression::Context context) {
1499 // Left-hand sides that rewrite to explicit property accesses do not reach 1499 // Left-hand sides that rewrite to explicit property accesses do not reach
1500 // here. 1500 // here.
1501 ASSERT(var != NULL); 1501 ASSERT(var != NULL);
1502 ASSERT(var->is_global() || var->slot() != NULL); 1502 ASSERT(var->is_global() || var->slot() != NULL);
1503 1503
1504 if (var->is_global()) { 1504 if (var->is_global()) {
1505 ASSERT(!var->is_this()); 1505 ASSERT(!var->is_this());
1506 // Assignment to a global variable. Use inline caching for the 1506 // Assignment to a global variable. Use inline caching for the
1507 // assignment. Right-hand-side value is passed in r0, variable name in 1507 // assignment. Right-hand-side value is passed in r0, variable name in
1508 // r2, and the global object in r1. 1508 // r2, and the global object in r1.
1509 __ mov(r2, Operand(var->name())); 1509 __ mov(r2, Operand(var->name()));
1510 __ ldr(r1, CodeGenerator::GlobalObject()); 1510 __ ldr(r1, CodeGenerator::GlobalObject());
1511 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1511 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1512 __ Call(ic, RelocInfo::CODE_TARGET); 1512 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1513 1513
1514 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1514 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1515 // Perform the assignment for non-const variables and for initialization 1515 // Perform the assignment for non-const variables and for initialization
1516 // of const variables. Const assignments are simply skipped. 1516 // of const variables. Const assignments are simply skipped.
1517 Label done; 1517 Label done;
1518 Slot* slot = var->slot(); 1518 Slot* slot = var->slot();
1519 switch (slot->type()) { 1519 switch (slot->type()) {
1520 case Slot::PARAMETER: 1520 case Slot::PARAMETER:
1521 case Slot::LOCAL: 1521 case Slot::LOCAL:
1522 if (op == Token::INIT_CONST) { 1522 if (op == Token::INIT_CONST) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 1591 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1592 // Load receiver to r1. Leave a copy in the stack if needed for turning the 1592 // Load receiver to r1. Leave a copy in the stack if needed for turning the
1593 // receiver into fast case. 1593 // receiver into fast case.
1594 if (expr->ends_initialization_block()) { 1594 if (expr->ends_initialization_block()) {
1595 __ ldr(r1, MemOperand(sp)); 1595 __ ldr(r1, MemOperand(sp));
1596 } else { 1596 } else {
1597 __ pop(r1); 1597 __ pop(r1);
1598 } 1598 }
1599 1599
1600 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1600 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1601 __ Call(ic, RelocInfo::CODE_TARGET); 1601 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1602 1602
1603 // If the assignment ends an initialization block, revert to fast case. 1603 // If the assignment ends an initialization block, revert to fast case.
1604 if (expr->ends_initialization_block()) { 1604 if (expr->ends_initialization_block()) {
1605 __ push(r0); // Result of assignment, saved even if not needed. 1605 __ push(r0); // Result of assignment, saved even if not needed.
1606 // Receiver is under the result value. 1606 // Receiver is under the result value.
1607 __ ldr(ip, MemOperand(sp, kPointerSize)); 1607 __ ldr(ip, MemOperand(sp, kPointerSize));
1608 __ push(ip); 1608 __ push(ip);
1609 __ CallRuntime(Runtime::kToFastProperties, 1); 1609 __ CallRuntime(Runtime::kToFastProperties, 1);
1610 __ pop(r0); 1610 __ pop(r0);
1611 DropAndApply(1, context_, r0); 1611 DropAndApply(1, context_, r0);
(...skipping 23 matching lines...) Expand all
1635 __ pop(r1); // Key. 1635 __ pop(r1); // Key.
1636 // Load receiver to r2. Leave a copy in the stack if needed for turning the 1636 // Load receiver to r2. Leave a copy in the stack if needed for turning the
1637 // receiver into fast case. 1637 // receiver into fast case.
1638 if (expr->ends_initialization_block()) { 1638 if (expr->ends_initialization_block()) {
1639 __ ldr(r2, MemOperand(sp)); 1639 __ ldr(r2, MemOperand(sp));
1640 } else { 1640 } else {
1641 __ pop(r2); 1641 __ pop(r2);
1642 } 1642 }
1643 1643
1644 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1644 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1645 __ Call(ic, RelocInfo::CODE_TARGET); 1645 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1646 1646
1647 // If the assignment ends an initialization block, revert to fast case. 1647 // If the assignment ends an initialization block, revert to fast case.
1648 if (expr->ends_initialization_block()) { 1648 if (expr->ends_initialization_block()) {
1649 __ push(r0); // Result of assignment, saved even if not needed. 1649 __ push(r0); // Result of assignment, saved even if not needed.
1650 // Receiver is under the result value. 1650 // Receiver is under the result value.
1651 __ ldr(ip, MemOperand(sp, kPointerSize)); 1651 __ ldr(ip, MemOperand(sp, kPointerSize));
1652 __ push(ip); 1652 __ push(ip);
1653 __ CallRuntime(Runtime::kToFastProperties, 1); 1653 __ CallRuntime(Runtime::kToFastProperties, 1);
1654 __ pop(r0); 1654 __ pop(r0);
1655 DropAndApply(1, context_, r0); 1655 DropAndApply(1, context_, r0);
(...skipping 28 matching lines...) Expand all
1684 int arg_count = args->length(); 1684 int arg_count = args->length();
1685 for (int i = 0; i < arg_count; i++) { 1685 for (int i = 0; i < arg_count; i++) {
1686 VisitForValue(args->at(i), kStack); 1686 VisitForValue(args->at(i), kStack);
1687 } 1687 }
1688 __ mov(r2, Operand(name)); 1688 __ mov(r2, Operand(name));
1689 // Record source position for debugger. 1689 // Record source position for debugger.
1690 SetSourcePosition(expr->position()); 1690 SetSourcePosition(expr->position());
1691 // Call the IC initialization code. 1691 // Call the IC initialization code.
1692 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1692 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1693 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 1693 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1694 __ Call(ic, mode); 1694 EmitCallIC(ic, mode);
1695 // Restore context register. 1695 // Restore context register.
1696 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1696 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1697 Apply(context_, r0); 1697 Apply(context_, r0);
1698 } 1698 }
1699 1699
1700 1700
1701 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 1701 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
1702 Expression* key, 1702 Expression* key,
1703 RelocInfo::Mode mode) { 1703 RelocInfo::Mode mode) {
1704 // Code common for calls using the IC. 1704 // Code common for calls using the IC.
1705 ZoneList<Expression*>* args = expr->arguments(); 1705 ZoneList<Expression*>* args = expr->arguments();
1706 int arg_count = args->length(); 1706 int arg_count = args->length();
1707 for (int i = 0; i < arg_count; i++) { 1707 for (int i = 0; i < arg_count; i++) {
1708 VisitForValue(args->at(i), kStack); 1708 VisitForValue(args->at(i), kStack);
1709 } 1709 }
1710 VisitForValue(key, kAccumulator); 1710 VisitForValue(key, kAccumulator);
1711 __ mov(r2, r0); 1711 __ mov(r2, r0);
1712 // Record source position for debugger. 1712 // Record source position for debugger.
1713 SetSourcePosition(expr->position()); 1713 SetSourcePosition(expr->position());
1714 // Call the IC initialization code. 1714 // Call the IC initialization code.
1715 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1715 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1716 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, 1716 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
1717 in_loop); 1717 in_loop);
1718 __ Call(ic, mode); 1718 EmitCallIC(ic, mode);
1719 // Restore context register. 1719 // Restore context register.
1720 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1720 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1721 Apply(context_, r0); 1721 Apply(context_, r0);
1722 } 1722 }
1723 1723
1724 1724
1725 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 1725 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1726 // Code common for calls using the call stub. 1726 // Code common for calls using the call stub.
1727 ZoneList<Expression*>* args = expr->arguments(); 1727 ZoneList<Expression*>* args = expr->arguments();
1728 int arg_count = args->length(); 1728 int arg_count = args->length();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 // For a synthetic property use keyed load IC followed by function call, 1847 // For a synthetic property use keyed load IC followed by function call,
1848 // for a regular property use keyed CallIC. 1848 // for a regular property use keyed CallIC.
1849 VisitForValue(prop->obj(), kStack); 1849 VisitForValue(prop->obj(), kStack);
1850 if (prop->is_synthetic()) { 1850 if (prop->is_synthetic()) {
1851 VisitForValue(prop->key(), kAccumulator); 1851 VisitForValue(prop->key(), kAccumulator);
1852 // Record source code position for IC call. 1852 // Record source code position for IC call.
1853 SetSourcePosition(prop->position()); 1853 SetSourcePosition(prop->position());
1854 __ pop(r1); // We do not need to keep the receiver. 1854 __ pop(r1); // We do not need to keep the receiver.
1855 1855
1856 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1856 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1857 __ Call(ic, RelocInfo::CODE_TARGET); 1857 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1858 __ ldr(r1, CodeGenerator::GlobalObject()); 1858 __ ldr(r1, CodeGenerator::GlobalObject());
1859 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 1859 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
1860 __ Push(r0, r1); // Function, receiver. 1860 __ Push(r0, r1); // Function, receiver.
1861 EmitCallWithStub(expr); 1861 EmitCallWithStub(expr);
1862 } else { 1862 } else {
1863 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 1863 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
1864 } 1864 }
1865 } 1865 }
1866 } else { 1866 } else {
1867 // Call to some other expression. If the expression is an anonymous 1867 // Call to some other expression. If the expression is an anonymous
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 int arg_count = args->length(); 2762 int arg_count = args->length();
2763 for (int i = 0; i < arg_count; i++) { 2763 for (int i = 0; i < arg_count; i++) {
2764 VisitForValue(args->at(i), kStack); 2764 VisitForValue(args->at(i), kStack);
2765 } 2765 }
2766 2766
2767 if (expr->is_jsruntime()) { 2767 if (expr->is_jsruntime()) {
2768 // Call the JS runtime function. 2768 // Call the JS runtime function.
2769 __ mov(r2, Operand(expr->name())); 2769 __ mov(r2, Operand(expr->name()));
2770 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 2770 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
2771 NOT_IN_LOOP); 2771 NOT_IN_LOOP);
2772 __ Call(ic, RelocInfo::CODE_TARGET); 2772 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2773 // Restore context register. 2773 // Restore context register.
2774 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2774 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2775 } else { 2775 } else {
2776 // Call the C runtime function. 2776 // Call the C runtime function.
2777 __ CallRuntime(expr->function(), arg_count); 2777 __ CallRuntime(expr->function(), arg_count);
2778 } 2778 }
2779 Apply(context_, r0); 2779 Apply(context_, r0);
2780 } 2780 }
2781 2781
2782 2782
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3058 } else { 3058 } else {
3059 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3059 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3060 Token::ASSIGN, 3060 Token::ASSIGN,
3061 context_); 3061 context_);
3062 } 3062 }
3063 break; 3063 break;
3064 case NAMED_PROPERTY: { 3064 case NAMED_PROPERTY: {
3065 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 3065 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
3066 __ pop(r1); 3066 __ pop(r1);
3067 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 3067 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
3068 __ Call(ic, RelocInfo::CODE_TARGET); 3068 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3069 if (expr->is_postfix()) { 3069 if (expr->is_postfix()) {
3070 if (context_ != Expression::kEffect) { 3070 if (context_ != Expression::kEffect) {
3071 ApplyTOS(context_); 3071 ApplyTOS(context_);
3072 } 3072 }
3073 } else { 3073 } else {
3074 Apply(context_, r0); 3074 Apply(context_, r0);
3075 } 3075 }
3076 break; 3076 break;
3077 } 3077 }
3078 case KEYED_PROPERTY: { 3078 case KEYED_PROPERTY: {
3079 __ pop(r1); // Key. 3079 __ pop(r1); // Key.
3080 __ pop(r2); // Receiver. 3080 __ pop(r2); // Receiver.
3081 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 3081 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
3082 __ Call(ic, RelocInfo::CODE_TARGET); 3082 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3083 if (expr->is_postfix()) { 3083 if (expr->is_postfix()) {
3084 if (context_ != Expression::kEffect) { 3084 if (context_ != Expression::kEffect) {
3085 ApplyTOS(context_); 3085 ApplyTOS(context_);
3086 } 3086 }
3087 } else { 3087 } else {
3088 Apply(context_, r0); 3088 Apply(context_, r0);
3089 } 3089 }
3090 break; 3090 break;
3091 } 3091 }
3092 } 3092 }
3093 } 3093 }
3094 3094
3095 3095
3096 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { 3096 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
3097 VariableProxy* proxy = expr->AsVariableProxy(); 3097 VariableProxy* proxy = expr->AsVariableProxy();
3098 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3098 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3099 Comment cmnt(masm_, "Global variable"); 3099 Comment cmnt(masm_, "Global variable");
3100 __ ldr(r0, CodeGenerator::GlobalObject()); 3100 __ ldr(r0, CodeGenerator::GlobalObject());
3101 __ mov(r2, Operand(proxy->name())); 3101 __ mov(r2, Operand(proxy->name()));
3102 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3102 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
3103 // Use a regular load, not a contextual load, to avoid a reference 3103 // Use a regular load, not a contextual load, to avoid a reference
3104 // error. 3104 // error.
3105 __ Call(ic, RelocInfo::CODE_TARGET); 3105 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3106 if (where == kStack) __ push(r0); 3106 if (where == kStack) __ push(r0);
3107 } else if (proxy != NULL && 3107 } else if (proxy != NULL &&
3108 proxy->var()->slot() != NULL && 3108 proxy->var()->slot() != NULL &&
3109 proxy->var()->slot()->type() == Slot::LOOKUP) { 3109 proxy->var()->slot()->type() == Slot::LOOKUP) {
3110 Label done, slow; 3110 Label done, slow;
3111 3111
3112 // Generate code for loading from variables potentially shadowed 3112 // Generate code for loading from variables potentially shadowed
3113 // by eval-introduced variables. 3113 // by eval-introduced variables.
3114 Slot* slot = proxy->var()->slot(); 3114 Slot* slot = proxy->var()->slot();
3115 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); 3115 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
3358 Apply(context_, if_true, if_false); 3358 Apply(context_, if_true, if_false);
3359 } 3359 }
3360 3360
3361 3361
3362 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 3362 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
3363 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3363 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3364 Apply(context_, r0); 3364 Apply(context_, r0);
3365 } 3365 }
3366 3366
3367 3367
3368 Register FullCodeGenerator::result_register() { return r0; } 3368 Register FullCodeGenerator::result_register() {
3369 return r0;
3370 }
3369 3371
3370 3372
3371 Register FullCodeGenerator::context_register() { return cp; } 3373 Register FullCodeGenerator::context_register() {
3374 return cp;
3375 }
3376
3377
3378 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
3379 ASSERT(mode == RelocInfo::CODE_TARGET ||
3380 mode == RelocInfo::CODE_TARGET_CONTEXT);
3381 __ Call(ic, mode);
3382 }
3372 3383
3373 3384
3374 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 3385 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
3375 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 3386 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
3376 __ str(value, MemOperand(fp, frame_offset)); 3387 __ str(value, MemOperand(fp, frame_offset));
3377 } 3388 }
3378 3389
3379 3390
3380 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 3391 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
3381 __ ldr(dst, ContextOperand(cp, context_index)); 3392 __ ldr(dst, ContextOperand(cp, context_index));
(...skipping 26 matching lines...) Expand all
3408 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3419 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3409 __ add(pc, r1, Operand(masm_->CodeObject())); 3420 __ add(pc, r1, Operand(masm_->CodeObject()));
3410 } 3421 }
3411 3422
3412 3423
3413 #undef __ 3424 #undef __
3414 3425
3415 } } // namespace v8::internal 3426 } } // namespace v8::internal
3416 3427
3417 #endif // V8_TARGET_ARCH_ARM 3428 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698