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

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

Issue 42602: Simplify the way the code generator handles calls to IC stubs. Before... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 9 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/virtual-frame.cc » ('j') | src/virtual-frame-ia32.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 3217 matching lines...) Expand 10 before | Expand all | Expand 10 after
3228 __ mov(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX)); 3228 __ mov(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX));
3229 __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset)); 3229 __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
3230 __ jmp(&next); 3230 __ jmp(&next);
3231 __ bind(&fast); 3231 __ bind(&fast);
3232 } 3232 }
3233 context.Unuse(); 3233 context.Unuse();
3234 tmp.Unuse(); 3234 tmp.Unuse();
3235 3235
3236 // All extension objects were empty and it is safe to use a global 3236 // All extension objects were empty and it is safe to use a global
3237 // load IC call. 3237 // load IC call.
3238 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
3239 // Load the global object.
3240 LoadGlobal(); 3238 LoadGlobal();
3241 // Setup the name register. All non-reserved registers are available. 3239 frame_->Push(slot->var()->name());
3242 Result name = allocator_->Allocate(ecx); 3240 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
3243 ASSERT(name.is_valid()); 3241 ? RelocInfo::CODE_TARGET
3244 __ mov(name.reg(), slot->var()->name()); 3242 : RelocInfo::CODE_TARGET_CONTEXT;
3245 RelocInfo::Mode rmode = (typeof_state == INSIDE_TYPEOF) 3243 Result answer = frame_->CallLoadIC(mode);
3246 ? RelocInfo::CODE_TARGET
3247 : RelocInfo::CODE_TARGET_CONTEXT;
3248 Result answer = frame_->CallCodeObject(ic, rmode, &name, 0);
3249 3244
3250 // Discard the global object. The result is in answer. 3245 // Discard the global object. The result is in answer.
3251 frame_->Drop(); 3246 frame_->Drop();
3252 return answer; 3247 return answer;
3253 } 3248 }
3254 3249
3255 3250
3256 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { 3251 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
3257 if (slot->type() == Slot::LOOKUP) { 3252 if (slot->type() == Slot::LOOKUP) {
3258 ASSERT(slot->var()->is_dynamic()); 3253 ASSERT(slot->var()->is_dynamic());
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
3545 for (int i = 0; i < node->properties()->length(); i++) { 3540 for (int i = 0; i < node->properties()->length(); i++) {
3546 ObjectLiteral::Property* property = node->properties()->at(i); 3541 ObjectLiteral::Property* property = node->properties()->at(i);
3547 switch (property->kind()) { 3542 switch (property->kind()) {
3548 case ObjectLiteral::Property::CONSTANT: 3543 case ObjectLiteral::Property::CONSTANT:
3549 break; 3544 break;
3550 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 3545 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
3551 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 3546 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
3552 // else fall through. 3547 // else fall through.
3553 case ObjectLiteral::Property::COMPUTED: { 3548 case ObjectLiteral::Property::COMPUTED: {
3554 Handle<Object> key(property->key()->handle()); 3549 Handle<Object> key(property->key()->handle());
3555 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
3556 if (key->IsSymbol()) { 3550 if (key->IsSymbol()) {
3557 // Duplicate the object as the IC receiver. 3551 // Duplicate the object as the IC receiver.
3558 frame_->Dup(); 3552 frame_->Dup();
3559 Load(property->value()); 3553 Load(property->value());
3560 Result value = frame_->Pop(); 3554 frame_->Push(key);
3561 value.ToRegister(eax); 3555 Result ignored = frame_->CallStoreIC();
3562
3563 Result name = allocator_->Allocate(ecx);
3564 ASSERT(name.is_valid());
3565 __ Set(name.reg(), Immediate(key));
3566 Result ignored =
3567 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET,
3568 &value, &name, 0);
3569 // Drop the duplicated receiver and ignore the result. 3556 // Drop the duplicated receiver and ignore the result.
3570 frame_->Drop(); 3557 frame_->Drop();
3571 break; 3558 break;
3572 } 3559 }
3573 // Fall through 3560 // Fall through
3574 } 3561 }
3575 case ObjectLiteral::Property::PROTOTYPE: { 3562 case ObjectLiteral::Property::PROTOTYPE: {
3576 // Duplicate the object as an argument to the runtime call. 3563 // Duplicate the object as an argument to the runtime call.
3577 frame_->Dup(); 3564 frame_->Dup();
3578 Load(property->key()); 3565 Load(property->key());
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after
5180 Label* patch_site() { return &patch_site_; } 5167 Label* patch_site() { return &patch_site_; }
5181 5168
5182 private: 5169 private:
5183 Label patch_site_; 5170 Label patch_site_;
5184 bool is_global_; 5171 bool is_global_;
5185 }; 5172 };
5186 5173
5187 5174
5188 void DeferredReferenceGetKeyedValue::Generate() { 5175 void DeferredReferenceGetKeyedValue::Generate() {
5189 CodeGenerator* cgen = generator(); 5176 CodeGenerator* cgen = generator();
5190 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
5191 Result receiver(cgen); 5177 Result receiver(cgen);
5192 Result key(cgen); 5178 Result key(cgen);
5193 enter()->Bind(&receiver, &key); 5179 enter()->Bind(&receiver, &key);
5194 cgen->frame()->Push(&receiver); // First IC argument. 5180 cgen->frame()->Push(&receiver); // First IC argument.
5195 cgen->frame()->Push(&key); // Second IC argument. 5181 cgen->frame()->Push(&key); // Second IC argument.
5196 5182
5197 // Calculate the delta from the IC call instruction to the map check 5183 // Calculate the delta from the IC call instruction to the map check
5198 // cmp instruction in the inlined version. This delta is stored in 5184 // cmp instruction in the inlined version. This delta is stored in
5199 // a test(eax, delta) instruction after the call so that we can find 5185 // a test(eax, delta) instruction after the call so that we can find
5200 // it in the IC initialization code and patch the cmp instruction. 5186 // it in the IC initialization code and patch the cmp instruction.
5201 // This means that we cannot allow test instructions after calls to 5187 // This means that we cannot allow test instructions after calls to
5202 // KeyedLoadIC stubs in other places. 5188 // KeyedLoadIC stubs in other places.
5203 Result value(cgen); 5189 RelocInfo::Mode mode = is_global_
5204 if (is_global_) { 5190 ? RelocInfo::CODE_TARGET_CONTEXT
Kasper Lund 2009/03/25 13:25:34 4 space indent here?
5205 value = cgen->frame()->CallCodeObject(ic, 5191 : RelocInfo::CODE_TARGET;
5206 RelocInfo::CODE_TARGET_CONTEXT, 5192 Result value = cgen->frame()->CallKeyedLoadIC(mode);
5207 0);
5208 } else {
5209 value = cgen->frame()->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
5210 }
5211 // The result needs to be specifically the eax register because the 5193 // The result needs to be specifically the eax register because the
5212 // offset to the patch site will be expected in a test eax 5194 // offset to the patch site will be expected in a test eax
5213 // instruction. 5195 // instruction.
5214 ASSERT(value.is_register() && value.reg().is(eax)); 5196 ASSERT(value.is_register() && value.reg().is(eax));
5215 // The delta from the start of the map-compare instruction to the 5197 // The delta from the start of the map-compare instruction to the
5216 // test eax instruction. 5198 // test eax instruction.
5217 int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site()); 5199 int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site());
5218 __ test(value.reg(), Immediate(-delta_to_patch_site)); 5200 __ test(value.reg(), Immediate(-delta_to_patch_site));
5219 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); 5201 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
5220 5202
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
5262 break; 5244 break;
5263 } 5245 }
5264 5246
5265 case NAMED: { 5247 case NAMED: {
5266 // TODO(1241834): Make sure that it is safe to ignore the 5248 // TODO(1241834): Make sure that it is safe to ignore the
5267 // distinction between expressions in a typeof and not in a 5249 // distinction between expressions in a typeof and not in a
5268 // typeof. If there is a chance that reference errors can be 5250 // typeof. If there is a chance that reference errors can be
5269 // thrown below, we must distinguish between the two kinds of 5251 // thrown below, we must distinguish between the two kinds of
5270 // loads (typeof expression loads must not throw a reference 5252 // loads (typeof expression loads must not throw a reference
5271 // error). 5253 // error).
5272 VirtualFrame* frame = cgen_->frame();
5273 Comment cmnt(masm, "[ Load from named Property"); 5254 Comment cmnt(masm, "[ Load from named Property");
5274 Handle<String> name(GetName()); 5255 cgen_->frame()->Push(GetName());
5256
5275 Variable* var = expression_->AsVariableProxy()->AsVariable(); 5257 Variable* var = expression_->AsVariableProxy()->AsVariable();
5276 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
5277 // Setup the name register.
5278 Result name_reg = cgen_->allocator()->Allocate(ecx);
5279 ASSERT(name_reg.is_valid());
5280 __ mov(name_reg.reg(), name);
5281 ASSERT(var == NULL || var->is_global()); 5258 ASSERT(var == NULL || var->is_global());
5282 RelocInfo::Mode rmode = (var == NULL) 5259 RelocInfo::Mode mode = (var == NULL)
5283 ? RelocInfo::CODE_TARGET 5260 ? RelocInfo::CODE_TARGET
5284 : RelocInfo::CODE_TARGET_CONTEXT; 5261 : RelocInfo::CODE_TARGET_CONTEXT;
5285 Result answer = frame->CallCodeObject(ic, rmode, &name_reg, 0); 5262 Result answer = cgen_->frame()->CallLoadIC(mode);
5286 frame->Push(&answer); 5263 cgen_->frame()->Push(&answer);
5287 break; 5264 break;
5288 } 5265 }
5289 5266
5290 case KEYED: { 5267 case KEYED: {
5291 // TODO(1241834): Make sure that this it is safe to ignore the 5268 // TODO(1241834): Make sure that this it is safe to ignore the
5292 // distinction between expressions in a typeof and not in a typeof. 5269 // distinction between expressions in a typeof and not in a typeof.
5293 Comment cmnt(masm, "[ Load from keyed Property"); 5270 Comment cmnt(masm, "[ Load from keyed Property");
5294 Variable* var = expression_->AsVariableProxy()->AsVariable(); 5271 Variable* var = expression_->AsVariableProxy()->AsVariable();
5295 bool is_global = var != NULL; 5272 bool is_global = var != NULL;
5296 ASSERT(!is_global || var->is_global()); 5273 ASSERT(!is_global || var->is_global());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
5366 __ IncrementCounter(&Counters::keyed_load_inline, 1); 5343 __ IncrementCounter(&Counters::keyed_load_inline, 1);
5367 5344
5368 // Restore the receiver and key to the frame and push the 5345 // Restore the receiver and key to the frame and push the
5369 // result on top of it. 5346 // result on top of it.
5370 deferred->BindExit(&receiver, &key, &value); 5347 deferred->BindExit(&receiver, &key, &value);
5371 cgen_->frame()->Push(&receiver); 5348 cgen_->frame()->Push(&receiver);
5372 cgen_->frame()->Push(&key); 5349 cgen_->frame()->Push(&key);
5373 cgen_->frame()->Push(&value); 5350 cgen_->frame()->Push(&value);
5374 5351
5375 } else { 5352 } else {
5376 VirtualFrame* frame = cgen_->frame();
5377 Comment cmnt(masm, "[ Load from keyed Property"); 5353 Comment cmnt(masm, "[ Load from keyed Property");
5378 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 5354 RelocInfo::Mode mode = is_global
5379 RelocInfo::Mode rmode = is_global 5355 ? RelocInfo::CODE_TARGET_CONTEXT
5380 ? RelocInfo::CODE_TARGET_CONTEXT 5356 : RelocInfo::CODE_TARGET;
5381 : RelocInfo::CODE_TARGET; 5357 Result answer = cgen_->frame()->CallKeyedLoadIC(mode);
5382 Result answer = frame->CallCodeObject(ic, rmode, 0);
5383 // Make sure that we do not have a test instruction after the 5358 // Make sure that we do not have a test instruction after the
5384 // call. A test instruction after the call is used to 5359 // call. A test instruction after the call is used to
5385 // indicate that we have generated an inline version of the 5360 // indicate that we have generated an inline version of the
5386 // keyed load. The explicit nop instruction is here because 5361 // keyed load. The explicit nop instruction is here because
5387 // the push that follows might be peep-hole optimized away. 5362 // the push that follows might be peep-hole optimized away.
5388 __ nop(); 5363 __ nop();
5389 frame->Push(&answer); 5364 cgen_->frame()->Push(&answer);
5390 } 5365 }
5391 break; 5366 break;
5392 } 5367 }
5393 5368
5394 default: 5369 default:
5395 UNREACHABLE(); 5370 UNREACHABLE();
5396 } 5371 }
5397 } 5372 }
5398 5373
5399 5374
(...skipping 23 matching lines...) Expand all
5423 } else { 5398 } else {
5424 ASSERT(slot->type() == Slot::LOCAL); 5399 ASSERT(slot->type() == Slot::LOCAL);
5425 cgen_->frame()->TakeLocalAt(slot->index()); 5400 cgen_->frame()->TakeLocalAt(slot->index());
5426 } 5401 }
5427 } 5402 }
5428 5403
5429 5404
5430 void Reference::SetValue(InitState init_state) { 5405 void Reference::SetValue(InitState init_state) {
5431 ASSERT(cgen_->HasValidEntryRegisters()); 5406 ASSERT(cgen_->HasValidEntryRegisters());
5432 ASSERT(!is_illegal()); 5407 ASSERT(!is_illegal());
5433 MacroAssembler* masm = cgen_->masm();
5434 VirtualFrame* frame = cgen_->frame();
5435 switch (type_) { 5408 switch (type_) {
5436 case SLOT: { 5409 case SLOT: {
5437 Comment cmnt(masm, "[ Store to Slot"); 5410 Comment cmnt(cgen_->masm(), "[ Store to Slot");
5438 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 5411 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
5439 ASSERT(slot != NULL); 5412 ASSERT(slot != NULL);
5440 cgen_->StoreToSlot(slot, init_state); 5413 cgen_->StoreToSlot(slot, init_state);
5441 break; 5414 break;
5442 } 5415 }
5443 5416
5444 case NAMED: { 5417 case NAMED: {
5445 Comment cmnt(masm, "[ Store to named Property"); 5418 Comment cmnt(cgen_->masm(), "[ Store to named Property");
5446 // Call the appropriate IC code. 5419 cgen_->frame()->Push(GetName());
5447 Handle<String> name(GetName()); 5420 Result answer = cgen_->frame()->CallStoreIC();
5448 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 5421 cgen_->frame()->Push(&answer);
5449 // TODO(1222589): Make the IC grab the values from the stack.
5450 Result argument = frame->Pop();
5451 argument.ToRegister(eax);
5452 ASSERT(argument.is_valid());
5453 Result property_name = cgen_->allocator()->Allocate(ecx);
5454 ASSERT(property_name.is_valid());
5455 // Setup the name register.
5456 __ mov(property_name.reg(), name);
5457 Result answer = frame->CallCodeObject(ic, RelocInfo::CODE_TARGET,
5458 &argument, &property_name, 0);
5459 frame->Push(&answer);
5460 break; 5422 break;
5461 } 5423 }
5462 5424
5463 case KEYED: { 5425 case KEYED: {
5464 Comment cmnt(masm, "[ Store to keyed Property"); 5426 Comment cmnt(cgen_->masm(), "[ Store to keyed Property");
5465 // Call IC code. 5427 Result answer = cgen_->frame()->CallKeyedStoreIC();
5466 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 5428 cgen_->frame()->Push(&answer);
5467 // TODO(1222589): Make the IC grab the values from the stack.
5468 Result arg = frame->Pop();
5469 arg.ToRegister(eax);
5470 ASSERT(arg.is_valid());
5471 Result answer = frame->CallCodeObject(ic, RelocInfo::CODE_TARGET,
5472 &arg, 0);
5473 frame->Push(&answer);
5474 break; 5429 break;
5475 } 5430 }
5476 5431
5477 default: 5432 default:
5478 UNREACHABLE(); 5433 UNREACHABLE();
5479 } 5434 }
5480 } 5435 }
5481 5436
5482 5437
5483 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). 5438 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined).
(...skipping 1504 matching lines...) Expand 10 before | Expand all | Expand 10 after
6988 6943
6989 // Slow-case: Go through the JavaScript implementation. 6944 // Slow-case: Go through the JavaScript implementation.
6990 __ bind(&slow); 6945 __ bind(&slow);
6991 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6946 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6992 } 6947 }
6993 6948
6994 6949
6995 #undef __ 6950 #undef __
6996 6951
6997 } } // namespace v8::internal 6952 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/virtual-frame.cc » ('j') | src/virtual-frame-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698