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

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

Issue 502028: Streamline the calling convention of the call ICs by passing the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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/codegen-ia32.cc ('k') | src/ia32/ic-ia32.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 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 // By emitting a nop we make sure that we do not have a "test eax,..." 1059 // By emitting a nop we make sure that we do not have a "test eax,..."
1060 // instruction after the call it is treated specially by the LoadIC code. 1060 // instruction after the call it is treated specially by the LoadIC code.
1061 __ nop(); 1061 __ nop();
1062 // Drop key left on the stack by IC. 1062 // Drop key left on the stack by IC.
1063 __ add(Operand(esp), Immediate(kPointerSize)); 1063 __ add(Operand(esp), Immediate(kPointerSize));
1064 } 1064 }
1065 DropAndMove(expr->context(), eax); 1065 DropAndMove(expr->context(), eax);
1066 } 1066 }
1067 1067
1068 1068
1069 void FastCodeGenerator::EmitCallWithIC(Call* expr, RelocInfo::Mode reloc_info) { 1069 void FastCodeGenerator::EmitCallWithIC(Call* expr,
1070 Handle<Object> name,
1071 RelocInfo::Mode mode) {
1070 // Code common for calls using the IC. 1072 // Code common for calls using the IC.
1071 ZoneList<Expression*>* args = expr->arguments(); 1073 ZoneList<Expression*>* args = expr->arguments();
1072 int arg_count = args->length(); 1074 int arg_count = args->length();
1073 for (int i = 0; i < arg_count; i++) { 1075 for (int i = 0; i < arg_count; i++) {
1074 Visit(args->at(i)); 1076 Visit(args->at(i));
1075 ASSERT_EQ(Expression::kValue, args->at(i)->context()); 1077 ASSERT_EQ(Expression::kValue, args->at(i)->context());
1076 } 1078 }
1077 // Record source position for debugger. 1079 __ Set(ecx, Immediate(name));
1080 // Record source position of the IC call.
1078 SetSourcePosition(expr->position()); 1081 SetSourcePosition(expr->position());
1079 // Call the IC initialization code. 1082 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1080 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1083 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1081 NOT_IN_LOOP); 1084 __ call(ic, mode);
1082 __ call(ic, reloc_info);
1083 // Restore context register. 1085 // Restore context register.
1084 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1086 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1085 // Discard the function left on TOS. 1087 Move(expr->context(), eax);
1086 DropAndMove(expr->context(), eax);
1087 } 1088 }
1088 1089
1089 1090
1090 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1091 void FastCodeGenerator::EmitCallWithStub(Call* expr) {
1091 // Code common for calls using the call stub. 1092 // Code common for calls using the call stub.
1092 ZoneList<Expression*>* args = expr->arguments(); 1093 ZoneList<Expression*>* args = expr->arguments();
1093 int arg_count = args->length(); 1094 int arg_count = args->length();
1094 for (int i = 0; i < arg_count; i++) { 1095 for (int i = 0; i < arg_count; i++) {
1095 Visit(args->at(i)); 1096 Visit(args->at(i));
1096 } 1097 }
1097 // Record source position for debugger. 1098 // Record source position for debugger.
1098 SetSourcePosition(expr->position()); 1099 SetSourcePosition(expr->position());
1099 CallFunctionStub stub(arg_count, NOT_IN_LOOP); 1100 CallFunctionStub stub(arg_count, NOT_IN_LOOP);
1100 __ CallStub(&stub); 1101 __ CallStub(&stub);
1101 // Restore context register. 1102 // Restore context register.
1102 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1103 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1103 // Discard the function left on TOS.
1104 DropAndMove(expr->context(), eax); 1104 DropAndMove(expr->context(), eax);
1105 } 1105 }
1106 1106
1107 1107
1108 void FastCodeGenerator::VisitCall(Call* expr) { 1108 void FastCodeGenerator::VisitCall(Call* expr) {
1109 Comment cmnt(masm_, "[ Call"); 1109 Comment cmnt(masm_, "[ Call");
1110 Expression* fun = expr->expression(); 1110 Expression* fun = expr->expression();
1111 Variable* var = fun->AsVariableProxy()->AsVariable(); 1111 Variable* var = fun->AsVariableProxy()->AsVariable();
1112 1112
1113 if (var != NULL && var->is_possibly_eval()) { 1113 if (var != NULL && var->is_possibly_eval()) {
1114 // Call to the identifier 'eval'. 1114 // Call to the identifier 'eval'.
1115 UNREACHABLE(); 1115 UNREACHABLE();
1116 } else if (var != NULL && !var->is_this() && var->is_global()) { 1116 } else if (var != NULL && !var->is_this() && var->is_global()) {
1117 // Call to a global variable. 1117 // Push global object as receiver for the call IC.
1118 __ push(Immediate(var->name()));
1119 // Push global object as receiver for the call IC lookup.
1120 __ push(CodeGenerator::GlobalObject()); 1118 __ push(CodeGenerator::GlobalObject());
1121 EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT); 1119 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
1122 } else if (var != NULL && var->slot() != NULL && 1120 } else if (var != NULL && var->slot() != NULL &&
1123 var->slot()->type() == Slot::LOOKUP) { 1121 var->slot()->type() == Slot::LOOKUP) {
1124 // Call to a lookup slot. 1122 // Call to a lookup slot.
1125 UNREACHABLE(); 1123 UNREACHABLE();
1126 } else if (fun->AsProperty() != NULL) { 1124 } else if (fun->AsProperty() != NULL) {
1127 // Call to an object property. 1125 // Call to an object property.
1128 Property* prop = fun->AsProperty(); 1126 Property* prop = fun->AsProperty();
1129 Literal* key = prop->key()->AsLiteral(); 1127 Literal* key = prop->key()->AsLiteral();
1130 if (key != NULL && key->handle()->IsSymbol()) { 1128 if (key != NULL && key->handle()->IsSymbol()) {
1131 // Call to a named property, use call IC. 1129 // Call to a named property, use call IC.
1132 __ push(Immediate(key->handle()));
1133 Visit(prop->obj()); 1130 Visit(prop->obj());
1134 EmitCallWithIC(expr, RelocInfo::CODE_TARGET); 1131 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
1135 } else { 1132 } else {
1136 // Call to a keyed property, use keyed load IC followed by function 1133 // Call to a keyed property, use keyed load IC followed by function
1137 // call. 1134 // call.
1138 Visit(prop->obj()); 1135 Visit(prop->obj());
1139 Visit(prop->key()); 1136 Visit(prop->key());
1140 // Record source code position for IC call. 1137 // Record source code position for IC call.
1141 SetSourcePosition(prop->position()); 1138 SetSourcePosition(prop->position());
1142 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1139 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1143 __ call(ic, RelocInfo::CODE_TARGET); 1140 __ call(ic, RelocInfo::CODE_TARGET);
1144 // By emitting a nop we make sure that we do not have a "test eax,..." 1141 // By emitting a nop we make sure that we do not have a "test eax,..."
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 DropAndMove(expr->context(), eax); 1213 DropAndMove(expr->context(), eax);
1217 } 1214 }
1218 1215
1219 1216
1220 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1217 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1221 Comment cmnt(masm_, "[ CallRuntime"); 1218 Comment cmnt(masm_, "[ CallRuntime");
1222 ZoneList<Expression*>* args = expr->arguments(); 1219 ZoneList<Expression*>* args = expr->arguments();
1223 1220
1224 if (expr->is_jsruntime()) { 1221 if (expr->is_jsruntime()) {
1225 // Prepare for calling JS runtime function. 1222 // Prepare for calling JS runtime function.
1226 __ push(Immediate(expr->name()));
1227 __ mov(eax, CodeGenerator::GlobalObject()); 1223 __ mov(eax, CodeGenerator::GlobalObject());
1228 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 1224 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
1229 } 1225 }
1230 1226
1231 // Push the arguments ("left-to-right"). 1227 // Push the arguments ("left-to-right").
1232 int arg_count = args->length(); 1228 int arg_count = args->length();
1233 for (int i = 0; i < arg_count; i++) { 1229 for (int i = 0; i < arg_count; i++) {
1234 Visit(args->at(i)); 1230 Visit(args->at(i));
1235 ASSERT_EQ(Expression::kValue, args->at(i)->context()); 1231 ASSERT_EQ(Expression::kValue, args->at(i)->context());
1236 } 1232 }
1237 1233
1238 if (expr->is_jsruntime()) { 1234 if (expr->is_jsruntime()) {
1239 // Call the JS runtime function. 1235 // Call the JS runtime function via a call IC.
1240 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1236 __ Set(ecx, Immediate(expr->name()));
1241 NOT_IN_LOOP); 1237 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1238 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1242 __ call(ic, RelocInfo::CODE_TARGET); 1239 __ call(ic, RelocInfo::CODE_TARGET);
1243 // Restore context register. 1240 // Restore context register.
1244 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1241 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1245 // Discard the function left on TOS.
1246 DropAndMove(expr->context(), eax);
1247 } else { 1242 } else {
1248 // Call the C runtime function. 1243 // Call the C runtime function.
1249 __ CallRuntime(expr->function(), arg_count); 1244 __ CallRuntime(expr->function(), arg_count);
1250 Move(expr->context(), eax);
1251 } 1245 }
1246 Move(expr->context(), eax);
1252 } 1247 }
1253 1248
1254 1249
1255 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 1250 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1256 switch (expr->op()) { 1251 switch (expr->op()) {
1257 case Token::VOID: { 1252 case Token::VOID: {
1258 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 1253 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1259 Visit(expr->expression()); 1254 Visit(expr->expression());
1260 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); 1255 ASSERT_EQ(Expression::kEffect, expr->expression()->context());
1261 switch (expr->context()) { 1256 switch (expr->context()) {
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 1707
1713 1708
1714 void FastCodeGenerator::ThrowException() { 1709 void FastCodeGenerator::ThrowException() {
1715 __ push(result_register()); 1710 __ push(result_register());
1716 __ CallRuntime(Runtime::kThrow, 1); 1711 __ CallRuntime(Runtime::kThrow, 1);
1717 } 1712 }
1718 1713
1719 #undef __ 1714 #undef __
1720 1715
1721 } } // namespace v8::internal 1716 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698