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

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

Issue 3197010: Version 2.3.10... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 4 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/ia32/codegen-ia32.h ('k') | src/ia32/full-codegen-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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 3405 matching lines...) Expand 10 before | Expand all | Expand 10 after
3416 STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); 3416 STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
3417 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); 3417 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
3418 __ j(below, &build_args); 3418 __ j(below, &build_args);
3419 3419
3420 // Check that applicand.apply is Function.prototype.apply. 3420 // Check that applicand.apply is Function.prototype.apply.
3421 __ mov(eax, Operand(esp, kPointerSize)); 3421 __ mov(eax, Operand(esp, kPointerSize));
3422 __ test(eax, Immediate(kSmiTagMask)); 3422 __ test(eax, Immediate(kSmiTagMask));
3423 __ j(zero, &build_args); 3423 __ j(zero, &build_args);
3424 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ecx); 3424 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ecx);
3425 __ j(not_equal, &build_args); 3425 __ j(not_equal, &build_args);
3426 __ mov(ecx, FieldOperand(eax, JSFunction::kCodeEntryOffset));
3427 __ sub(Operand(ecx), Immediate(Code::kHeaderSize - kHeapObjectTag));
3426 Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply)); 3428 Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply));
3427 __ cmp(FieldOperand(eax, JSFunction::kCodeOffset), Immediate(apply_code)); 3429 __ cmp(Operand(ecx), Immediate(apply_code));
3428 __ j(not_equal, &build_args); 3430 __ j(not_equal, &build_args);
3429 3431
3430 // Check that applicand is a function. 3432 // Check that applicand is a function.
3431 __ mov(edi, Operand(esp, 2 * kPointerSize)); 3433 __ mov(edi, Operand(esp, 2 * kPointerSize));
3432 __ test(edi, Immediate(kSmiTagMask)); 3434 __ test(edi, Immediate(kSmiTagMask));
3433 __ j(zero, &build_args); 3435 __ j(zero, &build_args);
3434 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 3436 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
3435 __ j(not_equal, &build_args); 3437 __ j(not_equal, &build_args);
3436 3438
3437 // Copy the arguments to this function possibly from the 3439 // Copy the arguments to this function possibly from the
(...skipping 2075 matching lines...) Expand 10 before | Expand all | Expand 10 after
5513 __ push(Immediate(node_->pattern())); 5515 __ push(Immediate(node_->pattern()));
5514 // RegExp flags (3). 5516 // RegExp flags (3).
5515 __ push(Immediate(node_->flags())); 5517 __ push(Immediate(node_->flags()));
5516 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 5518 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
5517 if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax); 5519 if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax);
5518 } 5520 }
5519 5521
5520 5522
5521 class DeferredAllocateInNewSpace: public DeferredCode { 5523 class DeferredAllocateInNewSpace: public DeferredCode {
5522 public: 5524 public:
5523 DeferredAllocateInNewSpace(int size, Register target) 5525 DeferredAllocateInNewSpace(int size,
5524 : size_(size), target_(target) { 5526 Register target,
5527 int registers_to_save = 0)
5528 : size_(size), target_(target), registers_to_save_(registers_to_save) {
5525 ASSERT(size >= kPointerSize && size <= Heap::MaxObjectSizeInNewSpace()); 5529 ASSERT(size >= kPointerSize && size <= Heap::MaxObjectSizeInNewSpace());
5530 ASSERT_EQ(0, registers_to_save & target.bit());
5526 set_comment("[ DeferredAllocateInNewSpace"); 5531 set_comment("[ DeferredAllocateInNewSpace");
5527 } 5532 }
5528 void Generate(); 5533 void Generate();
5529 5534
5530 private: 5535 private:
5531 int size_; 5536 int size_;
5532 Register target_; 5537 Register target_;
5538 int registers_to_save_;
5533 }; 5539 };
5534 5540
5535 5541
5536 void DeferredAllocateInNewSpace::Generate() { 5542 void DeferredAllocateInNewSpace::Generate() {
5543 for (int i = 0; i < kNumRegs; i++) {
5544 if (registers_to_save_ & (1 << i)) {
5545 Register save_register = { i };
5546 __ push(save_register);
5547 }
5548 }
5537 __ push(Immediate(Smi::FromInt(size_))); 5549 __ push(Immediate(Smi::FromInt(size_)));
5538 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 5550 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
5539 if (!target_.is(eax)) { 5551 if (!target_.is(eax)) {
5540 __ mov(target_, eax); 5552 __ mov(target_, eax);
5541 } 5553 }
5554 for (int i = kNumRegs - 1; i >= 0; i--) {
5555 if (registers_to_save_ & (1 << i)) {
5556 Register save_register = { i };
5557 __ pop(save_register);
5558 }
5559 }
5542 } 5560 }
5543 5561
5544 5562
5545 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { 5563 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
5546 ASSERT(!in_safe_int32_mode()); 5564 ASSERT(!in_safe_int32_mode());
5547 Comment cmnt(masm_, "[ RegExp Literal"); 5565 Comment cmnt(masm_, "[ RegExp Literal");
5548 5566
5549 // Retrieve the literals array and check the allocated entry. Begin 5567 // Retrieve the literals array and check the allocated entry. Begin
5550 // with a writable copy of the function of this activation in a 5568 // with a writable copy of the function of this activation in a
5551 // register. 5569 // register.
(...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after
7355 __ bind(&slowcase); 7373 __ bind(&slowcase);
7356 __ CallRuntime(Runtime::kRegExpConstructResult, 3); 7374 __ CallRuntime(Runtime::kRegExpConstructResult, 3);
7357 7375
7358 __ bind(&done); 7376 __ bind(&done);
7359 } 7377 }
7360 frame_->Forget(3); 7378 frame_->Forget(3);
7361 frame_->Push(eax); 7379 frame_->Push(eax);
7362 } 7380 }
7363 7381
7364 7382
7383 void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
7384 ASSERT_EQ(1, args->length());
7385
7386 Load(args->at(0));
7387 Result object_result = frame_->Pop();
7388 object_result.ToRegister(eax);
7389 object_result.Unuse();
7390 {
7391 VirtualFrame::SpilledScope spilled_scope;
7392
7393 Label done;
7394
7395 __ test(eax, Immediate(kSmiTagMask));
7396 __ j(zero, &done);
7397
7398 // Load JSRegExpResult map into edx.
7399 // Arguments to this function should be results of calling RegExp exec,
7400 // which is either an unmodified JSRegExpResult or null. Anything not having
7401 // the unmodified JSRegExpResult map is returned unmodified.
7402 // This also ensures that elements are fast.
7403 __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
7404 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
7405 __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX));
7406 __ cmp(edx, FieldOperand(eax, HeapObject::kMapOffset));
7407 __ j(not_equal, &done);
7408
7409 if (FLAG_debug_code) {
7410 // Check that object really has empty properties array, as the map
7411 // should guarantee.
7412 __ cmp(FieldOperand(eax, JSObject::kPropertiesOffset),
7413 Immediate(Factory::empty_fixed_array()));
7414 __ Check(equal, "JSRegExpResult: default map but non-empty properties.");
7415 }
7416
7417 DeferredAllocateInNewSpace* allocate_fallback =
7418 new DeferredAllocateInNewSpace(JSRegExpResult::kSize,
7419 ebx,
7420 edx.bit() | eax.bit());
7421
7422 // All set, copy the contents to a new object.
7423 __ AllocateInNewSpace(JSRegExpResult::kSize,
7424 ebx,
7425 ecx,
7426 no_reg,
7427 allocate_fallback->entry_label(),
7428 TAG_OBJECT);
7429 __ bind(allocate_fallback->exit_label());
7430
7431 // Copy all fields from eax to ebx.
7432 STATIC_ASSERT(JSRegExpResult::kSize % (2 * kPointerSize) == 0);
7433 // There is an even number of fields, so unroll the loop once
7434 // for efficiency.
7435 for (int i = 0; i < JSRegExpResult::kSize; i += 2 * kPointerSize) {
7436 STATIC_ASSERT(JSObject::kMapOffset % (2 * kPointerSize) == 0);
7437 if (i != JSObject::kMapOffset) {
7438 // The map was already loaded into edx.
7439 __ mov(edx, FieldOperand(eax, i));
7440 }
7441 __ mov(ecx, FieldOperand(eax, i + kPointerSize));
7442
7443 STATIC_ASSERT(JSObject::kElementsOffset % (2 * kPointerSize) == 0);
7444 if (i == JSObject::kElementsOffset) {
7445 // If the elements array isn't empty, make it copy-on-write
7446 // before copying it.
7447 Label empty;
7448 __ cmp(Operand(edx), Immediate(Factory::empty_fixed_array()));
7449 __ j(equal, &empty);
7450 ASSERT(!Heap::InNewSpace(Heap::fixed_cow_array_map()));
7451 __ mov(FieldOperand(edx, HeapObject::kMapOffset),
7452 Immediate(Factory::fixed_cow_array_map()));
7453 __ bind(&empty);
7454 }
7455 __ mov(FieldOperand(ebx, i), edx);
7456 __ mov(FieldOperand(ebx, i + kPointerSize), ecx);
7457 }
7458 __ mov(eax, ebx);
7459
7460 __ bind(&done);
7461 }
7462 frame_->Push(eax);
7463 }
7464
7465
7365 class DeferredSearchCache: public DeferredCode { 7466 class DeferredSearchCache: public DeferredCode {
7366 public: 7467 public:
7367 DeferredSearchCache(Register dst, Register cache, Register key) 7468 DeferredSearchCache(Register dst, Register cache, Register key)
7368 : dst_(dst), cache_(cache), key_(key) { 7469 : dst_(dst), cache_(cache), key_(key) {
7369 set_comment("[ DeferredSearchCache"); 7470 set_comment("[ DeferredSearchCache");
7370 } 7471 }
7371 7472
7372 virtual void Generate(); 7473 virtual void Generate();
7373 7474
7374 private: 7475 private:
(...skipping 2433 matching lines...) Expand 10 before | Expand all | Expand 10 after
9808 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx); 9909 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
9809 __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset), 9910 __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset),
9810 Immediate(Factory::the_hole_value())); 9911 Immediate(Factory::the_hole_value()));
9811 __ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx); 9912 __ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx);
9812 __ mov(FieldOperand(eax, JSFunction::kContextOffset), esi); 9913 __ mov(FieldOperand(eax, JSFunction::kContextOffset), esi);
9813 __ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx); 9914 __ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx);
9814 9915
9815 // Initialize the code pointer in the function to be the one 9916 // Initialize the code pointer in the function to be the one
9816 // found in the shared function info object. 9917 // found in the shared function info object.
9817 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); 9918 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
9818 __ mov(FieldOperand(eax, JSFunction::kCodeOffset), edx); 9919 __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
9920 __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
9819 9921
9820 // Return and remove the on-stack parameter. 9922 // Return and remove the on-stack parameter.
9821 __ ret(1 * kPointerSize); 9923 __ ret(1 * kPointerSize);
9822 9924
9823 // Create a new closure through the slower runtime call. 9925 // Create a new closure through the slower runtime call.
9824 __ bind(&gc); 9926 __ bind(&gc);
9825 __ pop(ecx); // Temporarily remove return address. 9927 __ pop(ecx); // Temporarily remove return address.
9826 __ pop(edx); 9928 __ pop(edx);
9827 __ push(esi); 9929 __ push(esi);
9828 __ push(edx); 9930 __ push(edx);
(...skipping 4577 matching lines...) Expand 10 before | Expand all | Expand 10 after
14406 masm.GetCode(&desc); 14508 masm.GetCode(&desc);
14407 // Call the function from C++. 14509 // Call the function from C++.
14408 return FUNCTION_CAST<MemCopyFunction>(buffer); 14510 return FUNCTION_CAST<MemCopyFunction>(buffer);
14409 } 14511 }
14410 14512
14411 #undef __ 14513 #undef __
14412 14514
14413 } } // namespace v8::internal 14515 } } // namespace v8::internal
14414 14516
14415 #endif // V8_TARGET_ARCH_IA32 14517 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698