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

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

Issue 2024002: Pass key and receiver in registers for keyed load IC on ARM... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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/arm/codegen-arm.cc ('k') | src/arm/ic-arm.cc » ('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 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 Move(r1, object_slot); 731 Move(r1, object_slot);
732 732
733 // Assert that the key is a smi. 733 // Assert that the key is a smi.
734 Literal* key_literal = property->key()->AsLiteral(); 734 Literal* key_literal = property->key()->AsLiteral();
735 ASSERT_NOT_NULL(key_literal); 735 ASSERT_NOT_NULL(key_literal);
736 ASSERT(key_literal->handle()->IsSmi()); 736 ASSERT(key_literal->handle()->IsSmi());
737 737
738 // Load the key. 738 // Load the key.
739 __ mov(r0, Operand(key_literal->handle())); 739 __ mov(r0, Operand(key_literal->handle()));
740 740
741 // Push both as arguments to ic. 741 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
742 __ Push(r1, r0);
743
744 // Call keyed load IC. It has all arguments on the stack and the key in r0.
745 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 742 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
746 __ Call(ic, RelocInfo::CODE_TARGET); 743 __ Call(ic, RelocInfo::CODE_TARGET);
747 744 Apply(context, r0);
748 // Drop key and object left on the stack by IC, and push the result.
749 DropAndApply(2, context, r0);
750 } 745 }
751 } 746 }
752 747
753 748
754 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 749 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
755 Comment cmnt(masm_, "[ RegExpLiteral"); 750 Comment cmnt(masm_, "[ RegExpLiteral");
756 Label done; 751 Label done;
757 // Registers will be used as follows: 752 // Registers will be used as follows:
758 // r4 = JS function, literals array 753 // r4 = JS function, literals array
759 // r3 = literal index 754 // r3 = literal index
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 case NAMED_PROPERTY: 923 case NAMED_PROPERTY:
929 if (expr->is_compound()) { 924 if (expr->is_compound()) {
930 // We need the receiver both on the stack and in the accumulator. 925 // We need the receiver both on the stack and in the accumulator.
931 VisitForValue(prop->obj(), kAccumulator); 926 VisitForValue(prop->obj(), kAccumulator);
932 __ push(result_register()); 927 __ push(result_register());
933 } else { 928 } else {
934 VisitForValue(prop->obj(), kStack); 929 VisitForValue(prop->obj(), kStack);
935 } 930 }
936 break; 931 break;
937 case KEYED_PROPERTY: 932 case KEYED_PROPERTY:
938 VisitForValue(prop->obj(), kStack); 933 // We need the key and receiver on both the stack and in r0 and r1.
939 VisitForValue(prop->key(), kStack); 934 if (expr->is_compound()) {
935 VisitForValue(prop->obj(), kStack);
936 VisitForValue(prop->key(), kAccumulator);
937 __ ldr(r1, MemOperand(sp, 0));
938 __ push(r0);
939 } else {
940 VisitForValue(prop->obj(), kStack);
941 VisitForValue(prop->key(), kStack);
942 }
940 break; 943 break;
941 } 944 }
942 945
943 // If we have a compound assignment: Get value of LHS expression and 946 // If we have a compound assignment: Get value of LHS expression and
944 // store in on top of the stack. 947 // store in on top of the stack.
945 if (expr->is_compound()) { 948 if (expr->is_compound()) {
946 Location saved_location = location_; 949 Location saved_location = location_;
947 location_ = kStack; 950 location_ = kStack;
948 switch (assign_type) { 951 switch (assign_type) {
949 case VARIABLE: 952 case VARIABLE:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 Literal* key = prop->key()->AsLiteral(); 1001 Literal* key = prop->key()->AsLiteral();
999 __ mov(r2, Operand(key->handle())); 1002 __ mov(r2, Operand(key->handle()));
1000 __ ldr(r0, MemOperand(sp, 0)); 1003 __ ldr(r0, MemOperand(sp, 0));
1001 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1004 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1002 __ Call(ic, RelocInfo::CODE_TARGET); 1005 __ Call(ic, RelocInfo::CODE_TARGET);
1003 } 1006 }
1004 1007
1005 1008
1006 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1009 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1007 SetSourcePosition(prop->position()); 1010 SetSourcePosition(prop->position());
1008 // Call keyed load IC. It has all arguments on the stack and the key in r0. 1011 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1009 __ ldr(r0, MemOperand(sp, 0));
1010 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1012 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1011 __ Call(ic, RelocInfo::CODE_TARGET); 1013 __ Call(ic, RelocInfo::CODE_TARGET);
1012 } 1014 }
1013 1015
1014 1016
1015 void FullCodeGenerator::EmitBinaryOp(Token::Value op, 1017 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1016 Expression::Context context) { 1018 Expression::Context context) {
1017 __ pop(r1); 1019 __ pop(r1);
1018 GenericBinaryOpStub stub(op, NO_OVERWRITE, r1, r0); 1020 GenericBinaryOpStub stub(op, NO_OVERWRITE, r1, r0);
1019 __ CallStub(&stub); 1021 __ CallStub(&stub);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 Expression* key = expr->key(); 1166 Expression* key = expr->key();
1165 1167
1166 // Evaluate receiver. 1168 // Evaluate receiver.
1167 VisitForValue(expr->obj(), kStack); 1169 VisitForValue(expr->obj(), kStack);
1168 1170
1169 if (key->IsPropertyName()) { 1171 if (key->IsPropertyName()) {
1170 EmitNamedPropertyLoad(expr); 1172 EmitNamedPropertyLoad(expr);
1171 // Drop receiver left on the stack by IC. 1173 // Drop receiver left on the stack by IC.
1172 DropAndApply(1, context_, r0); 1174 DropAndApply(1, context_, r0);
1173 } else { 1175 } else {
1174 VisitForValue(expr->key(), kStack); 1176 VisitForValue(expr->key(), kAccumulator);
1177 __ pop(r1);
1175 EmitKeyedPropertyLoad(expr); 1178 EmitKeyedPropertyLoad(expr);
1176 // Drop key and receiver left on the stack by IC. 1179 Apply(context_, r0);
1177 DropAndApply(2, context_, r0);
1178 } 1180 }
1179 } 1181 }
1180 1182
1181 void FullCodeGenerator::EmitCallWithIC(Call* expr, 1183 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1182 Handle<Object> name, 1184 Handle<Object> name,
1183 RelocInfo::Mode mode) { 1185 RelocInfo::Mode mode) {
1184 // Code common for calls using the IC. 1186 // Code common for calls using the IC.
1185 ZoneList<Expression*>* args = expr->arguments(); 1187 ZoneList<Expression*>* args = expr->arguments();
1186 int arg_count = args->length(); 1188 int arg_count = args->length();
1187 for (int i = 0; i < arg_count; i++) { 1189 for (int i = 0; i < arg_count; i++) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 Property* prop = fun->AsProperty(); 1241 Property* prop = fun->AsProperty();
1240 Literal* key = prop->key()->AsLiteral(); 1242 Literal* key = prop->key()->AsLiteral();
1241 if (key != NULL && key->handle()->IsSymbol()) { 1243 if (key != NULL && key->handle()->IsSymbol()) {
1242 // Call to a named property, use call IC. 1244 // Call to a named property, use call IC.
1243 VisitForValue(prop->obj(), kStack); 1245 VisitForValue(prop->obj(), kStack);
1244 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 1246 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
1245 } else { 1247 } else {
1246 // Call to a keyed property, use keyed load IC followed by function 1248 // Call to a keyed property, use keyed load IC followed by function
1247 // call. 1249 // call.
1248 VisitForValue(prop->obj(), kStack); 1250 VisitForValue(prop->obj(), kStack);
1249 VisitForValue(prop->key(), kStack); 1251 VisitForValue(prop->key(), kAccumulator);
1250 // Record source code position for IC call. 1252 // Record source code position for IC call.
1251 SetSourcePosition(prop->position()); 1253 SetSourcePosition(prop->position());
1252 // Call keyed load IC. It has all arguments on the stack and the key in 1254 if (prop->is_synthetic()) {
1253 // r0. 1255 __ pop(r1); // We do not need to keep the receiver.
1254 __ ldr(r0, MemOperand(sp, 0)); 1256 } else {
1257 __ ldr(r1, MemOperand(sp, 0)); // Keep receiver, to call function on.
1258 }
1259
1255 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1260 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1256 __ Call(ic, RelocInfo::CODE_TARGET); 1261 __ Call(ic, RelocInfo::CODE_TARGET);
1257 // Load receiver object into r1.
1258 if (prop->is_synthetic()) { 1262 if (prop->is_synthetic()) {
1263 // Push result (function).
1264 __ push(r0);
1265 // Push Global receiver.
1259 __ ldr(r1, CodeGenerator::GlobalObject()); 1266 __ ldr(r1, CodeGenerator::GlobalObject());
1260 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 1267 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
1268 __ push(r1);
1261 } else { 1269 } else {
1262 __ ldr(r1, MemOperand(sp, kPointerSize)); 1270 // Pop receiver.
1271 __ pop(r1);
1272 // Push result (function).
1273 __ push(r0);
1274 __ push(r1);
1263 } 1275 }
1264 // Overwrite (object, key) with (function, receiver).
1265 __ str(r0, MemOperand(sp, kPointerSize));
1266 __ str(r1, MemOperand(sp));
1267 EmitCallWithStub(expr); 1276 EmitCallWithStub(expr);
1268 } 1277 }
1269 } else { 1278 } else {
1270 // Call to some other expression. If the expression is an anonymous 1279 // Call to some other expression. If the expression is an anonymous
1271 // function literal not called in a loop, mark it as one that should 1280 // function literal not called in a loop, mark it as one that should
1272 // also use the fast code generator. 1281 // also use the fast code generator.
1273 FunctionLiteral* lit = fun->AsFunctionLiteral(); 1282 FunctionLiteral* lit = fun->AsFunctionLiteral();
1274 if (lit != NULL && 1283 if (lit != NULL &&
1275 lit->name()->Equals(Heap::empty_string()) && 1284 lit->name()->Equals(Heap::empty_string()) &&
1276 loop_depth() == 0) { 1285 loop_depth() == 0) {
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 } else { 1554 } else {
1546 // Reserve space for result of postfix operation. 1555 // Reserve space for result of postfix operation.
1547 if (expr->is_postfix() && context_ != Expression::kEffect) { 1556 if (expr->is_postfix() && context_ != Expression::kEffect) {
1548 __ mov(ip, Operand(Smi::FromInt(0))); 1557 __ mov(ip, Operand(Smi::FromInt(0)));
1549 __ push(ip); 1558 __ push(ip);
1550 } 1559 }
1551 VisitForValue(prop->obj(), kStack); 1560 VisitForValue(prop->obj(), kStack);
1552 if (assign_type == NAMED_PROPERTY) { 1561 if (assign_type == NAMED_PROPERTY) {
1553 EmitNamedPropertyLoad(prop); 1562 EmitNamedPropertyLoad(prop);
1554 } else { 1563 } else {
1555 VisitForValue(prop->key(), kStack); 1564 VisitForValue(prop->key(), kAccumulator);
1565 __ ldr(r1, MemOperand(sp, 0));
1566 __ push(r0);
1556 EmitKeyedPropertyLoad(prop); 1567 EmitKeyedPropertyLoad(prop);
1557 } 1568 }
1558 } 1569 }
1559 1570
1560 // Call ToNumber only if operand is not a smi. 1571 // Call ToNumber only if operand is not a smi.
1561 Label no_conversion; 1572 Label no_conversion;
1562 __ tst(r0, Operand(kSmiTagMask)); 1573 __ tst(r0, Operand(kSmiTagMask));
1563 __ b(eq, &no_conversion); 1574 __ b(eq, &no_conversion);
1564 __ push(r0); 1575 __ push(r0);
1565 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); 1576 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 __ pop(result_register()); 1870 __ pop(result_register());
1860 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 1871 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
1861 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 1872 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
1862 __ add(pc, r1, Operand(masm_->CodeObject())); 1873 __ add(pc, r1, Operand(masm_->CodeObject()));
1863 } 1874 }
1864 1875
1865 1876
1866 #undef __ 1877 #undef __
1867 1878
1868 } } // namespace v8::internal 1879 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698