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

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

Issue 523052: More cleanup of slot handling in the nonoptimizing code generator.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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/fast-codegen.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 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 __ mov(eax, Operand(esp, 0)); 254 __ mov(eax, Operand(esp, 0));
255 TestAndBranch(eax, &discard, false_label_); 255 TestAndBranch(eax, &discard, false_label_);
256 __ bind(&discard); 256 __ bind(&discard);
257 __ Drop(1); 257 __ Drop(1);
258 __ jmp(true_label_); 258 __ jmp(true_label_);
259 } 259 }
260 } 260 }
261 } 261 }
262 262
263 263
264 template <> 264 MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
265 Operand FastCodeGenerator::CreateSlotOperand<Operand>(Slot* source, 265 switch (slot->type()) {
266 Register scratch) {
267 switch (source->type()) {
268 case Slot::PARAMETER: 266 case Slot::PARAMETER:
269 case Slot::LOCAL: 267 case Slot::LOCAL:
270 return Operand(ebp, SlotOffset(source)); 268 return Operand(ebp, SlotOffset(slot));
271 case Slot::CONTEXT: { 269 case Slot::CONTEXT: {
272 int context_chain_length = 270 int context_chain_length =
273 function_->scope()->ContextChainLength(source->var()->scope()); 271 function_->scope()->ContextChainLength(slot->var()->scope());
274 __ LoadContext(scratch, context_chain_length); 272 __ LoadContext(scratch, context_chain_length);
275 return CodeGenerator::ContextOperand(scratch, source->index()); 273 return CodeGenerator::ContextOperand(scratch, slot->index());
276 } 274 }
277 case Slot::LOOKUP: 275 case Slot::LOOKUP:
278 UNIMPLEMENTED(); 276 UNREACHABLE();
279 } 277 }
280 UNREACHABLE(); 278 UNREACHABLE();
281 return Operand(eax, 0); 279 return Operand(eax, 0);
282 } 280 }
283 281
284 282
285 void FastCodeGenerator::Move(Register dst, Slot* source) { 283 void FastCodeGenerator::Move(Register destination, Slot* source) {
286 Operand location = CreateSlotOperand<Operand>(source, dst); 284 MemOperand location = EmitSlotSearch(source, destination);
287 __ mov(dst, location); 285 __ mov(destination, location);
288 } 286 }
289 287
290 288
291 void FastCodeGenerator::Move(Expression::Context context, 289 void FastCodeGenerator::Move(Expression::Context context,
292 Slot* source, 290 Slot* source,
293 Register scratch) { 291 Register scratch) {
294 switch (context) { 292 switch (context) {
295 case Expression::kUninitialized: 293 case Expression::kUninitialized:
296 UNREACHABLE(); 294 UNREACHABLE();
297 case Expression::kEffect: 295 case Expression::kEffect:
298 break; 296 break;
299 case Expression::kValue: { 297 case Expression::kValue: {
300 Operand location = CreateSlotOperand<Operand>(source, scratch); 298 MemOperand location = EmitSlotSearch(source, scratch);
301 __ push(location); 299 __ push(location);
302 break; 300 break;
303 } 301 }
304 case Expression::kTest: 302 case Expression::kTest:
305 case Expression::kValueTest: 303 case Expression::kValueTest:
306 case Expression::kTestValue: 304 case Expression::kTestValue:
307 Move(scratch, source); 305 Move(scratch, source);
308 Move(context, scratch); 306 Move(context, scratch);
309 break; 307 break;
310 } 308 }
(...skipping 16 matching lines...) Expand all
327 Move(context, eax); 325 Move(context, eax);
328 break; 326 break;
329 } 327 }
330 } 328 }
331 329
332 330
333 void FastCodeGenerator::Move(Slot* dst, 331 void FastCodeGenerator::Move(Slot* dst,
334 Register src, 332 Register src,
335 Register scratch1, 333 Register scratch1,
336 Register scratch2) { 334 Register scratch2) {
337 switch (dst->type()) { 335 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
338 case Slot::PARAMETER: 336 ASSERT(!scratch1.is(src) && !scratch2.is(src));
339 case Slot::LOCAL: 337 MemOperand location = EmitSlotSearch(dst, scratch1);
340 __ mov(Operand(ebp, SlotOffset(dst)), src); 338 __ mov(location, src);
341 break; 339 // Emit the write barrier code if the location is in the heap.
342 case Slot::CONTEXT: { 340 if (dst->type() == Slot::CONTEXT) {
343 ASSERT(!src.is(scratch1)); 341 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
344 ASSERT(!src.is(scratch2)); 342 __ RecordWrite(scratch1, offset, src, scratch2);
345 ASSERT(!scratch1.is(scratch2));
346 int context_chain_length =
347 function_->scope()->ContextChainLength(dst->var()->scope());
348 __ LoadContext(scratch1, context_chain_length);
349 __ mov(Operand(scratch1, Context::SlotOffset(dst->index())), src);
350 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
351 __ RecordWrite(scratch1, offset, src, scratch2);
352 break;
353 }
354 case Slot::LOOKUP:
355 UNIMPLEMENTED();
356 } 343 }
357 } 344 }
358 345
359 346
360 void FastCodeGenerator::DropAndMove(Expression::Context context, 347 void FastCodeGenerator::DropAndMove(Expression::Context context,
361 Register source, 348 Register source,
362 int count) { 349 int count) {
363 ASSERT(count > 0); 350 ASSERT(count > 0);
364 switch (context) { 351 switch (context) {
365 case Expression::kUninitialized: 352 case Expression::kUninitialized:
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 Variable* var = decl->proxy()->var(); 428 Variable* var = decl->proxy()->var();
442 ASSERT(var != NULL); // Must have been resolved. 429 ASSERT(var != NULL); // Must have been resolved.
443 Slot* slot = var->slot(); 430 Slot* slot = var->slot();
444 Property* prop = var->AsProperty(); 431 Property* prop = var->AsProperty();
445 432
446 if (slot != NULL) { 433 if (slot != NULL) {
447 switch (slot->type()) { 434 switch (slot->type()) {
448 case Slot::PARAMETER: 435 case Slot::PARAMETER:
449 case Slot::LOCAL: 436 case Slot::LOCAL:
450 if (decl->mode() == Variable::CONST) { 437 if (decl->mode() == Variable::CONST) {
451 __ mov(Operand(ebp, SlotOffset(var->slot())), 438 __ mov(Operand(ebp, SlotOffset(slot)),
452 Immediate(Factory::the_hole_value())); 439 Immediate(Factory::the_hole_value()));
453 } else if (decl->fun() != NULL) { 440 } else if (decl->fun() != NULL) {
454 Visit(decl->fun()); 441 Visit(decl->fun());
455 __ pop(Operand(ebp, SlotOffset(var->slot()))); 442 __ pop(Operand(ebp, SlotOffset(slot)));
456 } 443 }
457 break; 444 break;
458 445
459 case Slot::CONTEXT: 446 case Slot::CONTEXT:
447 // We bypass the general EmitSlotSearch because we know more about
448 // this specific context.
449
460 // The variable in the decl always resides in the current context. 450 // The variable in the decl always resides in the current context.
461 ASSERT_EQ(0, function_->scope()->ContextChainLength(var->scope())); 451 ASSERT_EQ(0, function_->scope()->ContextChainLength(var->scope()));
462 if (FLAG_debug_code) { 452 if (FLAG_debug_code) {
463 // Check if we have the correct context pointer. 453 // Check if we have the correct context pointer.
464 __ mov(ebx, 454 __ mov(ebx,
465 CodeGenerator::ContextOperand(esi, Context::FCONTEXT_INDEX)); 455 CodeGenerator::ContextOperand(esi, Context::FCONTEXT_INDEX));
466 __ cmp(ebx, Operand(esi)); 456 __ cmp(ebx, Operand(esi));
467 __ Check(equal, "Unexpected declaration in current context."); 457 __ Check(equal, "Unexpected declaration in current context.");
468 } 458 }
469 if (decl->mode() == Variable::CONST) { 459 if (decl->mode() == Variable::CONST) {
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 887 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
898 __ call(ic, RelocInfo::CODE_TARGET); 888 __ call(ic, RelocInfo::CODE_TARGET);
899 // Overwrite the receiver on the stack with the result if needed. 889 // Overwrite the receiver on the stack with the result if needed.
900 DropAndMove(context, eax); 890 DropAndMove(context, eax);
901 891
902 } else if (var->slot() != NULL) { 892 } else if (var->slot() != NULL) {
903 Slot* slot = var->slot(); 893 Slot* slot = var->slot();
904 switch (slot->type()) { 894 switch (slot->type()) {
905 case Slot::LOCAL: 895 case Slot::LOCAL:
906 case Slot::PARAMETER: { 896 case Slot::PARAMETER: {
907 Operand target = Operand(ebp, SlotOffset(var->slot())); 897 Operand target = Operand(ebp, SlotOffset(slot));
908 switch (context) { 898 switch (context) {
909 case Expression::kUninitialized: 899 case Expression::kUninitialized:
910 UNREACHABLE(); 900 UNREACHABLE();
911 case Expression::kEffect: 901 case Expression::kEffect:
912 // Perform assignment and discard value. 902 // Perform assignment and discard value.
913 __ pop(target); 903 __ pop(target);
914 break; 904 break;
915 case Expression::kValue: 905 case Expression::kValue:
916 // Perform assignment and preserve value. 906 // Perform assignment and preserve value.
917 __ mov(eax, Operand(esp, 0)); 907 __ mov(eax, Operand(esp, 0));
(...skipping 23 matching lines...) Expand all
941 __ bind(&discard); 931 __ bind(&discard);
942 __ add(Operand(esp), Immediate(kPointerSize)); 932 __ add(Operand(esp), Immediate(kPointerSize));
943 __ jmp(true_label_); 933 __ jmp(true_label_);
944 break; 934 break;
945 } 935 }
946 } 936 }
947 break; 937 break;
948 } 938 }
949 939
950 case Slot::CONTEXT: { 940 case Slot::CONTEXT: {
951 int chain_length = 941 MemOperand target = EmitSlotSearch(slot, ecx);
952 function_->scope()->ContextChainLength(slot->var()->scope()); 942 __ pop(eax);
953 if (chain_length > 0) { 943 __ mov(target, eax);
954 // Move up the context chain to the context containing the slot.
955 __ mov(eax,
956 Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX)));
957 // Load the function context (which is the incoming, outer context).
958 __ mov(eax, FieldOperand(eax, JSFunction::kContextOffset));
959 for (int i = 1; i < chain_length; i++) {
960 __ mov(eax,
961 Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)));
962 __ mov(eax, FieldOperand(eax, JSFunction::kContextOffset));
963 }
964 } else { // Slot is in the current context. Generate optimized code.
965 __ mov(eax, esi); // RecordWrite destroys the object register.
966 }
967 if (FLAG_debug_code) {
968 __ cmp(eax,
969 Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)));
970 __ Check(equal, "Context Slot chain length wrong.");
971 }
972 __ pop(ecx);
973 __ mov(Operand(eax, Context::SlotOffset(slot->index())), ecx);
974 944
975 // RecordWrite may destroy all its register arguments. 945 // RecordWrite may destroy all its register arguments.
976 if (context == Expression::kValue) { 946 if (context == Expression::kValue) {
977 __ push(ecx); 947 __ push(eax);
978 } else if (context != Expression::kEffect) { 948 } else if (context != Expression::kEffect) {
979 __ mov(edx, ecx); 949 __ mov(edx, eax);
980 } 950 }
981 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 951 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
982 __ RecordWrite(eax, offset, ecx, ebx); 952 __ RecordWrite(ecx, offset, eax, ebx);
983 if (context != Expression::kEffect && 953 if (context != Expression::kEffect &&
984 context != Expression::kValue) { 954 context != Expression::kValue) {
985 Move(context, edx); 955 Move(context, edx);
986 } 956 }
987 break; 957 break;
988 } 958 }
989 959
990 case Slot::LOOKUP: 960 case Slot::LOOKUP:
991 UNREACHABLE(); 961 UNREACHABLE();
992 break; 962 break;
993 } 963 }
964 } else {
965 // Variables rewritten as properties are not treated as variables in
966 // assignments.
967 UNREACHABLE();
994 } 968 }
995 } 969 }
996 970
997 971
998 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 972 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
999 // Assignment to a property, using a named store IC. 973 // Assignment to a property, using a named store IC.
1000 Property* prop = expr->target()->AsProperty(); 974 Property* prop = expr->target()->AsProperty();
1001 ASSERT(prop != NULL); 975 ASSERT(prop != NULL);
1002 ASSERT(prop->key()->AsLiteral() != NULL); 976 ASSERT(prop->key()->AsLiteral() != NULL);
1003 977
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 __ add(Operand(edx), Immediate(masm_->CodeObject())); 1767 __ add(Operand(edx), Immediate(masm_->CodeObject()));
1794 __ mov(Operand(esp, 0), edx); 1768 __ mov(Operand(esp, 0), edx);
1795 // And return. 1769 // And return.
1796 __ ret(0); 1770 __ ret(0);
1797 } 1771 }
1798 1772
1799 1773
1800 #undef __ 1774 #undef __
1801 1775
1802 } } // namespace v8::internal 1776 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698